Created
March 17, 2017 09:06
-
-
Save otizis/a6ee65a92eac0b7eac09606afc0caf7d to your computer and use it in GitHub Desktop.
学习canvas的操作
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Document</title> | |
</head> | |
<body> | |
<canvas id="myCanvas" width="600" height="400" style="border: 1px black solid"></canvas> | |
<script> | |
function Dot(centerX, centerY, color,startx,starty) { | |
this.x = centerX; | |
this.y = centerY; | |
this.color = color; | |
this.x2 = centerX + (Math.random() - 0.5)*5; | |
this.y2 = centerY + (Math.random() - 0.5)*5; | |
this.frameNum = 0;//示为这个粒子当前在第几帧 | |
this.frameCount = Math.ceil(3000 / 16.66);//表示一共有多少帧,一般来说我们不会直接知道做完这个动画一共有多少帧,所以这里我们是算出来的,parseInt(3000 / 16.66) 中3000表示3000毫秒,也就是整个动画耗时3秒,而16.66是因为按60FPS来算,浏览器对每一帧画面的渲染工作需要1秒 / 60 = 16.66毫秒,算出来之后再做个向上取整,就算出总帧数。 | |
this.startx = startx; | |
this.starty = starty; | |
this.delay = Math.random()*this.frameCount | |
} | |
function rgb2hex(red, green, blue) { | |
var rgb = blue | (green << 8) | (red << 16); | |
return '#' + (0x1000000 + rgb).toString(16).slice(1) | |
} | |
// 计算缓动的函数 | |
// t 当前时间 | |
// b 初始值 | |
// c 总位移 | |
// d 总时间 | |
function easeInOutCubic(t, b, c, d) { | |
if ((t/=d/2) < 1) return c/2*t*t*t + b; | |
return c/2*((t-=2)*t*t + 2) + b; | |
} | |
(function() { | |
var canvas=document.getElementById('myCanvas') | |
var ctx = null; | |
if(canvas.getContext){ | |
ctx = canvas.getContext('2d'); | |
} | |
var winWidth = canvas.width; | |
var winHeight = canvas.height; | |
var image = new Image(); | |
var imgW = image.width, | |
imgH = image.height; | |
var dotList=[]; | |
var endDotNum = 0; | |
var rafId=null; | |
function draw() { | |
// body.. | |
ctx.clearRect(0, 0, winWidth, winHeight); | |
var curDot; | |
var frameNum = 0,frameCount = 0,curX, curY; | |
var len = dotList.length; | |
for(var i=0; i< len; i++) | |
{ | |
curDot = dotList[i]; | |
if(curDot.delay > 0) | |
{ | |
curDot.delay-=2; | |
continue; | |
} | |
frameNum = curDot.frameNum; | |
frameCount = curDot.frameCount; | |
if(frameNum < frameCount){ | |
curx = easeInOutCubic(frameNum,curDot.startx,curDot.x2 - curDot.startx,frameCount); | |
cury = easeInOutCubic(frameNum,curDot.starty,curDot.y2 - curDot.starty,frameCount); | |
//设置填充颜色 | |
ctx.fillStyle = curDot.color; | |
//绘粒子到画布上 | |
ctx.fillRect(curx, cury ,1,1); | |
curDot.frameNum++; | |
}else if(frameNum == frameCount){ | |
//设置填充颜色 | |
ctx.fillStyle = curDot.color; | |
//绘粒子到画布上 | |
ctx.fillRect(curDot.x2, curDot.y2,1,1); | |
endDotNum++; | |
curDot.frameNum++; | |
}else{ | |
//设置填充颜色 | |
ctx.fillStyle = curDot.color; | |
//绘粒子到画布上 | |
ctx.fillRect(curDot.x2, curDot.y2,1,1); | |
} | |
} | |
if(endDotNum >= len) | |
{ | |
cancelAnimationFrame(rafId); | |
float(); | |
return; | |
} | |
rafId = requestAnimationFrame(draw); | |
} | |
function float(){ | |
// body.. | |
ctx.clearRect(0, 0, winWidth, winHeight); | |
var curDot; | |
var frameNum = 0,frameCount = 0,curX, curY; | |
var len = dotList.length; | |
for(var i=0; i< len; i++) | |
{ | |
curDot = dotList[i]; | |
if(curDot.delay > 0) | |
{ | |
curDot.delay-=2; | |
continue; | |
} | |
frameNum = curDot.frameNum; | |
frameCount = curDot.frameCount; | |
if(frameNum < frameCount){ | |
curx = easeInOutCubic(frameNum,curDot.startx,curDot.x2 - curDot.startx,frameCount); | |
cury = easeInOutCubic(frameNum,curDot.starty,curDot.y2 - curDot.starty,frameCount); | |
//设置填充颜色 | |
ctx.fillStyle = curDot.color; | |
//绘粒子到画布上 | |
ctx.fillRect(curx, cury ,1,1); | |
curDot.frameNum++; | |
}else if(frameNum == frameCount){ | |
//设置填充颜色 | |
ctx.fillStyle = curDot.color; | |
//绘粒子到画布上 | |
ctx.fillRect(curDot.x2, curDot.y2,1,1); | |
curDot.startx = curDot.x2; | |
curDot.starty = curDot.y2; | |
curDot.x2 = curDot.x + (Math.random() - 0.5)*20; | |
curDot.y2 = curDot.y + (Math.random() - 0.5)*20; | |
curDot.frameNum = 0; | |
curDot.frameCount = 20; | |
} | |
} | |
rafId = requestAnimationFrame(float); | |
} | |
image.onload = function () { | |
imgW = image.width; | |
imgH = image.height; | |
var sx = winWidth/2-imgW/2; | |
var sy = winHeight/2-imgH/2; | |
ctx.drawImage(image,sx,sy); | |
var imgData = ctx.getImageData(sx,sy,imgW,imgH); | |
console.log(imgData); | |
var forX = imgData.width; | |
var forY = imgData.height; | |
var imageArray = imgData.data; | |
for(var x=0; x<forX; x+=1) { | |
for(var y=0; y<forY; y+=1) { | |
//imgData.data代表的是rgba的值,比如说第一个数字0,代表第一个像素的R值,第二个数字0代表第一个像素的G值,第三第四个0分别代表第一个像素的B值和Alpha值,最后出来第一个像素就是个全透明的颜色,第五个数字就代表第二个像素的R值了。 | |
var i = (y*forX + x) * 4; | |
//imgData.data[i+3] > 128 表示alpha值不透明 | |
if((imageArray[i]+imageArray[i+1]+imageArray[i+2]+imageArray[i+3] < 900)&&imageArray[i+3] > 128){ | |
var dot = new Dot( | |
sx + x, | |
sy + y, | |
rgb2hex(imageArray[i],imageArray[i+1],imageArray[i+2],imageArray[i+3]), | |
winWidth*Math.random(), | |
winHeight*Math.random()); | |
dotList.push(dot); | |
} | |
} | |
} | |
console.log(dotList.length); | |
float(); | |
} | |
image.src = 'bug.png'; | |
})() | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment