利用纯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 大数据相加的问题
Aug 03 Javascript
主页面中的两个iframe实现鼠标拖动改变其大小
Apr 16 Javascript
JS+CSS实现一个气泡提示框
Aug 18 Javascript
运用JQuery的toggle实现网页加载完成自动弹窗
Mar 18 Javascript
使用Jquery实现每日签到功能
Apr 03 Javascript
js实现模拟计算器退格键删除文字效果的方法
May 07 Javascript
微信小程序 表单Form实例详解(附源码)
Dec 22 Javascript
js实现九宫格拼图小游戏
Feb 13 Javascript
JS实现多张图片预览同步上传功能
Jun 23 Javascript
angular4模块中给标签添加背景图的实现方法
Sep 15 Javascript
Angular5中调用第三方js插件的方法
Feb 26 Javascript
JS模拟实现哈希表及应用详解
May 04 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 函数使用方法与函数定义方法
2010/05/09 PHP
PHP_Cooikes不同页面无法传递的解决方法
2014/03/07 PHP
Yii操作数据库的3种方法
2014/03/11 PHP
php判断页面是否是微信打开的示例(微信打开网页)
2014/04/25 PHP
thinkphp使用phpmailer发送邮件的方法
2014/11/24 PHP
laravel配置Redis多个库的实现方法
2019/04/10 PHP
JavaScript 入门基础知识 想学习js的朋友可以参考下
2009/12/26 Javascript
jquery实用代码片段集合
2010/08/12 Javascript
JSChart轻量级图形报表工具(内置函数中文参考)
2010/10/11 Javascript
通过JS获取用户本地图片路径并显示的代码
2012/02/16 Javascript
js数组操作常用方法
2014/05/08 Javascript
JS实现清除指定cookies的方法
2014/09/20 Javascript
基于Javascript实现文件实时加载进度的方法
2016/10/12 Javascript
浅谈javascript alert和confirm的美化
2016/12/15 Javascript
angularjs实现多张图片上传并预览功能
2017/02/24 Javascript
基于jQuery实现定位导航位置效果
2017/11/15 jQuery
mint-ui 时间插件使用及获取选择值的方法
2018/02/09 Javascript
浅析node.js的模块加载机制
2018/05/25 Javascript
ES6的异步终极解决方案分享
2019/07/11 Javascript
angular8和ngrx8结合使用的步骤介绍
2019/12/01 Javascript
js实现计时器秒表功能
2019/12/16 Javascript
多个Vue项目部署到服务器的步骤记录
2020/10/22 Javascript
python实现端口转发器的方法
2015/03/13 Python
Python实现列表转换成字典数据结构的方法
2016/03/11 Python
Python入门教程之运算符与控制流
2016/08/17 Python
Python复数属性和方法运算操作示例
2017/07/21 Python
python将字符串以utf-8格式保存在txt文件中的方法
2018/10/30 Python
python 获取一个值在某个区间的指定倍数的值方法
2018/11/12 Python
Django将默认的SQLite更换为MySQL的实现
2019/11/18 Python
html5通过postMessage进行跨域通信的方法
2017/12/04 HTML / CSS
利用canvas实现图片压缩的示例代码
2018/07/17 HTML / CSS
Mio Skincare法国官网:身体紧致及孕期身体护理
2018/04/04 全球购物
美国时尚假发购物网站:Wigsbuy
2019/04/06 全球购物
幼儿园校园小喇叭广播稿
2014/10/17 职场文书
酒店采购员岗位职责
2015/04/03 职场文书
学校捐书活动总结
2015/05/08 职场文书