利用纯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 相关文章推荐
基于jquery的图片的切换(以数字的形式)
Feb 14 Javascript
jQuery链式操作如何实现以及为什么要用链式操作
Jan 17 Javascript
B/S模式项目中常用的javascript汇总
Dec 17 Javascript
EasyUI,点击开启编辑框,并且编辑框获得焦点的方法
Mar 01 Javascript
javascript实现简单的二级联动
Mar 19 Javascript
给before和after伪元素设置js效果的方法
Dec 04 Javascript
JS判断是否长按某一键的方法
Mar 02 Javascript
jQuery EasyUI基础教程之EasyUI常用组件(推荐)
Jul 15 Javascript
javascript之IE版本检测超简单方法
Aug 20 Javascript
json定义及jquery操作json的方法
Oct 03 Javascript
ES6如何用一句代码实现函数的柯里化
Jan 18 Javascript
JS实现简易留言板增删功能
Feb 08 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
判断php数组是否为索引数组的实现方法
2013/06/13 PHP
PHP修改session_id示例代码
2014/01/08 PHP
适用于抽奖程序、随机广告的PHP概率算法实例
2014/04/09 PHP
php基于mcrypt_encrypt和mcrypt_decrypt实现字符串加密解密的方法
2016/07/12 PHP
一个判断email合法性的函数[非正则]
2008/12/09 Javascript
js GridView 实现自动计算操作代码
2009/03/25 Javascript
javascript闭包传参和事件的循环绑定示例探讨
2014/04/17 Javascript
javascript关于运动的各种问题经典总结
2015/04/27 Javascript
jQuery基于ajax实现星星评论代码
2015/08/07 Javascript
jQuery EasyUI Pagination实现分页的常用方法
2016/05/21 Javascript
jQuery版AJAX简易封装代码
2016/09/14 Javascript
使用JQuery选择HTML遍历函数的方法
2016/09/17 Javascript
微信小程序 自定义对话框实例详解
2017/01/20 Javascript
js实现适合新闻类图片的轮播效果
2017/02/05 Javascript
jQuery实现简单弹窗遮罩效果
2017/02/27 Javascript
详解JavaScript中return的用法
2017/05/08 Javascript
微信小程序scroll-view横向滑动嵌套for循环的示例代码
2018/09/20 Javascript
微信小程序以ssm做后台开发的实现示例
2020/04/08 Javascript
Vue 同步异步存值取值实现案例
2020/08/05 Javascript
vue实现标签云效果的示例
2020/11/09 Javascript
vue下拉刷新组件的开发及slot的使用详解
2020/12/23 Vue.js
在Python中用keys()方法返回字典键的教程
2015/05/21 Python
python中pip的安装与使用教程
2018/08/10 Python
Python使用pydub库对mp3与wav格式进行互转的方法
2019/01/10 Python
简单了解python gevent 协程使用及作用
2019/07/22 Python
python 在右键菜单中加入复制目标文件的有效存放路径(单斜杠或者双反斜杠)
2020/04/08 Python
Pandas把dataframe或series转换成list的方法
2020/06/14 Python
浅析CSS3 用text-overflow解决文字排版问题
2020/10/28 HTML / CSS
美国领先的奢侈手表在线零售商:WatchMaxx
2017/12/17 全球购物
可打印的优惠券、杂货和优惠券代码:Coupons.com
2018/06/12 全球购物
LUISAVIAROMA中国官网:时尚奢侈品牌购物网站
2020/11/01 全球购物
环保倡议书
2014/04/14 职场文书
十佳少先队员演讲稿
2014/09/12 职场文书
社区党的群众路线教育实践活动领导班子对照检查材料
2014/09/25 职场文书
政风行风评议个人心得体会
2014/10/29 职场文书
2015秋季田径运动会广播稿
2015/08/19 职场文书