利用纯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调用浏览器打印功能实例分析
Jul 17 Javascript
JavaScript实现点击单元格改变背景色的方法
Feb 12 Javascript
JQuery点击事件回到页面顶部效果的实现代码
May 24 Javascript
Jquery Easyui对话框组件Dialog使用详解(14)
Dec 19 Javascript
详解微信小程序——自定义圆形进度条
Dec 29 Javascript
Three.js基础部分学习
Jan 08 Javascript
Restify中接入Socket.io报Error:Can’t set headers的错误解决
Mar 28 Javascript
解决vue处理axios post请求传参的问题
Mar 05 Javascript
详解angular部署到iis出现404解决方案
Aug 14 Javascript
Vue开发环境中修改端口号的实现方法
Aug 15 Javascript
使用layui的router来进行传参的实现方法
Sep 06 Javascript
node koa2 ssr项目搭建的方法步骤
Dec 11 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中使用php://input处理相同name值的表单数据
2015/02/03 PHP
百度地图经纬度转换到腾讯地图/Google 对应的经纬度
2015/08/28 PHP
PHP实现的Redis多库选择功能单例类
2017/07/27 PHP
laravel5.4利用163邮箱发送邮件的步骤详解
2017/09/22 PHP
PHP CURL实现模拟登陆并上传文件操作示例
2020/01/02 PHP
Jjcarousellite 实现图片列表滚动的简单实例
2013/11/29 Javascript
调整小数的格式保留小数点后两位
2014/05/14 Javascript
禁止iframe脚本弹出的窗口覆盖了父窗口的方法
2014/09/06 Javascript
JavaScript sup方法入门实例(把字符串显示为上标)
2014/10/20 Javascript
express的中间件basicAuth详解
2014/12/04 Javascript
JavaScript计时器示例分析
2015/02/05 Javascript
JS和css实现检测移动设备方向的变化并判断横竖屏幕
2015/05/25 Javascript
Bootstrap3.0学习教程之JS折叠插件
2016/05/27 Javascript
Bootstrap Table使用心得总结
2016/11/29 Javascript
解析NodeJS异步I/O的实现
2017/04/13 NodeJs
VSCode 配置React Native开发环境的方法
2017/12/27 Javascript
React中使用外部样式的3种方式(小结)
2019/05/28 Javascript
Element Dialog对话框的使用示例
2020/07/26 Javascript
vue-simple-uploader上传成功之后的response获取代码
2020/09/07 Javascript
Python操作SQLite数据库的方法详解
2017/06/16 Python
使用python写的opencv实时监测和解析二维码和条形码
2019/08/14 Python
关于Python形参打包与解包小技巧分享
2019/08/24 Python
python Qt5实现窗体跟踪鼠标移动
2019/12/13 Python
django的模型类管理器——数据库操作的封装详解
2020/04/01 Python
前端面试必备之html5的新特性
2017/09/05 HTML / CSS
美国旅游网站:Tours4Fun
2017/02/17 全球购物
高尔夫球鞋、服装、手套和装备:FootJoy
2018/12/15 全球购物
银行职员自我鉴定
2014/04/20 职场文书
新文化运动的基本口号
2014/06/21 职场文书
2014年教师工作总结
2014/11/10 职场文书
金秋助学感谢信
2015/01/21 职场文书
百万英镑观后感
2015/06/09 职场文书
公司管理建议书
2015/09/14 职场文书
教你用Java Swing实现自助取款机系统
2021/06/11 Java/Android
JavaWeb Servlet开发注册页面实例
2022/04/11 Java/Android
python使用shell脚本创建kafka连接器
2022/04/29 Python