心形函数-封心

这篇博客介绍了在制作心形函数动画过程中的一些创意实践。作者在调试过程中发现了两种有趣的效果:一是将粒子生成范围扩大至全局,模拟出星星闪烁的效果;二是通过特定设置,创造出粒子从画布右下角喷射的视觉效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个是《html5实验室-Canvas世界》中的一个例子,最大的收获当然是心形函数(x ^ 2 + y ^ 2 - 1) - x ^ 2 * y ^ 3 = 0。

有了前面几个动画做铺垫,这个还是比较容易就完成了,没有遇到什么奇特的问题。不过也因为比较轻松,代码的组织不是很认真,也不想去改了。

值得一提的是这个动画很容易另行发挥,我在调试的过程之中也看到了几个很有意思的版本。有一个版本将粒子生成点扩大到全局,这样配合inHeart函数一闪即逝,会有小星星的效果。另一个版本因为几个巧合把粒子生成点放到了画布右下角,而且方向都在第二象限,造成了从右下角喷射粒子的效果。


<!DOCTYPE html>
<html>
<head>
	<title>♥</title>
	<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
	<script type = "text/javascript">
		var limit = 300;
		var unit = 200;//心形线单位一
		var width = 800,
			height = 600;
		var ctx = null;
		var balls = [];
		var side = [];
		function inHeart(b){
			//(x ^ 2 +y^ 2 - 1) - x ^ 2 * y ^ 3 == 0,心形函数
			var x = b.x / unit;
			var y = -b.y / unit;//因为坐标y轴是向下的
			var part = x * x + y * y - 1;
			return (part * part * part < x * x * y * y * y);
		}

		function randomColor(){
			var x = Math.floor(Math.random() * 155) + 100;
			var y = Math.floor(Math.random() * 155) + 100; 
			var z = Math.floor(Math.random() * 155) + 100;
			return "rgb(" + x + "," + y + "," + z + ")";
		}

		function createBall(){
			return {
				x : (Math.random() - Math.random()) * width * 0.1,
				y : (Math.random() - Math.random()) * height * 0.2 - height * 0.1,
				vx : (Math.random() - Math.random()) * 7,
				vy : (Math.random() - Math.random()) * 7,
				r : Math.random() * 5,
				color : randomColor()
			}
		}

		function init(){
			var cvs = document.createElement("canvas");
			cvs.width = width;
			cvs.height = height;
			ctx = cvs.getContext("2d");

			ctx.translate(width / 2, height / 2);

			document.body.appendChild(cvs);

			for(i = 0; i < limit; i++){
				balls.push(createBall());
			}
			for(i = 0; i < limit / 5; i++){
				side.push(undefined);
			}
		}

		function drawBall(ctx, ball){
			ctx.fillStyle = ball.color;
			ctx.beginPath();
			ctx.arc(ball.x, ball.y, ball.r, 0, Math.PI * 2, false);
			ctx.closePath();
			ctx.fill();
		}

		function start(){
			document.body.removeChild(document.getElementById("start"));

			setInterval(function(){
				ctx.fillStyle = "rgba(0, 0, 0, 0.3)";
				ctx.fillRect(-width / 2, -height / 2, width, height);
				for(i in balls){
					var b = balls[i];
					drawBall(ctx, b);
					b.x += b.vx;
					b.y += b.vy;
					if(!inHeart(b)){
						side[Math.floor(Math.random() * side.length)] = balls[i];
						balls[i] = createBall();
					}
				}

				for(var i in side){
					var b = side[i];
					if(b != undefined){
						drawBall(ctx, b);
					}
				}
			}, 33);
		}
	</script>
</head>
<body onload = "init();">
	<button id = "start" onclick = "start();">click me!</button>
	<br />
</body>
</html>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值