状态管理
- 状态管理,管理的是上下文对象的状态。
- 上下文对象的状态就是上下文对象的属性。比如描边颜色,填充颜色,投影,线条样式,变换信息…
- 管理上下文状态的方法有两个:
- 保存当前状态:
save()
- 恢复上一次保存的状态:
restore()
- 一般在我们绘制具备同一种样式的图形时,都会用save() restore() 将其包裹起来。这是为了避免当前的图形样式影响以后所要绘制的的图形样式。
状态的嵌套
a - save()
b - save()
restore() – b
restore() – a
变换
- 变换有3个特性:
- 移动: translate(x,y)
- 旋转: rotate(angle)
- 缩放: scale(x,y)
const canvas=document.getElementById('canvas');
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
const ctx=canvas.getContext('2d');
ctx.fillStyle='green';
ctx.translate(100,100);
ctx.rotate(Math.PI/24);
ctx.scale(0.5,0.5);
ctx.fillRect(100,100,400,200);
时钟
const canvas=document.getElementById('canvas');
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
const ctx=canvas.getContext('2d');
const [redA,redB,yellow]=['#db655c','#d63d46','#9f8d7d'];
const c=Math.PI*2;
const {width,height}=canvas;
!(function render(){
ctx.clearRect(0,0,width,height);
draw();
requestAnimationFrame(render);
})()
function draw(){
ctx.save();
ctx.translate(width/2,height/2);
ctx.rotate(-Math.PI/2);
ctx.save();
ctx.beginPath();
ctx.arc(
0,0,
145,
0,c
);
ctx.strokeStyle=redA;
ctx.lineWidth=20;
ctx.stroke();
ctx.beginPath();
ctx.arc(
0,0,
155,
0,c
);
ctx.strokeStyle=redB;
ctx.lineWidth=9;
ctx.stroke();
ctx.restore();
ctx.save();
ctx.beginPath();
ctx.lineWidth=15;
ctx.strokeStyle=redB;
for(let i=0;i<4;i++){
ctx.moveTo(90,0);
ctx.lineTo(120,0);
ctx.rotate(c/4);
}
ctx.stroke();
ctx.restore();
ctx.save();
ctx.beginPath();
ctx.lineWidth=6;
ctx.strokeStyle=yellow;
for(let i=0;i<12;i++){
if(i%3){
ctx.moveTo(90,0);
ctx.lineTo(120,0);
}
ctx.rotate(c/12);
}
ctx.stroke();
ctx.restore();
ctx.save();
ctx.beginPath();
ctx.lineWidth=3;
ctx.strokeStyle=yellow;
for(let i=0;i<60;i++){
if(i%5){
ctx.moveTo(118,0);
ctx.lineTo(120,0);
}
ctx.rotate(c/60);
}
ctx.stroke();
ctx.restore();
const {rh,rm,rs}=getRadian();
ctx.save();
ctx.beginPath();
ctx.lineWidth=9;
ctx.strokeStyle=yellow;
ctx.rotate(rh);
ctx.moveTo(-20,0);
ctx.lineTo(65,0);
ctx.stroke();
ctx.restore();
ctx.save();
ctx.beginPath();
ctx.lineWidth=4;
ctx.strokeStyle=yellow;
ctx.rotate(rm);
ctx.moveTo(-28,0);
ctx.lineTo(80,0);
ctx.stroke();
ctx.restore();
ctx.save();
ctx.beginPath();
ctx.lineWidth=2;
ctx.strokeStyle=redB;
ctx.rotate(rs);
ctx.moveTo(-30,0);
ctx.lineTo(88,0);
ctx.stroke();
ctx.restore();
ctx.save();
ctx.fillStyle=redB;
ctx.beginPath();
ctx.arc(0,0,10,0,c);
ctx.fill();
ctx.restore();
ctx.restore();
}
function getRadian(){
const date=new Date();
let h=date.getHours();
if(h>12){h-=12}
let m=date.getMinutes();
let s=date.getSeconds();
const rh=c*h/12+c*m/12/60+c*s/12/60/60;
const rm=c*m/60+c*s/60/60;
const rs=c*s/60;
return {rh,rm,rs};
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/b3c34fcf1a8d4f298a02348d21943c76.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5oiR5Zyo5Lq66Ze06LSp5Y2W6Z2S5pil,size_11,color_FFFFFF,t_70,g_se,x_16)