0

【Canvas与艺术】模拟八一电影制片厂电影片头效果

 1 month ago
source link: https://blog.51cto.com/u_7726611/10230638
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

【Canvas与艺术】模拟八一电影制片厂电影片头效果

精选 原创

科技之巅 2024-03-27 23:04:50 博主文章分类:代码艺术 ©著作权

文章标签 Canvas 八一厂 片头 文章分类 代码人生

八一厂每部电影前都有其专有开头,如:https://www.ixigua.com/6799821997258834440?logTag=2eacce76401e13f9efe7 ,令人印象深刻。

这个片头可以用canvas模拟一部分。

【关键点】

线型放射状粒子系统的运作。

立体感五角星的绘制。

【Canvas与艺术】模拟八一电影制片厂电影片头效果_Canvas 八一厂 片头
【Canvas与艺术】模拟八一电影制片厂电影片头效果_Canvas 八一厂 片头_02
【Canvas与艺术】模拟八一电影制片厂电影片头效果_Canvas 八一厂 片头_03
<!DOCTYPE html>
<html lang="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<head>
     <title>模拟八一电影制片厂片头</title>
     <style type="text/css">
     .centerlize{
        margin:0 auto;
        width:1200px;
     }
     </style>
	 </head>

     <body onload="init();">
        <div class="centerlize">
            <canvas id="myCanvas" width="10px" height="10px" style="border:1px dotted black;">
                如果看到这段文字说您的浏览器尚不支持HTML5 Canvas,请更换浏览器再试.
            </canvas>
        </div>
     </body>
</html>
<script type="text/javascript">
<!--
/*****************************************************************
* 将全体代码(从<!DOCTYPE到script>)拷贝下来,粘贴到文本编辑器中,
* 另存为.html文件,再用chrome浏览器打开,就能看到实现效果。
******************************************************************/

// canvas的绘图环境
var ctx;

// 边长
const WIDTH=1000;
const HEIGHT=540;

// 舞台对象
var stage;

//-------------------------------
// 初始化
//-------------------------------
function init(){
	// 获得canvas对象
	var canvas=document.getElementById('myCanvas');  
	canvas.width =WIDTH;
	canvas.height=HEIGHT;

	// 初始化canvas的绘图环境
	ctx=canvas.getContext('2d');  
	ctx.translate(WIDTH/2,HEIGHT/2);// 原点平移到画布中央

	// 准备
	stage=new Stage();	
	stage.init();

	// 开幕
    animate();
}

// 播放动画
function animate(){    
    stage.update();	
	stage.paintBg(ctx);
	stage.paintFg(ctx);	 

	// 循环
    if(true){
		window.requestAnimationFrame(animate);   
    }
}

// 舞台类
function Stage(){
	// 粒子数量
	this.starCnt=600;

	// 粒子数组
	this.points=[];

	// 下面两个量用来控制五个角依次闪亮
	this.currLightPos=0;
	this.lightIdx=0;

	// 初始化
	this.init=function(){
		// 放射性原始数组
		var arr=[];
		for(let i=0;i<360;i++){
			let theta=i*Math.PI*2/360;
			var pt={};
			pt.x=54*Math.cos(theta);
			pt.y=54*Math.sin(theta);
			pt.theta=theta;
			arr.push(pt);
		}


		for(let i=0;i<this.starCnt;i++){
			// 随机取原始数组的一个
			let idx=Math.floor(Math.random()*arr.length);
			let pt=arr[idx];

			// 创建点
			var point={};
			point.x=arr[idx].x;
			point.y=arr[idx].y;
			point.step=Math.random()*10+1;
			point.theta=arr[idx].theta;
			point.xInitial=arr[idx].x;
			point.yInitial=arr[idx].y;

			// 放入粒子数组
			this.points.push(point);
		}
	}

	// 更新
	this.update=function(){
		const DIS=WIDTH/2*WIDTH/2+HEIGHT/2*HEIGHT/2;

		for(i=0;i<this.starCnt;i++){
			var pt=this.points[i];

			pt.x+=pt.step*Math.cos(pt.theta);
			pt.y+=pt.step*Math.sin(pt.theta);

			var distance=pt.x*pt.x+pt.y*pt.y;
			
			// 越过对角线长度一半即回到初始位置
			if(distance>DIS)
			{	pt.x=pt.xInitial;
				pt.y=pt.yInitial;
			}
		}

		// 累计五百变一次
		this.lightIdx++;
		this.currLightPos=Math.floor(this.lightIdx/100)
		if(this.lightIdx>500){
			this.lightIdx=0;
		}
	}

	// 画背景
	this.paintBg=function(ctx){
		// 清屏
		ctx.clearRect(-WIDTH/2,-HEIGHT/2,WIDTH,HEIGHT);	

		ctx.fillStyle = "rgba(0, 64, 128, 0.8)";// 加上半透明蒙层,字和光源便出现了残影效果
		ctx.fillRect(-WIDTH/2,-HEIGHT/2,WIDTH,HEIGHT);		
	}

	// 画前景
	this.paintFg=function(ctx){	
		
		// 用直线模拟放射状光芒
		for(let i=0;i<this.starCnt;i++){
			var pt=this.points[i];
			
			ctx.beginPath();
			ctx.moveTo(pt.x,pt.y);
			ctx.lineTo(pt.x-20*Math.cos(pt.theta),pt.y-20*Math.sin(pt.theta));
			ctx.closePath();
			ctx.lineWidth=2;
			ctx.strokeStyle="white";
			ctx.stroke();
		}

		// 渐变色圈(可不加)
        var rgnt=ctx.createRadialGradient(0,0,30,0,0,80);         
        rgnt.addColorStop(0,"rgb(255,255,255)");
        rgnt.addColorStop(1,"rgba(0,64,128,0.001)");
        ctx.fillStyle=rgnt;
        ctx.beginPath();
        ctx.arc(0,0,80,0,2*Math.PI,true);
        ctx.closePath();
        ctx.fill();

		// 画白底五角星
		draw5Star(ctx,0,0,90,"white");

		// 画立体五角星
		const R=80;// 五角星外角半径
		const r=30;// 五角星内角半径
		ctx.save();
		ctx.rotate(Math.PI/10);
		for(let i=0;i<5;i++){
			var alpha=i*2*Math.PI/5-Math.PI/5;
			var beta=i*2*Math.PI/5;			

			// 画红色五片
			var x1=R*Math.cos(alpha);
			var y1=R*Math.sin(alpha);
			var x2=r*Math.cos(beta);
			var y2=r*Math.sin(beta);
			ctx.beginPath();
			ctx.moveTo(0,0);
			ctx.lineTo(x1,y1);
			ctx.lineTo(x2,y2);
			ctx.closePath();
			if(this.currLightPos==i){
				ctx.fillStyle="red";
			}else{
				ctx.fillStyle="rgb(206,0,0)";
			}
			
			ctx.fill();

			// 画黄色五片
			var gama=(i)*2*Math.PI/5+Math.PI/5;
			var x3=R*Math.cos(gama);
			var y3=R*Math.sin(gama);

			ctx.beginPath();
			ctx.moveTo(0,0);			
			ctx.lineTo(x3,y3);
			ctx.lineTo(x2,y2);
			ctx.closePath();
			if(this.currLightPos==i){
				ctx.fillStyle="rgb(249,249,0)";
			}else{
				ctx.fillStyle="rgb(255,211,6)";
			}
			ctx.fill();
		}
		ctx.restore();

		// 下方文字说明
		ctx.save();
		ctx.shadowColor = 'black';
		ctx.shadowOffsetX = 5;
		ctx.shadowOffsetY = -2;
		ctx.shadowBlur = 5;
		ctx.textAlign="center";
		ctx.textBaseLine="Middle";
		ctx.font="40px Microsoft YaHei UI";
		ctx.fillStyle="white";    
		ctx.fillText('模拟八一电影制片厂电影片头',0,200);


		ctx.font="10px Microsoft YaHei UI";
		ctx.fillStyle="white";    
		ctx.fillText('逆火原创',450,260);

		ctx.restore();
	}
}

// 画实心五角星的函数
function draw5Star(ctx,x,y,r,color){
	ctx.save()
	ctx.translate(x-r,y-r);	
	ctx.beginPath();
	ctx.moveTo(r, 0);
	ctx.lineTo(r+Math.cos(Math.PI*3/10)*r, r+Math.sin(Math.PI*3/10)*r);
	ctx.lineTo(r-Math.cos(Math.PI*1/10)*r, r-Math.sin(Math.PI*1/10)*r);
	ctx.lineTo(r+Math.cos(Math.PI*1/10)*r, r-Math.sin(Math.PI*1/10)*r);
	ctx.lineTo(r-Math.cos(Math.PI*3/10)*r, r+Math.sin(Math.PI*3/10)*r);
	ctx.lineTo(r, 0);
	ctx.closePath();
	ctx.fillStyle=color;
	ctx.fill();
	ctx.restore();
}

/*--------------------------------------------------------------------------
十人烧香九为财,不知财从何处来?
为人有德天长佑,行善无求福自来。
--------------------------------------------------------------------------*/
//-->
</script>
  • 收藏
  • 评论
  • 分享
  • 举报

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK