带你使用canvas制作马赛克&canvas飞鸟动画&小球动画 您所在的位置:网站首页 马赛克画效果图 带你使用canvas制作马赛克&canvas飞鸟动画&小球动画

带你使用canvas制作马赛克&canvas飞鸟动画&小球动画

2024-06-17 01:38| 来源: 网络整理| 查看: 265

在这里插入图片描述

文章目录 canvas制作马赛克&飞鸟动画&小球拖拽动画一、了解单像素操作1、在canvas中的像素操作2、得到场景像素数据3、ImageData对象4、在场景中写入像素数据5、创建一个ImageData对象 二、canvas使用图片1、在canvas中插入图片(需要image对象)2、在canvas中设置背景(需要image对象)渐变 三、飞鸟动画效果图完整代码 四、操作单个像素(行与列)示例一效果图示例二HTML&CSS获取某个点的像素设置某个点的像素完整JavaScript代码效果图 五、马赛克HTML&CSS选取马赛克矩形单像素操作完整代码效果图 六、小球动画1、角度与弧度的js表达式:2、canvas绘制圆形3、arcTo4、实现小球拖拽与自动移动动画 七、后记

canvas制作马赛克&飞鸟动画&小球拖拽动画

在这里插入图片描述 在这里插入图片描述

在这里插入图片描述

一、了解单像素操作 1、在canvas中的像素操作

到目前为止,我们尚未深入了解Canvas画布真实像素的原理,事实上, 你可以直接通过ImageData对象操纵像素数据,直接读取或将数据数组写入该对象中

2、得到场景像素数据

getImageData():获得一个包含画布场景像素数据的ImageData对像,它代表了画布区域的对象数据

ctx.getImageData(sx, sy, sw, sh) sx:将要被提取的图像数据矩形区域的左上角 x 坐标。 sy:将要被提取的图像数据矩形区域的左上角 y 坐标。 sw:将要被提取的图像数据矩形区域的宽度。 sh:将要被提取的图像数据矩形区域的高度。 3、ImageData对象

ImageData对象中存储着canvas对象真实的像素数据,它包含以下几个只读属性: width:图片宽度,单位是像素 height:图片高度,单位是像素 data:Uint8ClampedArray类型的一维数组, 包含着RGBA格式的整型数据,范围在0至255之间(包括255) R:0 --> 255(黑色到白色) G:0 --> 255(黑色到白色) B:0 --> 255(黑色到白色) A:0 --> 255(透明到不透明)

4、在场景中写入像素数据

putImageData()方法去对场景进行像素数据的写入。 putImageData(myImageData, dx, dy) dx和dy参数表示你希望在场景内左上角绘制的像素数据所得到的设备坐标

5、创建一个ImageData对象 ctx.createImageData(width, height); width : ImageData 新对象的宽度。 height: ImageData 新对象的高度。

默认创建出来的是透明的

二、canvas使用图片 1、在canvas中插入图片(需要image对象)

1.canvas操作图片时,必须要等图片加载完才能操作 2.drawImage(image, x, y, width, height) 其中 image是 image或者canvas对象,x 和 y是其在目标 canvas 里的起始坐标。 这个方法多了2个参数:width 和 height,这两个参数用来控制 当像canvas画入时应该缩放的大小

* { margin: 0; padding: 0; } html, body { height: 100%; overflow: hidden; } body { background: pink; } #test { background: gray; position: absolute; left: 0; top: 0; right: 0; bottom: 0; margin: auto; } 您的浏览器不支持画布元素 请您换成萌萌的谷歌 window.onload = function() { var canvas = document.querySelector("#test"); if (canvas.getContext) { var ctx = canvas.getContext("2d"); var img = new Image(); //加载图片 img.src = "tg.png"; img.onload = function() { draw(); //加载成功之后 } function draw() { ctx.drawImage(img, 0, 0, img.width, img.height) } } }

在这里插入图片描述

2、在canvas中设置背景(需要image对象) 1.createPattern(image, repetition) image:图像源 epetition: "repeat" "repeat-x" "repeat-y" "no-repeat"

一般情况下,我们都会将createPattern返回的对象作为fillstyle的值

渐变

canvas渐变(线性渐变) createLinearGradient(x1, y1, x2, y2) 表示渐变的起点 (x1,y1) 与终点 (x2,y2)

gradient.addColorStop(position, color) gradient :createLinearGradient的返回值 addColorStop方法接受 2 个参数, position 参数必须是一个 0.0 与 1.0 之间的数值,表示渐变中颜色所在的相对位置。 例如,0.5 表示颜色会出现在正中间。 color 参数必须是一个有效的 CSS 颜色值(如 #FFF, rgba(0,0,0,1),等等)

* { margin: 0; padding: 0; } html, body { height: 100%; overflow: hidden; } body { background: pink; } #test { background: gray; position: absolute; left: 0; top: 0; right: 0; bottom: 0; margin: auto; } 您的浏览器不支持画布元素 请您换成萌萌的谷歌 window.onload = function() { var canvas = document.querySelector("#test"); if (canvas.getContext) { var ctx = canvas.getContext("2d"); /*var img = new Image(); img.src="tg.png"; img.οnlοad=function(){ draw(); }*/ // function draw(){ var gradient = ctx.createLinearGradient(0, 0, 300, 300); gradient.addColorStop(0, "red"); gradient.addColorStop(0.5, "yellow"); gradient.addColorStop(0.7, "pink"); gradient.addColorStop(1, "green"); ctx.fillStyle = gradient; ctx.fillRect(0, 0, 300, 300); // } } }

在这里插入图片描述

canvas渐变(径向渐变) createRadialGradient(x1, y1, r1, x2, y2, r2) 前三个参数则定义另一个以(x1,y1) 为原点,半径为 r1 的圆, 后三个参数则定义另一个以 (x2,y2) 为原点,半径为 r2 的圆。

*{ margin: 0; padding: 0; } html,body{ height: 100%; overflow: hidden; } body{ background: pink; } #test{ background: gray; position: absolute; left: 0; top: 0; right: 0; bottom: 0; margin: auto; } 您的浏览器不支持画布元素 请您换成萌萌的谷歌 window.onload=function(){ var canvas = document.querySelector("#test"); if(canvas.getContext){ var ctx = canvas.getContext("2d"); /*var img = new Image(); img.src="tg.png"; img.οnlοad=function(){ draw(); }*/ // function draw(){ var gradient = ctx.createRadialGradient(150, 150, 50, 150, 150, 100) gradient.addColorStop(0,"red"); gradient.addColorStop(0.5,"yellow"); gradient.addColorStop(0.7,"pink"); gradient.addColorStop(1,"green"); ctx.fillStyle=gradient; ctx.fillRect(0,0,300,300); // } } }

在这里插入图片描述

三、飞鸟动画 效果图

在这里插入图片描述

完整代码 *{ margin: 0; padding: 0; } html,body{ height: 100%; overflow: hidden; } body{ background: pink; } #test{ background: white; position: absolute; left: 0; top: 0; right: 0; bottom: 0; margin: auto; } 您的浏览器不支持画布元素 请您换成萌萌的谷歌 window.onload=function(){ var canvas = document.querySelector("#test"); canvas.width = document.documentElement.clientWidth; canvas.height = document.documentElement.clientHeight; if(canvas.getContext){ var ctx = canvas.getContext("2d"); var flag = 0; var value=0; setInterval(function(){ ctx.clearRect(0,0,canvas.width,canvas.height) value+=10; flag++; if(flag==9){ flag=1; } var img = new Image(); img.src="img/q_r"+(flag)+".jpg"; img.onload=function(){ draw(this); } },100) function draw(img){ ctx.drawImage(img,value,0) } } } 四、操作单个像素(行与列) 示例一 *{ margin: 0; padding: 0; } html,body{ height: 100%; overflow: hidden; } body{ background: pink; } #test{ background: gray; position: absolute; left: 0; top: 0; right: 0; bottom: 0; margin: auto; } 您的浏览器不支持画布元素 请您换成萌萌的谷歌 window.onload=function(){ var canvas = document.querySelector("#test"); if(canvas.getContext){ var ctx = canvas.getContext("2d"); // ctx.fillStyle="rgba(255, 192, 203,1)"; // ctx.fillRect(0,0,100,100); //100*100 10000个像素点 /*imageData width:横向上像素点的个数 height:纵向上像素点的个数 data:数组 每一个像素点的rgba信息 */ //默认创建出来 rgba(0,0,0,0) var imageData = ctx.createImageData(100,100); for(var i=0;i margin: 0; padding: 0; } html, body { height: 100%; overflow: hidden; } body { background: pink; } #test { background: gray; position: absolute; left: 0; top: 0; right: 0; bottom: 0; margin: auto; } 您的浏览器不支持画布元素 请您换成萌萌的谷歌 获取某个点的像素

求出该点像素的坐标关系 在这里插入图片描述

function getPxInfo(imgdata, x, y) { var color = []; var data = imgdata.data; var w = imgdata.width; var h = imgdata.height; //(x,y) x*w+y //r color[0] = data[(y * w + x) * 4]; //g color[1] = data[(y * w + x) * 4 + 1]; //b color[2] = data[(y * w + x) * 4 + 2]; //a color[3] = data[(y * w + x) * 4 + 3]; return color; } 设置某个点的像素 function setPxInfo(imgdata, x, y, color) { var data = imgdata.data; var w = imgdata.width; var h = imgdata.height; //(x,y) x*w+y x:多少列 y:多少行 //r data[(y * w + x) * 4] = color[0]; //g data[(y * w + x) * 4 + 1] = color[1]; //b data[(y * w + x) * 4 + 2] = color[2]; //a data[(y * w + x) * 4 + 3] = color[3]; } 完整JavaScript代码 window.onload = function() { var canvas = document.querySelector("#test"); if (canvas.getContext) { var ctx = canvas.getContext("2d"); ctx.save(); ctx.fillStyle = "pink"; ctx.beginPath(); ctx.fillRect(50, 50, 100, 100); ctx.restore(); var imgdata = ctx.getImageData(0, 0, canvas.width, canvas.height); /*var color = getPxInfo(imgdata,49,49); console.log(color);*/ for (var i = 0; i setPxInfo(imgdata, i, 50, [0, 0, 0, 255]); } ctx.putImageData(imgdata, 0, 0); function getPxInfo(imgdata, x, y) { var color = []; var data = imgdata.data; var w = imgdata.width; var h = imgdata.height; //(x,y) x*w+y //r color[0] = data[(y * w + x) * 4]; //g color[1] = data[(y * w + x) * 4 + 1]; //b color[2] = data[(y * w + x) * 4 + 2]; //a color[3] = data[(y * w + x) * 4 + 3]; return color; } function setPxInfo(imgdata, x, y, color) { var data = imgdata.data; var w = imgdata.width; var h = imgdata.height; //(x,y) x*w+y x:多少列 y:多少行 //r data[(y * w + x) * 4] = color[0]; //g data[(y * w + x) * 4 + 1] = color[1]; //b data[(y * w + x) * 4 + 2] = color[2]; //a data[(y * w + x) * 4 + 3] = color[3]; } } 效果图

平行X轴

for (var i = 0; i setPxInfo(imgdata, i, 50, [0, 0, 0, 255]); }

在这里插入图片描述

五、马赛克 HTML&CSS * { margin: 0; padding: 0; } html, body { height: 100%; overflow: hidden; } #msk { position: absolute; left: 50%; top: 50%; transform: translate3d(-50%, -50%, 0); /*background: gray;*/ } 选取马赛克矩形 选取一个马赛克矩形(可以通过size调节模糊程度)从马赛克矩形中随机抽出一个像素点的信息(rgba)将整个马赛克矩形中的像素点信息统一调成随机抽出的那个 function draw() { ctx.drawImage(img, 0, 0); var oldImgdata = ctx.getImageData(0, 0, img.width, img.height); var newImgdata = ctx.createImageData(img.width, img.height); //马赛克 /* 1.选取一个马赛克矩形 2.从马赛克矩形中随机抽出一个像素点的信息(rgba) 3.将整个马赛克矩形中的像素点信息统一调成随机抽出的那个 */ //选取一个马赛克矩形 var size = 5; for (var i = 0; i //(i,j) 每一个马赛克矩形的坐标 //(0,0): (0,0) (4,4);[0,4] //(1,0): (5,0) (9,4) //(0,1): (0,5) (4,9) //(1,1): (5,5) (9,9) //Math.random() [0,1) //Math.random()*size [0,5) //Math.floor(Math.random()*size) [0,4] //从马赛克矩形中随机抽出一个像素点的信息(rgba) var color = getPxInfo(oldImgdata, i * size + Math.floor(Math.random() * size), j * size + Math.floor(Math.random() * size)); //将整个马赛克矩形中的像素点信息统一调成随机抽出的那个 for (var a = 0; a setPxInfo(newImgdata, i * size + a, j * size + b, color) } } } } 单像素操作 function getPxInfo(imgdata, x, y) { var color = []; var data = imgdata.data; var w = imgdata.width; var h = imgdata.height; color[0] = data[(y * w + x) * 4]; color[1] = data[(y * w + x) * 4 + 1]; color[2] = data[(y * w + x) * 4 + 2]; color[3] = data[(y * w + x) * 4 + 3]; return color; } function setPxInfo(imgdata, x, y, color) { var data = imgdata.data; var w = imgdata.width; var h = imgdata.height; data[(y * w + x) * 4] = color[0]; data[(y * w + x) * 4 + 1] = color[1]; data[(y * w + x) * 4 + 2] = color[2]; data[(y * w + x) * 4 + 3] = color[3]; } 完整代码 * { margin: 0; padding: 0; } html, body { height: 100%; overflow: hidden; } #msk { position: absolute; left: 50%; top: 50%; transform: translate3d(-50%, -50%, 0); /*background: gray;*/ } var oc = document.querySelector("#msk"); if (oc.getContext) { var ctx = oc.getContext("2d"); var img = new Image(); img.src = "2.png"; img.onload = function() { oc.width = img.width * 2; oc.height = img.height * 2; draw(); } function draw() { ctx.drawImage(img, 0, 0); var oldImgdata = ctx.getImageData(0, 0, img.width, img.height); var newImgdata = ctx.createImageData(img.width, img.height); //马赛克 /* 1.选取一个马赛克矩形 2.从马赛克矩形中随机抽出一个像素点的信息(rgba) 3.将整个马赛克矩形中的像素点信息统一调成随机抽出的那个 */ //选取一个马赛克矩形 var size = 5; for (var i = 0; i //(i,j) 每一个马赛克矩形的坐标 //(0,0): (0,0) (4,4);[0,4] //(1,0): (5,0) (9,4) //(0,1): (0,5) (4,9) //(1,1): (5,5) (9,9) //从马赛克矩形中随机抽出一个像素点的信息(rgba) var color = getPxInfo(oldImgdata, i * size + Math.floor(Math.random() * size), j * size + Math.floor(Math.random() * size)); //将整个马赛克矩形中的像素点信息统一调成随机抽出的那个 for (var a = 0; a setPxInfo(newImgdata, i * size + a, j * size + b, color) } } } } ctx.putImageData(newImgdata, img.width, 0); } function getPxInfo(imgdata, x, y) { var color = []; var data = imgdata.data; var w = imgdata.width; var h = imgdata.height; color[0] = data[(y * w + x) * 4]; color[1] = data[(y * w + x) * 4 + 1]; color[2] = data[(y * w + x) * 4 + 2]; color[3] = data[(y * w + x) * 4 + 3]; return color; } function setPxInfo(imgdata, x, y, color) { var data = imgdata.data; var w = imgdata.width; var h = imgdata.height; data[(y * w + x) * 4] = color[0]; data[(y * w + x) * 4 + 1] = color[1]; data[(y * w + x) * 4 + 2] = color[2]; data[(y * w + x) * 4 + 3] = color[3]; } } 效果图

在这里插入图片描述

六、小球动画

在这里插入图片描述

1、角度与弧度的js表达式:

radians=(Math.PI/180)*degrees。

2、canvas绘制圆形

arc(x, y, radius, startAngle, endAngle, anticlockwise) 画一个以(x,y)为圆心的以radius为半径的圆弧(圆),从startAngle开始到endAngle结束, 按照anticlockwise给定的方向(默认为顺时针)来生成。 ture:逆时针 false:顺时针 x,y为绘制圆弧所在圆上的圆心坐标 radius为半径 startAngle以及endAngle参数用弧度定义了开始以及结束的弧度。这些都是以x轴为基准 参数anticlockwis 为一个布尔值。为true时,是逆时针方向,否则顺时针方向。

3、arcTo

arcTo(x1, y1, x2, y2, radius) 根据给定的控制点和半径画一段圆弧 肯定会从(x1 y1) 但不一定经过(x2 y2);(x2 y2)只是控制一个方向

4、实现小球拖拽与自动移动动画 Document * { margin: 0; padding: 0; } html, body { height: 100%; overflow: hidden; } #canvas { position: absolute; left: 0; right: 0; top: 0; bottom: 0; margin: auto; background-color: rgb(255, 235, 205); } var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); var raf; var running = false; console.log(canvas.offsetHeight, canvas.offsetLeft); var ball = { x: 100, y: 100, vx: 5, vy: 1, radius: 25, color: 'blue', draw: function() { ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true); ctx.closePath(); ctx.fillStyle = this.color; ctx.fill(); } }; function clear() { ctx.fillStyle = 'rgba(255, 235, 205,0.3)'; ctx.fillRect(0, 0, canvas.width, canvas.height); } function draw() { clear(); ball.draw(); ball.x += ball.vx; ball.y += ball.vy; if (ball.y + ball.vy > canvas.height || ball.y + ball.vy ball.vx = -ball.vx; } raf = window.requestAnimationFrame(draw); } canvas.addEventListener('mousemove', function(e) { if (!running) { clear(); ball.x = e.clientX - canvas.offsetLeft; ball.y = e.clientY - canvas.offsetTop; // console.log(e.clientX, e.clientY); ball.draw(); } }); canvas.addEventListener('click', function(e) { if (!running) { raf = window.requestAnimationFrame(draw); running = true; } }); canvas.addEventListener('mouseout', function(e) { window.cancelAnimationFrame(raf); running = false; }); ball.draw();

在这里插入图片描述

七、后记 喜欢的话可以关注我哦,相互交流学习。

在这里插入图片描述 在这里插入图片描述



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有