canvas流星雨 数据流

canvas数据直线流动

最近做平台优化的时候,有两个涉及到了canvas的需求,初有成效,在此分享下。先看需求效果(如下图 ps:用手机视频做的动图请忽略粗糙的观感)大概的意思是背景图中的城市空中有很多的数据衔接,之前就是单纯的一张效果背景图,现在产品让优化下,添加些动态效果,于是乎就想到了用canvas
在这里插入图片描述
首先声明以下所需要的变量

const numberLine = 56;//光线数量
const tail = 400; //光线长度
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
// 创建img对象 引如背景图 
var img = new Image();
	img.src = "./img/zhiNengSouSuo_back.png";
//设置画布长宽
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

canvas绘制线条的时候是靠moveTo和lineTo属性,所以现在随机生成一组线条坐标

//n为传如的生成线条的个数
const createLine = n => {
	const line = [];
	for (let i = 0; i < n; ++i) {
		line.push({
			x: Math.random() * canvas.width,
			y: Math.random() * canvas.height,
			s: Math.random() * 2 + 1
		});
	}
	return line;
};

有了坐标点,然后开始绘制

const render = line => {
	var bg = ctx.createPattern(img, "no-repeat");//createPattern() 方法在指定的方向内重复指定的元素。
	ctx.fillStyle = bg;//fillStyle 属性设置或返回用于填充绘画的颜色、渐变或模式。
	ctx.fillRect(0, 0, canvas.width, canvas.height);//定义了矩形当前的填充方式。
	for (let l of line) {
		renderLine(l);
	}
};
const renderLine = l => {
	//设置线条渐变
	const grad = ctx.createLinearGradient(l.x, l.y, l.x, l.y + tail);
	//添加颜色时直接时候能够色值的时候效果很生硬,所以用hsla色值
	//简单介绍一下
	//H(色调:Hue):衍生于色盘,其中0和360是红色,接近120的是绿色,240是蓝色;
	//S(饱和度:Saturation):值为一个百分比数,0%代表灰度,100%代表最高饱和度;
	//L(亮度:Lightness):值也为一个百分比数,其中0%代表最暗,50%为均值,100%表示最亮。
	//A(透明度:Alpha):值为0~1之间的一个数,其中0代表不透明,1代表完全透明
	
	const a = 1 - (canvas.height - l.y) / canvas.height * 0.8;
	grad.addColorStop(0, `hsla(202,100%,100%,${a})`);
	grad.addColorStop(1, "hsla(202,100%,50%,0)");
	ctx.strokeStyle = grad;
	ctx.beginPath();
	ctx.lineWidth=2.5;
	ctx.moveTo(l.x, l.y);
	ctx.lineTo(l.x, l.y + tail);
	ctx.stroke();
};
render(createLine(numberLine));

此时,可以看到的效果如下
在这里插入图片描述
接下来就需要让这些线段动起来,window有一个requestAnimationFrame方法,可以执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。
那么我们把他加进来

const render = line => {
	var bg = ctx.createPattern(img, "no-repeat");//createPattern() 方法在指定的方向内重复指定的元素。
	ctx.fillStyle = bg;//fillStyle 属性设置或返回用于填充绘画的颜色、渐变或模式。
	ctx.fillRect(0, 0, canvas.width, canvas.height);
	for (let l of line) {
		renderLine(l);
	}
	requestAnimationFrame(() => render(line));
};

然而刷新之后,线条并没有按预想的动起来,是因为我们么有去更新线条的moveTo和lineTo,那就再把这个加进来

const updateLine = l => {
	//改变之前生成线条的坐标值
	l.y -= l.s;
	if (l.y < -tail) {
		l.y = canvas.height;
	}
};

将之放在render 中,每次renderLine之后就更新。如此数据线条就动起来了。完整代码可以到码云查看link

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供关于H5 Canvas流星特效的一些指导。 首先,您需要在HTML文件中创建一个canvas元素,以便在其中绘制流星效果。然后,您可以使用JavaScript来编写代码,实现流星效果。 以下是一个简单的流星特效的实现代码示例: ```javascript // 获取canvas元素 var canvas = document.getElementById('myCanvas'); // 设置canvas的宽度和高度 canvas.width = window.innerWidth; canvas.height = window.innerHeight; // 获取画布的上下文对象 var ctx = canvas.getContext('2d'); // 创建流星对象 function Meteor(x, y, dx, dy, size, color) { this.x = x; this.y = y; this.dx = dx; this.dy = dy; this.size = size; this.color = color; // 绘制流星 this.draw = function() { ctx.beginPath(); ctx.moveTo(this.x, this.y); ctx.lineTo(this.x + this.size, this.y - this.size); ctx.strokeStyle = this.color; ctx.stroke(); } // 更新流星的位置 this.update = function() { this.x += this.dx; this.y += this.dy; } } // 创建多个流星对象并加入数组 var meteors = []; for (var i = 0; i < 10; i++) { var x = Math.random() * canvas.width; var y = Math.random() * canvas.height; var dx = -1 - Math.random(); var dy = 1 + Math.random(); var size = 10 + Math.random() * 20; var color = 'white'; var meteor = new Meteor(x, y, dx, dy, size, color); meteors.push(meteor); } // 动画循环 function animate() { requestAnimationFrame(animate); ctx.clearRect(0, 0, canvas.width, canvas.height); // 绘制每一个流星 for (var i = 0; i < meteors.length; i++) { var meteor = meteors[i]; meteor.draw(); meteor.update(); } } // 开始动画循环 animate(); ``` 在这个代码示例中,我们创建了一个Meteor类来表示流星对象,并使用它来绘制和更新每一个流星。我们还创建了一个包含多个流星对象的数组,并在动画循环中使用它来绘制和更新每一个流星。 请注意,这只是一个简单的流星特效实现,您可以根据自己的需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值