利用纯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 相关文章推荐
javascript GUID生成器实现代码
Oct 31 Javascript
ASP.NET MVC中EasyUI的datagrid跨域调用实现代码
Mar 14 Javascript
分享一道笔试题[有n个直线最多可以把一个平面分成多少个部分]
Oct 12 Javascript
jQuery中选择器小问题(新人难免遇到)
Mar 31 Javascript
JavaScript获取元素尺寸和大小操作总结
Feb 27 Javascript
JavaScript函数参数使用带参数名的方式赋值传入的方法
Mar 19 Javascript
javascript实现动态统计图开发实例
Nov 21 Javascript
Vue批量图片显示时遇到的路径被解析问题
Mar 28 Javascript
TypeScript类型声明书写详解
Aug 28 Javascript
微信小程序实现蓝牙打印
Sep 23 Javascript
原生js实现贪食蛇小游戏的思路详解
Nov 26 Javascript
JavaScript的一些小技巧分享
Jan 06 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入门教程之日期与时间操作技巧总结(格式化,验证,获取,转换,计算等)
2016/09/11 PHP
JavaScript 模拟用户单击事件
2009/12/31 Javascript
js中的异常处理try...catch使用介绍
2013/09/21 Javascript
jQuery选择器简明总结(含用法实例,一目了然)
2014/04/25 Javascript
JQuery的ON()方法支持的所有事件罗列
2015/02/28 Javascript
WebApi+Bootstrap+KnockoutJs打造单页面程序
2016/05/16 Javascript
jQuery实现鼠标滚动图片延迟加载效果附源码下载
2016/06/28 Javascript
在使用JSON格式处理数据时应该注意的问题小结
2017/05/20 Javascript
Vue 路由 过渡动效 数据获取方法
2018/07/31 Javascript
看看“疫苗查询”小程序有温度的代码
2018/07/31 Javascript
详解js的视频和音频采集
2018/08/09 Javascript
vue生成文件本地打开查看效果的实例
2018/09/06 Javascript
对angularJs中2种自定义服务的实例讲解
2018/09/30 Javascript
在JS循环中使用async/await的方法
2018/10/12 Javascript
vue组件化中slot的基本使用方法
2019/05/01 Javascript
解决vue单页面应用中动态修改title问题
2019/06/09 Javascript
jQuery中DOM常见操作实例小结
2019/08/01 jQuery
[07:55]2014DOTA2 TI正赛第三日 VG上演推进荣耀DKEG告别
2014/07/21 DOTA
[01:00:44]DOTA2上海特级锦标赛主赛事日 - 3 败者组第三轮#1COL VS Alliance第三局
2016/03/04 DOTA
Python编写检测数据库SA用户的方法
2014/07/11 Python
Python监控主机是否存活并以邮件报警
2015/09/22 Python
Python处理json字符串转化为字典的简单实现
2016/07/07 Python
Python 提取dict转换为xml/json/table并输出的实现代码
2016/08/28 Python
Python反爬虫技术之防止IP地址被封杀的讲解
2019/01/09 Python
浅谈python中频繁的print到底能浪费多长时间
2020/02/21 Python
Python下载网易云歌单歌曲的示例代码
2020/08/12 Python
Carter’s官方旗舰店:美国受欢迎的婴童服装品牌
2018/01/21 全球购物
大学新生欢迎词
2014/01/10 职场文书
销售顾问工作计划书
2014/09/15 职场文书
个人先进材料范文
2014/12/30 职场文书
幼儿园2015年度工作总结
2015/04/01 职场文书
2015年教师节广播稿
2015/08/19 职场文书
小学英语课教学反思
2016/02/15 职场文书
2019年市场部个人述职报告(三篇)
2019/10/23 职场文书
Log4j.properties配置及其使用
2021/08/02 Java/Android
python超详细实现完整学生成绩管理系统
2022/03/17 Python