利用纯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 30 Javascript
javascrip关于继承的小例子
May 10 Javascript
JavaScript自定义事件介绍
Aug 29 Javascript
jQuery响应enter键的实现思路
Apr 18 Javascript
完美兼容IE,chrome,ff的设为首页、加入收藏及保存到桌面js代码
Dec 17 Javascript
JavaScript实现自动变换表格边框颜色
May 08 Javascript
JavaScript中reduce()方法的使用详解
Jun 09 Javascript
APP中javascript+css3实现下拉刷新效果
Jan 27 Javascript
jQuery实现的tab标签切换效果示例
Sep 05 Javascript
微信小程序 image组件binderror使用例子与js中的onerror区别
Feb 15 Javascript
Vue.js常用指令之循环使用v-for指令教程
Jun 27 Javascript
JavaScript实现原型封装轮播图
Dec 27 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
成本8450万,票房仅2亿,口碑两极分化,又一部DC电影扑街了
2020/04/09 欧美动漫
PHP防盗链代码实例
2014/08/27 PHP
PHP生成不重复标识符的方法
2014/11/21 PHP
解读PHP中的垃圾回收机制
2015/08/10 PHP
laravel实现按月或天或小时统计mysql数据的方法
2019/10/09 PHP
BOOM vs RR BO5 第三场 2.14
2021/03/10 DOTA
jQuery Ajax之$.get()方法和$.post()方法
2009/10/12 Javascript
javascript获取下拉列表框当中的文本值示例代码
2013/07/31 Javascript
js实现改进的仿蓝色论坛导航菜单效果代码
2015/09/06 Javascript
如何根据百度地图计算出两地之间的驾驶距离(两种语言js和C#)
2015/10/29 Javascript
javascript实现保留两位小数的多种方法
2015/12/18 Javascript
js实现异步循环实现代码
2016/02/16 Javascript
JavaScript过滤字符串中的中文与空格方法汇总
2016/03/07 Javascript
Javascript的无new构建实例详解
2016/05/15 Javascript
AngularJS基础 ng-include 指令简单示例
2016/08/01 Javascript
浅谈js之字面量、对象字面量的访问、关键字in的用法
2016/11/20 Javascript
微信小程序与php 实现微信支付的简单实例
2017/06/23 Javascript
knockoutjs模板实现树形结构列表
2017/07/31 Javascript
Vue 父子组件数据传递的四种方式( inheritAttrs + $attrs + $listeners)
2018/05/04 Javascript
vue webpack打包后图片路径错误的完美解决方法
2018/12/07 Javascript
用npm-run实现自动化任务的方法示例
2019/01/14 Javascript
vue与bootstrap实现简单用户信息添加删除功能
2019/02/15 Javascript
Vue axios与Go Frame后端框架的Options请求跨域问题详解
2020/03/03 Javascript
vue+iview框架实现左侧动态菜单功能的示例代码
2020/07/23 Javascript
小程序实现tab标签页
2020/11/16 Javascript
[05:45]Ti4观战指南(下)
2014/07/07 DOTA
Python中不同进制互相转换(二进制、八进制、十进制和十六进制)
2015/04/05 Python
Python Scrapy框架第一个入门程序示例
2020/02/05 Python
用python对oracle进行简单性能测试
2020/12/05 Python
css3类选择器之结合元素选择器和多类选择器用法
2017/03/09 HTML / CSS
关于HTML5你必须知道的28个新特性,新技巧以及新技术
2012/05/28 HTML / CSS
亚瑟士美国官网:ASICS美国
2017/02/01 全球购物
欧舒丹比利时官网:L’OCCITANE比利时
2017/04/25 全球购物
Pamela Love官网:纽约设计师Pamela Love的精美、时尚和穿孔珠宝
2020/10/19 全球购物
团支部建设方案
2014/05/02 职场文书
Nginx本地配置SSL访问的实例教程
2022/05/30 Servers