HTML5 Canvas 六角光阑动态效果

时间:2023-02-09 09:16:08

光阑是光具组件中光学元件的边缘、框架或特别设置的带孔屏障,本人实现了结构比较简单的六角光阑,效果有点像宇航员在徐徐张开的飞船舷窗中看到逐渐完整的地球,下面四张图可以感受一下。

HTML5 Canvas 六角光阑动态效果HTML5 Canvas 六角光阑动态效果

HTML5 Canvas 六角光阑动态效果HTML5 Canvas 六角光阑动态效果

当然看动态效果才能真正体验,要看完整的演示请下载:https://files.cnblogs.com/files/xiandedanteng/slotAnimation.rar 并用chrome打开。

代码如下:

<!DOCTYPE html>
<html lang="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<head>
<title>六角光阑</title>
</head>

<body onload="draw()">
<canvas id="myCanvus" width="400px" height="400px" style="border:1px dashed black;">
出现文字表示你的浏览器不支持HTML5
</canvas>
</body>
</html>
<script type="text/javascript">
<!--
function draw(){
var canvas=document.getElementById('myCanvus');
canvas.width
=400;
canvas.height
=400;


context
=canvas.getContext('2d');
context.translate(
200,200);

animate();
};

var delta=0;// 旋转角
var radius=0;// 旋转半径
var outerRad=200;// 外径
var context;

function animate(){
context.clearRect(
-200,-200,400,400);// 清屏


var s=new Slot();
s.update(radius,delta,outerRad);
s.paintBg(context);
s.paint(context);
s.paintBase(context);

delta
+=1;
radius
+=1;

if(radius<outerRad){
// 让浏览器自行决定帧速率
window.requestAnimationFrame(animate);
}
}

// 角度得到弧度
function getRad(degree){
return degree/180*Math.PI;
}

function Slot(){
var obj=new Object;

obj.bx
=0;
obj.by
=0;
obj.cx
=0;
obj.cy
=0;
obj.dx
=0;
obj.dy
=0;
obj.angleC
=0;
obj.angleD
=0;
obj.radius
=0;
obj.outerRad
=0;
obj.img;


// 计算
obj.update=function(radius,theta,outerRad){
this.img=new Image();
this.img.src="earth.jpg";
this.radius=radius;
this.outerRad=outerRad;

this.bx=radius*Math.cos(getRad(theta+60));
this.by=radius*Math.sin(getRad(theta+60));

var alpha=Math.asin(radius*Math.sin(getRad(60))/this.outerRad);
this.angleC=getRad(theta)+alpha;
this.cx=outerRad*Math.cos(this.angleC);
this.cy=outerRad*Math.sin(this.angleC);

this.angleD=this.angleC-Math.PI/3;
this.dx=outerRad*Math.cos(this.angleD);
this.dy=outerRad*Math.sin(this.angleD);
};

// 画背景
obj.paintBg=function(ctx){
context.drawImage(
this.img,0,0,800,800,-200,-200,400,400);
};

// 描光阑
obj.paint=function(ctx){
ctx.strokeStyle
= "black";

for(var i=0;i<6;i++){
ctx.save();
ctx.fillStyle
= getColor(i+5);
ctx.rotate(Math.PI
/3*i);

ctx.beginPath();

ctx.lineTo(
this.bx,this.by);
ctx.lineTo(
this.dx,this.dy);
ctx.arc(
0,0,this.outerRad,this.angleD,this.angleC,false);
ctx.lineTo(
this.bx,this.by);

ctx.closePath();
ctx.stroke();
ctx.fill();

ctx.restore();
}
};

// 描基座
obj.paintBase=function(ctx){
ctx.strokeStyle
= "black";

for(var i=0;i<4;i++){
ctx.save();
ctx.fillStyle
= getColor(13);
ctx.rotate(Math.PI
/2*i);

ctx.beginPath();


ctx.arc(
0,0,this.outerRad,0,Math.PI/2,false);
ctx.lineTo(this.outerRad,this.outerRad);
ctx.lineTo(
this.outerRad,0);

ctx.closePath();
ctx.stroke();
ctx.fill();

ctx.restore();
}
};

return obj;
}

// 得到颜色
function getColor(index){
if(index==0){
return "green";
}
else if(index==1){
return "silver";
}
else if(index==2){
return "lime";
}
else if(index==3){
return "gray";
}
else if(index==4){
return "white";
}
else if(index==5){
return "yellow";
}
else if(index==6){
return "maroon";
}
else if(index==7){
return "navy";
}
else if(index==8){
return "red";
}
else if(index==9){
return "blue";
}
else if(index==10){
return "purple";
}
else if(index==11){
return "teal";
}
else if(index==12){
return "fuchsia";
}
else if(index==13){
return "aqua";
}
else if(index==14){
return "black";
}
}

//-->
</script>