利用纯JS实现像素逐渐显示的方法示例


Posted in Javascript onAugust 14, 2017

前言

对于新手的我,以前从来没有做过对像素进行操作的实例。于是把资料书找了出来,实现了这个功能,比较简单,大神勿喷。下面是效果图,因为重在思路,效果就简陋一些。

利用纯JS实现像素逐渐显示的方法示例

利用纯JS实现像素逐渐显示的方法示例

利用纯JS实现像素逐渐显示的方法示例

实现思路

其实就是简单的用JS实现将左上角的矩形随时间图像逐渐显示在它的右下方。

首先,先把思路架构起来,因为对像素操作,所以需要用到canvas。

然后,我们 需要画一个矩形,并且需要获取到它的每一个像素的值,即每一个像素的4要素,rgba。(方法getImageData,4个参数,前两个坐标,X和Y,后两个是长和宽)

最后,用一个定时器实现逐渐显示的功能。(显示可以用putImageData,3个参数,第一个是需要显示的图像,第二和第三是坐标值XY)

然后我们开始动手敲代码:

我们可以先做出一个没有定时器的,也就是先试着获取到原矩形1/10的像素点,然后显示出来。

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <style>
  body{
   background-color: black;
  }
  canvas{
   background-color: white;
  }
 </style>
 <title>Title</title>
 <script>
  window.onload = function(){
   var oC = document.querySelector("#c");
   var oGc = oC.getContext("2d");
   oGc.fillRect(0,0,100,100);//画原矩形

   var rectData = oGc.getImageData(0,0,100,100);//获取原矩形的像素点的值
   var w = rectData.width;//原矩形的宽
   var h = rectData.height;//原矩形的长

   var dataC = randomData(w*h,w*h/10);//randomData方法实现随机从原矩形的像素点中抽取一部分出来
   var newData = oGc.createImageData(w,h);//创造一个新的矩形


   //dataC数组中存放的是第几个像素,*4是为了把图片的data数组定位到这个像素的数据的第一个值,然后加一是第二个,以此类推。
   for(var j=0;j<dataC.length;j++){
    newData.data[4*dataC[j]]=rectData.data[4*dataC[j]];
    newData.data[4*dataC[j]+1]=rectData.data[4*dataC[j]+1];
    newData.data[4*dataC[j]+2]=rectData.data[4*dataC[j]+2];
    newData.data[4*dataC[j]+3]=rectData.data[4*dataC[j]+3];
   }
   oGc.putImageData(newData,w,h);

   function randomData(allNum,nowNum) {
    var dataA = [];
    var dataB = [];
    for(var i=0;i<allNum;i++){
     dataA.push(i);
    }

    for(var i=0;i<nowNum;i++){
     dataB.push(dataA.splice(Math.floor(Math.random()*dataA.length),1));

    }
    return dataB;

   }

  }
 </script>
</head>
<body>
<canvas id="c" width="400" height="400"></canvas>
</body>
</html>

其中因为getImageData的data属性是一个数组,而且数组中的存放的东西,就是我们需要的rgba4个数,存放形式为:

  • data[0]第一个像素点的r值:
  • data[1]:第一个像素点的g值
  • data[2]:第一个像素点的b值
  • data[3]:第一个像素点的a值
  • data[4]:第二个像素点的r值
  • data[5]:第二个像素点的g值

以此类推,4个一循环。

然后数组dataC里面存放的是取出的像素点位置,然后用乘以4和分别加一,加二,加三为了定位到每一个像素点的rgba分别的4个值。此时就能实现抽取一部分像素点显示的功能。

利用纯JS实现像素逐渐显示的方法示例

最后,将代码改进。

第一步,我们需要改进randomData这个函数,使之返回的数组是包含原矩形的所有像素。

function randomData(allNum,nowNum) {
    var dataA = [];
    var dataB = [];
    for(var i=0;i<allNum;i++){
     dataA.push(i);
    }

    for(var i=0;i<allNum/nowNum;i++){
     var otherData = [];
     for(var j=0;j<nowNum;j++){
      otherData.push(dataA.splice(Math.floor(Math.random()*dataA.length),1));
     }
     dataB.push(otherData);
    }
    return dataB;
   }

嵌套了一层for循环,使返回的dataB数组里面分成了一定组数的一定量个像素点。

然后增加一个定时器,最终代码为:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <style>
  body{
   background-color: black;
  }
  canvas{
   background: #fff;
  }
 </style>
 <title>Title</title>
 <script>
  window.onload = function(){
   var oC = document.querySelector("#c");
   var oGc = oC.getContext("2d");
   oGc.fillRect(0,0,100,100);

   var rectData = oGc.getImageData(0,0,100,100);
   var w = rectData.width;
   var h = rectData.height;


   var dataC = randomData(w*h,w*h/10);
   var newData = oGc.createImageData(w,h);

   var iNum = 0;

   var timer = setInterval(function () {
    for(var j=0;j<dataC[iNum].length;j++){
     newData.data[4*dataC[iNum][j]]=rectData.data[4*dataC[iNum][j]];
     newData.data[4*dataC[iNum][j]+1]=rectData.data[4*dataC[iNum][j]+1];
     newData.data[4*dataC[iNum][j]+2]=rectData.data[4*dataC[iNum][j]+2];
     newData.data[4*dataC[iNum][j]+3]=rectData.data[4*dataC[iNum][j]+3];

    }
    oGc.putImageData(newData,w,h);

    if(iNum<9){
     iNum++;
    }
    else{
     iNum=0;
     oGc.clearRect(w,h,w,h);
     for(var i=0;i<newData.data.length;i++){
      newData.data[i]=0;
     }
    }
   },200);


   function randomData(allNum,nowNum) {
    var dataA = [];
    var dataB = [];
    for(var i=0;i<allNum;i++){
     dataA.push(i);
    }

    for(var i=0;i<allNum/nowNum;i++){
     var otherData = [];
     for(var j=0;j<nowNum;j++){
      otherData.push(dataA.splice(Math.floor(Math.random()*dataA.length),1));
     }
     dataB.push(otherData);
    }
    return dataB;
   }

  }
 </script>
</head>
<body>
<canvas id="c" width="400" height="400"></canvas>
</body>
</html>

其中31到35行的for循环还是一样将原矩形的像素点传递给新矩形。但是这一次是用iNum来实现分批次的传递和显示。注意这里的dataC,也就是randomData函数返回的数组是一个二维数组。最后用一个if—else判断来控制计时器的继续计时和停止计时。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
editable.js 基于jquery的表格的编辑插件
Oct 24 Javascript
jQuery中height()方法用法实例
Dec 24 Javascript
ajax+jQuery实现级联显示地址的方法
May 06 Javascript
jQuery EasyUI 组件加上“清除”功能实例详解
Apr 11 jQuery
vue router demo详解
Oct 13 Javascript
javascript实现获取一个日期段内每天不同的价格(计算入住总价格)
Feb 05 Javascript
vue 路由页面之间实现用手指进行滑动的方法
Feb 23 Javascript
JavaScript函数重载操作实例浅析
May 02 Javascript
vue实现购物车列表
Jun 30 Javascript
Vue中父子组件的值传递与方法传递
Sep 28 Javascript
使用react+redux实现计数器功能及遇到问题
Jun 02 Javascript
js基于div丝滑实现贝塞尔曲线
Sep 23 Javascript
jQuery 实时保存页面动态添加的数据的示例
Aug 14 #jQuery
js异步编程小技巧详解
Aug 14 #Javascript
js数字滑动时钟的简单实现(示例讲解)
Aug 14 #Javascript
使用yeoman构建angular应用的方法
Aug 14 #Javascript
AngularJS 购物车全选/取消全选功能的实现方法
Aug 14 #Javascript
使用D3.js制作图表详解
Aug 13 #Javascript
Vue-Cli中自定义过滤器的实现代码
Aug 12 #Javascript
You might like
一个域名查询的程序
2006/10/09 PHP
PHP中将数组转成XML格式的实现代码
2011/08/08 PHP
PHP计算2点经纬度之间的距离代码
2013/08/12 PHP
php使用strip_tags()去除html标签仍有空白的解决方法
2016/07/28 PHP
PHP生成唯一ID之SnowFlake算法
2016/12/17 PHP
ThinkPHP5.0框架结合Swoole开发实现WebSocket在线聊天案例详解
2019/04/02 PHP
PHP实现统计代码行数小工具
2019/09/19 PHP
禁止刷新,回退的JS
2006/11/25 Javascript
jquery api参考 visualjquery 中国线路 速度快
2007/11/30 Javascript
基于jquery的高性能td和input切换并可修改内容实现代码
2011/01/09 Javascript
说明你的Javascript技术很烂的五个原因
2011/04/26 Javascript
利用进制转换压缩数字函数分享
2014/01/02 Javascript
Javascript基础教程之定义和调用函数
2015/01/18 Javascript
javascript变量声明实例分析
2015/04/25 Javascript
jquery网页日历显示控件calendar3.1使用详解
2016/11/24 Javascript
BootStrap daterangepicker 双日历控件
2017/06/02 Javascript
详解webpack 如何集成第三方js库
2017/06/29 Javascript
nodejs 搭建简易服务器的图文教程(推荐)
2017/07/18 NodeJs
vue父组件中获取子组件中的数据(实例讲解)
2017/09/27 Javascript
jQuery获取所有父级元素及同级元素及子元素的方法(推荐)
2018/01/21 jQuery
vue实现打印功能的两种方法
2018/09/07 Javascript
Vue面试题及Vue知识点整理
2018/10/07 Javascript
原生js实现trigger方法示例代码
2019/05/22 Javascript
解决antd日期选择组件,添加value就无法点击下一年和下一月问题
2020/10/29 Javascript
python GUI图形化编程wxpython的使用
2019/07/19 Python
俄罗斯第一家篮球店:StreetBall
2020/07/30 全球购物
您熟悉ORM(Object-Relation Mapping)吗?请谈谈您所理解的ORM
2016/02/08 面试题
初级软件工程师面试题 Junior Software Engineer Interview
2015/02/15 面试题
Ruby如何定义一个类
2012/10/08 面试题
房屋转让协议书范本
2014/04/11 职场文书
2015年乡镇信访工作总结
2015/04/07 职场文书
OpenCV-Python实现轮廓的特征值
2021/06/09 Python
全面盘点MySQL中的那些重要日志文件
2021/11/27 MySQL
Go语言的协程上下文的几个方法和用法
2022/04/11 Golang
tomcat下部署jenkins的方法
2022/05/06 Servers
项目中Nginx多级代理是如何获取客户端的真实IP地址
2022/05/30 Servers