案例1:七巧板
将一系列坐标点及颜色存储在数组中,使用Canvas来绘制图像。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Canvas七巧板</title>
</head>
<body>
<canvas id="canvas" style="border:1px solid #ddd;margin:50px auto" >
当前浏览器不支持Canvas
</canvas>
<script>
var TG =[
{p:[{x:0,y:0},{x:800,y:0},{x:400,y:400}],color:"#caff67"},
{p:[{x:0,y:0},{x:400,y:400},{x:0,y:800}],color:"#67becf"},
{p:[{x:800,y:0},{x:800,y:400},{x:600,y:600},{x:600,y:200}],color:"#ef3d61"},
{p:[{x:600,y:200},{x:600,y:600},{x:400,y:400}],color:"#f9f51a"},
{p:[{x:400,y:400},{x:600,y:600},{x:400,y:800},{x:200,y:600}],color:"#a594c0"},
{p:[{x:200,y:600},{x:400,y:800},{x:0,y:800}],color:"#fa8ecc"},
{p:[{x:800,y:400},{x:800,y:800},{x:400,y:800}],color:"#f6ca29"}
];
window.onload=function(){
var canvas=document.getElementById("canvas");
canvas.width=800;
canvas.height=800;
var context=canvas.getContext("2d");
for (var i = 0; i < TG.length; i++) {
draw(TG[i],context);
}
function draw(piece,ctx){
ctx.beginPath();
ctx.moveTo(piece.p[0].x,piece.p[0].y);
for (var i = 0; i < piece.p.length; i++) {
ctx.lineTo(piece.p[i].x,piece.p[i].y);
ctx.fillStyle=piece.color;
ctx.fill();
}
}
}
</script>
</body>
</html>
案例2:简易涂鸦板
1 |
|
案例3:运动小球
1 |
|
案例4:倒计时电子钟
用二维数组存储阿拉伯数字0-9,将时间用Canvas绘制出来,’0’表示无图案,’1’表示小圆。同时绘制小球运动效果。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27digit =
[
[
[0,0,1,1,1,0,0],
[0,1,1,0,1,1,0],
[1,1,0,0,0,1,1],
[1,1,0,0,0,1,1],
[1,1,0,0,0,1,1],
[1,1,0,0,0,1,1],
[1,1,0,0,0,1,1],
[1,1,0,0,0,1,1],
[0,1,1,0,1,1,0],
[0,0,1,1,1,0,0]
],//0
[
[0,0,0,1,1,0,0],
[0,1,1,1,1,0,0],
[0,0,0,1,1,0,0],
[0,0,0,1,1,0,0],
[0,0,0,1,1,0,0],
[0,0,0,1,1,0,0],
[0,0,0,1,1,0,0],
[0,0,0,1,1,0,0],
[0,0,0,1,1,0,0],
[1,1,1,1,1,1,1]
],//1
...
绘制数字:
设圆的半径为R,圆与圆之间的间距为2px,所以圆所在的正方形格子的边长为2(R+1)。
其中x表示起始的横坐标,y表示起始的纵坐标,i表示行数,j表示列数,因此:
第(i,j)个圆的圆心位置:
centerx : x + j 2 (R+1) + (R+1);
centery : y + i 2 * (R+1) + (R+1)
简单倒计时电子钟
1 | var WINDOW_WIDTH = 1024; |
倒计时电子钟(小球运动)
在上面案例的基础上,加上小球运动图案的绘制。
部分代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85var balls=[];
window.onload=function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
canvas.width=Window_width;
canvas.height=Window_height;
curShowTimeSeconds = getCurrentShowTimeSeconds();
setInterval(function(){
render(ctx);
update();
},50)
}
function update(){
...
if (nextSeconds!=CurSeconds) {
if (parseInt(CurHours/10)!=parseInt(nextHours/10)) {
addBalls(Margin_left,Margin_top,parseInt(CurHours/10));
}
if (parseInt(CurHours%10)!=parseInt(nextHours%10)) {
addBalls(Margin_left+15*(Radius+1),Margin_top,parseInt(CurHours%10));
}
if( parseInt(CurMinutes/10) != parseInt(nextMinutes/10) ){
addBalls( Margin_left + 39*(Radius+1) , Margin_top , parseInt(CurMinutes/10) );
}
if( parseInt(CurMinutes%10) != parseInt(nextMinutes%10) ){
addBalls( Margin_left + 54*(Radius+1) , Margin_top , parseInt(CurMinutes%10) );
}
if( parseInt(CurSeconds/10) != parseInt(nextSeconds/10) ){
addBalls( Margin_left + 78*(Radius+1) , Margin_top , parseInt(CurSeconds/10) );
}
if( parseInt(CurSeconds%10) != parseInt(nextSeconds%10) ){
addBalls( Margin_left + 93*(Radius+1) , Margin_top , parseInt(CurSeconds%10) );
}
curShowTimeSeconds=nextShowTimeSeconds;
}
updateBalls();
}
function updateBalls(){
for (var i = 0; i < balls.length; i++) {
balls[i].x+=balls[i].vx;
balls[i].y+=balls[i].vy;
balls[i].vy+=balls[i].g;
if (balls[i].y>=Window_height-Radius) {
balls[i].y=Window_height-Radius;
balls[i].vy=-balls[i].vy*0.75;
}
}
}
function addBalls(x,y,num){
for( var i = 0 ; i < digit[num].length ; i ++ ){
for( var j = 0 ; j < digit[num][i].length ; j ++ ){
if( digit[num][i][j] == 1 ){
var aBall = {
x:x+j*2*(Radius+1)+(Radius+1),
y:y+i*2*(Radius+1)+(Radius+1),
g:1.5+Math.random(),
vx:Math.pow( -1 , Math.ceil( Math.random()*1000 ) ) * 4,
vy:-5,
color: colors[ Math.floor( Math.random()*colors.length ) ]
}
balls.push( aBall )
}
}
}
}
function render(ctx){
ctx.clearRect(0,0,Window_width,Window_height);
...
for( var i = 0 ; i < balls.length ; i ++ ){
ctx.fillStyle=balls[i].color;
ctx.beginPath();
ctx.arc( balls[i].x , balls[i].y , Radius , 0 , 2*Math.PI , true );
ctx.closePath();
ctx.fill();
}
}
倒计时电子钟(小球运动)-性能优化
1、屏幕自适应:1
2
3
4
5
6
7
8
9
10
11var Window_width=1200;
var Window_height=800;
var Radius=8;
var Margin_top=60;
var Margin_left=30;
window.onload=function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
canvas.width=Window_width;
canvas.height=Window_height;
}
将上面代码改为如下代码,同时设置html文件中的html,body,canvas标签的样式:style="height:100%"
1
2
3
4
5
6
7
8
9
10
11
12
13
14window.onload=function(){
Window_width = document.body.clientWidth;
Window_height = document.body.clientHeight;
Margin_left = Math.round(Window_width /10);
Radius = Math.round(Window_width * 4 / 5 / 108)-1;
Margin_top = Math.round(Window_height /5);
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
canvas.width=Window_width;
canvas.height=Window_height;
}
2、性能优化:
小球会持续增多,会导致一段时间后页面卡顿,因此,需要对小球更新函数进行修改,当小球溢出Canvas画布范围时,删除小球,从而使Canvas画布里留存适量的小球数量。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29function updateBalls(){
for (var i = 0; i < balls.length; i++) {
balls[i].x+=balls[i].vx;
balls[i].y+=balls[i].vy;
balls[i].vy+=balls[i].g;
if (balls[i].y>=Window_height-Radius) {
balls[i].y=Window_height-Radius;
balls[i].vy=-balls[i].vy*0.75;
}
}
// 性能优化:限制画布里的小球,使其不一直增加。
/*var cnt=0;
for (var i = 0; i < balls.length; i++) {
if (balls[i].x+Radius>0 && balls[i].x-Radius<Window_width) {
balls[cnt++]=balls[i];
}
}
while(balls.length>Math.min(300,cnt)){
balls.pop(); //从末尾删除小球。
}
*/
for (var i = 0; i < balls.length; i++) {
if (balls[i].x>canvas.width||balls[i].x<-Radius) {
balls.splice(i,1)
};
}
}
电子钟
将上面的倒计时变成时钟正常显示,主要是修改时间代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22var endTime =new Date();
endTime.setTime(endTime.getTime()+3600*1000);
window.onload=function(){
curShowTimeSeconds = getCurrentShowTimeSeconds();
}
function getCurrentShowTimeSeconds(){
var curTime=new Date();
var ret = endTime.getTime() - curTime.getTime();
ret = Math.round( ret/1000 )
return ret >= 0 ? ret : 0;
}
//将上面的代码变成如下代码:
window.onload=function(){
curShowTimeSeconds = getCurrentShowTimeSeconds();
}
function getCurrentShowTimeSeconds(){
var curTime=new Date();
var ret=curTime.getHours()*3600+curTime.getMinutes()*60+curTime.getSeconds();
//到现在共计多少秒。
return ret;
}