网站地图    收藏    合作   

主页 > 采坑 > 前端采坑 > canvas采坑 >

canvas绘制抛物线之购物车效果

来源:未知    时间:2021-05-05 21:34 作者:小飞侠 阅读:

[导读] canvas绘制抛物线之购物车效果,今天来一个比较简单的,今天暂时用不到抛物线公式,还是利用三角公式,下面先看效果图: 思路引导: 已知道A,B坐标可以求出 a,b 的值,此时要求A-...

canvas绘制抛物线之购物车效果,今天来一个比较简单的,今天暂时用不到抛物线公式,还是利用三角公式,下面先看效果图:

image.png

效果预览:https://www.zixuephp.com/static/res/canvas/test/canvas-gwc.html


思路引导:

已知道A,B坐标可以求出 a,b 的值,此时要求A->B的角度(为了让抛物线角度递减,形成抛物线感觉),根据三角公式 tan(t) = b/a ,则得出最小角度为 s.

image.png

设置初始角度 firstAngle = 60, 则整个抛物线区间角度是 (firstAngle - s) / 动画执行次数(这里可以用定时或者帧事件自己掌控)

image.png

这时候就求每次运行单位P点的X,Y就可以形成抛物线动画了。

假设动画总执行次数为10次(cont), 那么每次动画的a1的x坐标则为 a / cont, 次数单位角度则是 s1 =  firstAngle - (firstAngle -s) /cont, 现在已经知道单位点 P的对边 a1 和 s1角度 求 b1, 根据三角函数 b1 = tan(s1) * a1 则得出b1(也就是P点的Y坐标)

然后根据定时间把整段运行联动起来就形成抛物线效果啦~~ 就这么简单。


代码如下:

<!DOCTYPE html>
<html>
<head>
	<title>太阳系</title>
	<style type="text/css" media="screen">
		body{
			margin: 0px; padding: 0px;
		}
	</style>
</head>
<body>
	<div id="canvas-warp">
    <canvas id="canvas" style="border: 1px solid #aaaaaa; display: block; margin: 0px auto;  width: 800; height: 500px;">
        你的浏览器居然不支持Canvas?!赶快换一个吧!!
    </canvas>
	</div>
	<script type="text/javascript">

		window.requestAnmFrame = (function(){
			return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequstAnimationFrame || window.oRequetAnimationFrame || window.msRequestAnimationFrame || function(callback){
				window.setTimeout(callback, 100/60)
			};
		})();

		var obj = {
			canvasEr:null,
			canvasContent: null,
			data: {
				a1x:100,
				a1y:400,
				b1x:600,
				b1y:200,
				num:1,
				firstAngle: 80, // 初始角度
				endAngle: 0,
				pxAngle:0,
				dy:0,
				dx:0,
				cont:50,
				pathList: []
			},
			init:function(){
				var canvas = document.getElementById("canvas");
				canvas.width = 800;
				canvas.height = 500;
				obj.canvasEr = canvas;
				obj.canvasContent = canvas.getContext('2d');

				var dy = Math.abs(obj.data.b1y - obj.data.a1y);
				var dx = Math.abs(obj.data.b1x - obj.data.a1x);
				this.data.dy = dy;
				this.data.dx = dx;
				obj.data.endAngle = Math.atan( dy / dx ) / (Math.PI / 180) // Math.atan (Math.PI / 180)
				obj.data.pxAngle = (obj.data.firstAngle - obj.data.endAngle) / this.data.cont;
				// console.log(dy, dx, obj.data.endAngle, obj.data.pxAngle)
				this.autoDraw()
				this.drawA()

			},
			// 绘制笑脸
			drawA(){
				obj.clearReact(); // 清除画布
				var x = obj.data.x, y = 200, r = 50;				
				var _ob = obj.drawArc({
					x:obj.data.a1x,
					y:obj.data.a1y,
					r:20,
					lcorlor:'yellow',
					bgcolor: 'red',
					isFull: true
				}).
				drawArc({
					x:obj.data.b1x,
					y:obj.data.b1y,
					r:20,
					lcorlor:'yellow',
					bgcolor: 'red',
					isFull: true
				})

			},
			drawB() {
				this.clearReact();
				this.drawA();
				var _ax1 = this.data.dx / this.data.cont * obj.data.num;
				var _ay1 = Math.tan(obj.data.firstAngle * (Math.PI / 180)) * _ax1; 

				this.data.pathList.push({
					x:obj.data.a1x + _ax1,
					y:obj.data.a1y - _ay1
				});

				obj.drawArc({
					x:obj.data.a1x + _ax1,
					y:obj.data.a1y - _ay1,
					r:20,
					lcorlor:'red',
					bgcolor: 'yellow',
					isFull: true
				}).drawArc({
					x:obj.data.a1x + _ax1,
					y:obj.data.a1y - _ay1,
					r:1,
					lcorlor:'red',
					bgcolor: 'red',
					isFull: true
				});

				// 绘制路径
				this.data.pathList.forEach(item => {
					obj.drawArc({
						x:item.x,
						y:item.y,
						r:1,
						lcorlor:'yellow',
						bgcolor: 'blue',
						isFull: true
					})
				});

				obj.data.firstAngle -= obj.data.pxAngle
			},
			clearReact: function(){
				obj.canvasContent.clearRect(0, 0, 800, 500);
			},
			moveTo:function(x,y){
				obj.canvasContent.moveTo(x, y);
			},
			/**
			 * @author lucky
			 * @DateTime 2021-05-02T22:56:11+0800
			 * @param    {[type]}                 pms [x,y,r,lw,lcorlor,bgcolor,isFull ,isStroke ,firstAngle, endAngle, anticlockwise]
			 * @return   {[type]}                     [obj]
			 */
			drawArc:function(pms){
				if (!pms || typeof pms !== 'object') {
					return
				}
				var _firstAngle = typeof pms.firstAngle === 'number' ? pms.firstAngle : 0,
				_endAngle = typeof pms.endAngle === 'number' ? pms.endAngle : Math.PI * 2,
				_isFull = typeof pms.isFull === 'boolean'? pms.isFull : true,
				_isStroke = typeof pms.isStroke === 'boolean' ? pms.isStroke : true,
				_anticlockwise = typeof pms.anticlockwise === 'boolean' ? pms.anticlockwise : false;
				this.moveTo(pms.x,pms.y);
				obj.canvasContent.beginPath();
				obj.canvasContent.arc(pms.x, pms.y, pms.r, _firstAngle, _endAngle, _anticlockwise);
				// 设置属性
				obj.canvasContent.lineWidth = pms.lw;
				obj.canvasContent.fillStyle = pms.bgcolor;
				_isFull && obj.canvasContent.fill();
				// 绘制路径
				obj.canvasContent.strokeStyle = pms.lcorlor;
				_isStroke && obj.canvasContent.stroke();
				obj.canvasContent.closePath();
				return obj;
			},
			autoDraw: function(){
				// console.log('执行自动绘制',obj.data.num)
				if (obj.data.num > obj.data.cont){
					return
				}
				obj.drawB()
				obj.data.num ++
				// 动画
				requestAnmFrame(obj.autoDraw)
				
			}

		}

		window.onload = function(){
			obj.init()
		}


	</script>
</body>
</html>

 

自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习

京ICP备14009008号-1@版权所有www.zixuephp.com

网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com

添加评论