![在这里插入图片描述](https://img-blog.csdnimg.cn/20200425131859199.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1NzY4ODcx,size_16,color_FFFFFF,t_70#pic_center)
文章目录
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制作马赛克&飞鸟动画&小球拖拽动画
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200425133207638.gif)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200425133951135.gif)
一、了解单像素操作
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)
}
}
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200425132815210.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1NzY4ODcx,size_16,color_FFFFFF,t_70)
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);
// }
}
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200425132624472.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1NzY4ODcx,size_16,color_FFFFFF,t_70)
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);
// }
}
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200425132718357.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1NzY4ODcx,size_16,color_FFFFFF,t_70)
三、飞鸟动画
效果图
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200425133207638.gif)
完整代码
*{
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;
}
您的浏览器不支持画布元素 请您换成萌萌的谷歌
获取某个点的像素
求出该点像素的坐标关系 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200425130616260.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1NzY4ODcx,size_16,color_FFFFFF,t_70)
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]);
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200425130821646.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1NzY4ODcx,size_16,color_FFFFFF,t_70)
五、马赛克
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];
}
}
效果图
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200425131731245.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1NzY4ODcx,size_16,color_FFFFFF,t_70)
六、小球动画
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200425133951135.gif)
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();
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200425133951135.gif)
七、后记
喜欢的话可以关注我哦,相互交流学习。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200425132052643.gif#pic_center)
|