码迷,mamicode.com
首页 > 其他好文 > 详细

canvas绘制“海上升明月”

时间:2015-03-04 09:54:42      阅读:184      评论:0      收藏:0      [点我收藏+]

标签:canvas   html5   

技术分享

核心内容

1.海浪绘制

海浪的形状有点像正弦函数,可以用canvas提供的三次贝赛尔曲线函数bezierCurveTo(x1,y1,x2,y2,x3,y3)

http://www.w3school.com.cn/tags/canvas_beziercurveto.asp

无论是arcTo还是二次贝赛尔曲线quadraticCurveTo,所谓的控制点就是切线的交点。海浪的动态效果通过改变控制点的纵坐标实现的。

2.升月绘制

升月包括两个部分:弯月和升起动画。
升起动画比较简单,改变弯月坐标,横坐标:radius * Math.cos(deg),纵坐标:radius * Math.sin(deg)。
弯月在于先用arc函数画外弧,再用arcTo画内弧,画内弧的时候需要选取弧外任意一点做控制点,然后通过相似三角形算出内弧半径即可。同时填充颜色。

源代码
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>海上生明月</title>
	<style>
	html,body{
		margin: 0;
		padding: 0;
		width: 100%;
		height: 100%;
		overflow: hidden;
	}
	</style>
</head>
<body>
	<canvas id="canvas"></canvas>
	<script>
		var WINDOW_WIDTH;
		var WINDOW_HEIGHT;
		window.onload = function(){
			WINDOW_WIDTH = document.documentElement.clientWidth;
			WINDOW_HEIGHT = document.documentElement.clientHeight;
			var cvs = document.getElementById("canvas");
			cvs.width = WINDOW_WIDTH;
			cvs.height = WINDOW_HEIGHT;
			var ctx = cvs.getContext("2d");
			var offset = 0;
			var delta = 10;
			var deg = 0;
			var r = 1/5*WINDOW_WIDTH;
			setInterval(function(){
				offset += delta;
				if(Math.abs(offset)>150) {
					delta = -delta;
					offset += delta;
				}
				ctx.clearRect(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
				//画个月亮消灭你
				if(Math.abs(deg)<90)deg--;
				var x = 1/2*WINDOW_WIDTH + Math.cos(deg/180*Math.PI)*r;
				var y = 1/4*WINDOW_HEIGHT + Math.sin(deg/180*Math.PI)*r;
				drawMoon(ctx, x, y, 45/360*Math.PI, 1, 180);
				//浪里个浪
				drawWave(ctx, offset);
			}, 50);
		};
		/**
		 * 绘制海浪
		 * @param  {context} ctx     绘图上下文
		 * @param  {Number} offsetY 波峰偏移值
		 * @return {[type]}         [description]
		 */
		function drawWave(ctx, offsetY){
			ctx.beginPath();
			var x = 0;
			var y = WINDOW_HEIGHT/2;
			var offsetX = 50;
			ctx.moveTo(x, y);
			for (var i = 0; i < 10; i++) {
				var delta = i * 4.5;
				ctx.bezierCurveTo(x+(1.5+delta)*offsetX, y+offsetY, x+(3+delta)*offsetX, y-offsetY, x+(4.5+delta)*offsetX, y);
			}
			ctx.lineTo(WINDOW_WIDTH, WINDOW_HEIGHT);
			ctx.lineTo(0, WINDOW_HEIGHT);
			ctx.closePath();
			ctx.fillStyle = "darkblue";
			ctx.fill();
			ctx.stroke();
		}
		/**
		 * 绘制新月
		 * @param  {context} ctx 绘图上下文
		 * @param  {Number} xc  切线交点横坐标
		 * @return {[type]}     [description]
		 */
		function createMoon(ctx, xc){
			//上圆弧切点
			var xa = 100;
			var ya = 100;
			//下圆弧切点
			var xb = 100;
			var yb = 200;
			//半圆半径
			var r = 50;
			//切线交点
			var yc = 150;
			ctx.beginPath();
			ctx.fillStyle="yellow";
			ctx.strokeStyle="yellow";
			//绘制半圆,一定要注意绘制路径
			ctx.arc((xa+xb)/2, (ya+yb)/2, r, 1/2*Math.PI, 3/2*Math.PI, true);
			var radius = r/(xc-xa)*Math.sqrt(Math.pow(r,2)+Math.pow(xc-xa,2));
			ctx.moveTo(xa, ya);
			ctx.arcTo(xc, yc, xb, yb, radius);
			ctx.fill();
			ctx.stroke();
		}
		/**
		 * 绘制月亮
		 * @param  {context} ctx    上下文绘图环境
		 * @param  {Number} x      平移横坐标
		 * @param  {Number} y      平移纵坐标
		 * @param  {Number} rotate 旋转弧度
		 * @param  {Number} scale  缩放倍率
		 * @param  {Number} xc     切线交点横坐标
		 * @return {[type]}        [description]
		 */
		function drawMoon(ctx, x, y, rotate, scale, xc){
			ctx.save();
			ctx.translate(x||0, y||0);
			ctx.rotate(rotate||0);
			ctx.scale(scale||1, scale||1);
			createMoon(ctx, xc);
			ctx.restore();
		}
	</script>
</body>
</html>


canvas绘制“海上升明月”

标签:canvas   html5   

原文地址:http://blog.csdn.net/yalishizhude/article/details/44048221

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!