上篇博客提到过,box-shadow属性的本质是对形状的复制,那么如果我设置一个1*1px的i标签,利用box-shadow可以叠加的特性,给每一个1*1px的阴影赋上颜色,那么最后不就是一幅图片了么。

html代码很简单:

<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>canvas</title>
<style>#shadow {position: relative;}#shadow i {display: block;width: 1px;height: 1px;}
</style>
<script src="shadowShow.class.js" defer="defer"></script>
</head>
<body>
<input id="file" class="file-upload" type="file" accept="image/png, image/gif" />
<canvas id="canvas">您的浏览器不支持canvas标签
</canvas>
<div id="shadow"><i></i></div>
<script>
var init = {fileObj: 'file',  //input控件的idcanvas: 'canvas',  //canvas的标签的idshadowBox: 'shadow',  //用于阴影显示的标签的id
};
</script></body>
</html>

  做了一个简单的图片上传控件,页面的js里读取了一些简单的控件信息。

  最初在直接用控件获取图片路径时,碰到了路径显示为fakepath的问题(直接给控件赋路径src='#'有效果),所以没法读取图片的路径。

  查询后使用了FileReader()解决了这个问题,FileReader()读取图片信息的使用很简单,请自行百度。

  重点还是用canvas的getImageData()获取了图片每个像素点的rgba信息。图片上的每个点都有rgb三原色加上一个透明度的信息,这些信息都放在getImageData()的data数组里,换句话说,data数组里每4个值组合起来就是一个像素点的颜色信息。而每个像素点的位置可以根据这是第几个像素点(每个像素点都是1*1px),加上原图片的长宽信息来计算得出,宽度上data数组里每4个值宽度加1px,如果像素点的宽度超过了图片的宽度,那么就说明该像素点是下一行的,即将高度加1px,宽度重置。

  又像素点的信息都是保存在一个名叫data的一维数据里,且每4条数据是一个像素点的颜色信息,所以可以每4条数据一读,比如 if (i % 4 === 0),那么像素点的red通道即是image.data[index],green通道是imageData.data[index + 1],blue通道是imageData.data[index + 2],alpha通道是imageData.data[index + 3],最后把这些颜色信息处理下通通push到一个数组里,赋给i标签的box-shadow属性就大功告成。

  下面给出完整的js代码:

(function() {/**最初我的init方法是这样的,但是在对象的属性里添加监听事件貌似无效,所以挪到了对象外init: function() {console.log(this.fileObj);this.fileObj.addEventListener('change', function() {shadowShow.upPic();});},*/document.getElementById(init.fileObj).addEventListener('change', function() {shadowShow.init();});var shadowShow =  {fileObj: document.getElementById(init.fileObj),canvas: document.getElementById(init.canvas),ctx: this.canvas.getContext('2d'),shadowBox: document.getElementById(init.shadowBox),init: function() {shadowShow.upPic();},/***用于获取上传的图片的信息并在canvas1中显示*@method upPic*/upPic: function() {image = new Image();this.setImageUrl(image, this.fileObj);image.onload = function() {// cavas的宽高用setAttribute设置,用canvas.width也可以,注意值不能加上单位width = this.width;height = this.height;shadowShow.canvas.setAttribute('width', width);shadowShow.canvas.setAttribute('height', height);shadowShow.ctx.drawImage(this, 0, 0, width, height);shadowShow.toShadowShow(this, shadowShow.ctx);}},/***用于设置创建的iamge对象的url*@method setImageUrl*@param {obj} image 创建的iamge对象*@param {obj} fileQuery 上传图片的file控件对象*/setImageUrl: function(image, fileQuery) { var file = fileQuery.files[0]; var reader = new FileReader();  reader.onload = function(e) { image.src = e.target.result;}reader.readAsDataURL(file);  },/***用于将上传的图片的用box-shadow表现出来*@method toBoxShadow*@param {obj} image 创建的iamge对象*@param {obj} context 创建的绘图的上下文对象*/toShadowShow: function(image, context) {width = image.width;height = image.height;this.shadowBox.style.width = width + 'px';this.shadowBox.style.height = height + 'px'; var imageData = context.getImageData(0, 0, width, height);var arrShadow = new Array();var index = 0;var interval = setInterval(function() {if (index < imageData.data.length) {// 每4个参数处理一次if (index % 4 === 0) {var x = index / 4 % width + 1,  //x坐标,以index=4为例,index/4=1,表示x是第1个像素点,1%width是为了获得第n行的像素点的x坐标,又index是从0开始的(index=0是真正的第一个像素点),所以x的坐标需要加上1y = Math.floor(index / 4 / width) + 1, //y坐标,alpha = Math.round(imageData.data[index + 3] / 255 * 100) / 100;  //透明度,imageData.data[index+3]/255需要乘以100是因为(imageData.data[index+3]/255)肯定是小于1的,为了避免round()取整值为1,故需要乘以100if (alpha == 255) {  //像素点没有透明度//将rgb转为16进制var redToHex = imageData.data[index].toString(16),greenToHex = imageData.data[index + 1].toString(16),blueToHex = imageData.data[index + 2].toString(16);redToHex = redToHex.length == 1 ? ('0' + redToHex) : redToHex;greenToHex = greenToHex.length == 1 ? ('0' + greenToHex) : greenToHex;blueToHex = blueToHex.length == 1 ? ('0' + blueToHex) : blueToHex;var hex = redToHex + greenToHex + blueToHex;//对形如#FFF的十六进制颜色作处理if (redToHex.slice(0,1) == redToHex.slice(-1) && greenToHex.slice(0,1) == greenToHex(-1) && blueToHex.slice(0,1) == blueToHex.slice(-1)) {hex = redToHex.slice(-1) + greenToHex.slice(-1) + blueToHex.slice(-1);}arrShadow.push(x + 'px ' + y + 'px #' + hex);} else if (alpha > 0) {a = [imageData.data[index], imageData.data[index + 1], imageData.data[index + 2], alpha].join();arrShadow.push(x + 'px ' + y + 'px rgba(' + a + ')');} }shadowShow.shadowBox.querySelector('i').style.boxShadow = arrShadow.join(); } else {clearInterval(interval);  //清除setInterval}index++;});    }};
})();

  这段代码我封装了一下,注释写的比较详细了,同时,加了一个定时器,这样就有了一个像素一个像素显示的效果,就是如果图片的width和height值比较大的话,完整的图片显示出来会比较慢。setInterval()的默认值查了下,如果设置的时间间隔小于10,则以10来算,即10ms,但是还是感觉图片显示的挺慢的,当然了,这要看图片的像素点的数量了。

  补充:

  当然了,如果仅需遍历每个像素点其实也不用像上面那么麻烦(上面主要是为了获得每个点的坐标(x, y)),如下就可以了:

  

//简单的灰阶过滤器
for (i = 0; i < imageData.data.length; i += 4) {var r = data[i],g = data[i + 1],b = data[i + 2],a = data[i + 3];var average = Math.floor((r + g + b) / 3);data[i] = data[i + 1] = data[i + 2] = average;
}

  

  最后更新于2016年11月22日

转载于:https://www.cnblogs.com/youyouluo/p/5839709.html

利用box-shadow绘图相关推荐

  1. html中投影效果图,利用CSS3(box shadow)制作边框投影

    应用CSS3的box shadow属性,可以直接在页面中使用投影,增加页面的立体效果. 最终效果预览 HTML 代码: CSS3 Box shadow 任鸟飞网页设计是一个关注于网页设计及网站开发.图 ...

  2. 成功解决 利用plt.plot绘图时,横坐标出现浮点小数而不是整数的情况(坐标轴刻度)

    成功解决 利用plt.plot绘图时,横坐标出现浮点小数而不是整数的情况(坐标轴刻度) 目录 解决问题 解决方法 相关文章 成功解决matplotlib绘图的时候,自定义横坐标和纵坐标刻度数值(调整坐 ...

  3. Matlab——Simulink输出的数据怎么利用plot函数绘图

    Matlab--Simulink输出的数据怎么利用plot函数绘图 1.将需要导出的数据添加至To Workspace模块. 2.设置To Workspace模块的名称并配置好模式,一般选择array ...

  4. Python利用turtle库绘图大熊猫

    Python利用turtle库绘图大熊猫 卡通大熊猫的详细代码 由代码绘制的熊猫宝宝 Turtle库是Python语言中一个很流行的绘制图像的函数库,想象一个小乌龟,在一个横轴为x.纵轴为y的坐标系原 ...

  5. 利用Python海龟绘图画一个世界杯的足球

    利用Python海龟绘图画一个世界杯的足球 花有重开日 人无再少年 四年一次的世界杯快要结束,为了纪念此次世界杯,特意用Python画了一个足球. 1.设计思路以及实现效果 世界杯足球实现思路: 首先 ...

  6. Box Shadow阴影和圆角

    一.盒子写Box Shadow阴影:如 box-shadow:2px 2px 5px #120F0B; //支持Opera浏览器 -moz-box-shadow:2px 2px 5px #120F0B ...

  7. Box Shadow(阴影)-Css3写法示例

    Box Shadow(阴影)-Css3演示 -moz-box-shadow:2px 2px 5px #333333; -webkit-box-shadow:2px 2px 5px #333333; b ...

  8. CSS Box Shadow Bottom Only [复制]

    本文翻译自:CSS Box Shadow Bottom Only [duplicate] This question already has an answer here: 这个问题在这里已有答案: ...

  9. CSS3 Box Shadow

    语法: box-shadow:1px 2px 3px #FFF; box-shadow:阴影水平偏移值(可取正负值): 阴影垂直偏移值(可取正负值):阴影模糊值:阴影颜色: 兼容性 Firefox支持 ...

  10. Shadow属性和【CSS3 Box Shadow(阴影)效果在线调试工具】

    Shadow属性示例 向内/向外 | x偏移量 | y偏移量 | 阴影模糊半径 | 阴影扩散半径 | 阴影颜色 inset 阴影向内 (默认向外) /* x偏移量 | y偏移量 | 阴影颜色 */ b ...

最新文章

  1. 2020年AI产业报告:100个岗位抢1个人,计算机视觉成最大缺口
  2. pandas自定义设置dataframe每个索引的标签、自定义设置索引的列名称(customize index name and index label)
  3. C语言 输入中文语句并按倒叙将它输出
  4. 数据结构整理中。。。
  5. Html5开发-使用Canvas绘制图片
  6. Java调用ElasticSearch 7.2.1 保存、统计、多字段分组聚合
  7. linux下用mail发送邮件
  8. plSQL中修改代码字体的大小
  9. 英国研制出新型机器人具有10种人类表情(组图)
  10. 【大厂面试】智力题怎么破?
  11. 远程控制电脑的软件哪个比较好用
  12. java+ssm驾校管理教练用户驾校系统@ssm
  13. 关于雷达隐身的一些事
  14. 010 Rust死灵书之Drop检查
  15. 文本分析——分配单词权重
  16. linux下安装grads
  17. 智能合约隐私计算之基于FO承诺的零知识范围证明
  18. 明略数据发布“明智系统2.0”,像“人脑”一样去感知和思考
  19. pwscf 声子计算
  20. 【分享】逆回购浅谈(代替圆球mm发)

热门文章

  1. 一个计算机高手的成长(转)
  2. 快排递归非递归python_Python递归神经网络终极指南
  3. 一群算法_树遍历解释:他们就像一群懒惰的学生,试图欺骗他们的考试
  4. vim编辑器异常退出产生备份文件
  5. (C++)寻找1-100以内所有素数,复杂度为O(nsqrt(n))与O(nloglogn)的两种方法
  6. 软件缺陷生命周期图示及当中涉及到的缺陷的状态
  7. Python中爬虫框架或模块的区别
  8. 如何处理用代码创建SD Sales order时遇到的错误消息KI 180
  9. Webpack 核心开发者 Sean Larkin 盛赞 Vue
  10. Java 8默认方法会破坏你的(用户的)代码