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
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值