三种canvas星空背景效果

8 篇文章 0 订阅
6 篇文章 0 订阅

第一种:旋转的光点,不限浏览器分辨率

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<canvas id="canvas" class="canvas"></canvas>
		<link type="text/css" rel="stylesheet" href="css/xk1.css"/>
		<script src="js/xk1.js"></script>

	</body>
</html>

css

body {
	margin: 0 auto;
	overflow: hidden;
}

.canvas {
	position: absolute;
	top: 0%;
	left: 0%;
	width: 100%;
	height: 100%;
	z-index: -6;
	filter: alpha(opacity=20);
}

js

drawStars();
//画星空背景
function drawStars() {
	var canvas = document.getElementById('canvas'),
		ctx = canvas.getContext('2d'),
		w = canvas.width = window.innerWidth,
		h = canvas.height = window.innerHeight,

		hue = 217, //色调色彩
		stars = [], //保存所有星星
		count = 0, //用于计算星星
		maxStars = 1300; //星星数量

	//canvas2是用来创建星星的源图像,即母版,
	//根据星星自身属性的大小来设置
	var canvas2 = document.createElement('canvas'),
		ctx2 = canvas2.getContext('2d');
	canvas2.width = 100;
	canvas2.height = 100;
	//创建径向渐变,从坐标(half,half)半径为0的圆开始,
	//到坐标为(half,half)半径为half的圆结束
	var half = canvas2.width / 2,
		gradient2 = ctx2.createRadialGradient(half, half, 0, half, half, half);
	gradient2.addColorStop(0.025, '#CCC');
	//hsl是另一种颜色的表示方式,
	//h->hue,代表色调色彩,0为red,120为green,240为blue
	//s->saturation,代表饱和度,0%-100%
	//l->lightness,代表亮度,0%为black,100%位white
	gradient2.addColorStop(0.1, 'hsl(' + hue + ', 61%, 33%)');
	gradient2.addColorStop(0.25, 'hsl(' + hue + ', 64%, 6%)');
	gradient2.addColorStop(1, 'transparent');

	ctx2.fillStyle = gradient2;
	ctx2.beginPath();
	ctx2.arc(half, half, half, 0, Math.PI * 2);
	ctx2.fill();

	// End cache
	function random(min, max) {
		if (arguments.length < 2) {
			max = min;
			min = 0;
		}

		if (min > max) {
			var hold = max;
			max = min;
			min = hold;
		}

		//返回min和max之间的一个随机值
		return Math.floor(Math.random() * (max - min + 1)) + min;
	}

	function maxOrbit(x, y) {
		var max = Math.max(x, y),
			diameter = Math.round(Math.sqrt(max * max + max * max));
		//星星移动范围,值越大范围越小,
		return diameter / 2;
	}

	var Star = function() {
		//星星移动的半径
		this.orbitRadius = random(maxOrbit(w, h));
		//星星大小,半径越小,星星也越小,即外面的星星会比较大
		this.radius = random(60, this.orbitRadius) / 8;
		//所有星星都是以屏幕的中心为圆心
		this.orbitX = w / 2;
		this.orbitY = h / 2;
		//星星在旋转圆圈位置的角度,每次增加speed值的角度
		//利用正弦余弦算出真正的x、y位置
		this.timePassed = random(0, maxStars);
		//星星移动速度
		this.speed = random(this.orbitRadius) / 500000;
		//星星图像的透明度
		this.alpha = random(2, 10) / 10;

		count++;
		stars[count] = this;
	}

	Star.prototype.draw = function() {
		//星星围绕在以屏幕中心为圆心,半径为orbitRadius的圆旋转
		var x = Math.sin(this.timePassed) * this.orbitRadius + this.orbitX,
			y = Math.cos(this.timePassed) * this.orbitRadius + this.orbitY,
			twinkle = random(10);

		//星星每次移动会有1/10的几率变亮或者变暗
		if (twinkle === 1 && this.alpha > 0) {
			//透明度降低,变暗
			this.alpha -= 0.05;
		} else if (twinkle === 2 && this.alpha < 1) {
			//透明度升高,变亮
			this.alpha += 0.05;
		}

		ctx.globalAlpha = this.alpha;
		//使用canvas2作为源图像来创建星星,
		//位置在x - this.radius / 2, y - this.radius / 2
		//大小为 this.radius
		ctx.drawImage(canvas2, x - this.radius / 2, y - this.radius / 2, this.radius, this.radius);
		//没旋转一次,角度就会增加
		this.timePassed += this.speed;
	}

	//初始化所有星星
	for (var i = 0; i < maxStars; i++) {
		new Star();
	}

	function animation() {
		//以新图像覆盖已有图像的方式进行绘制背景颜色
		ctx.globalCompositeOperation = 'source-over';
		ctx.globalAlpha = 0.5; //尾巴
		ctx.fillStyle = 'hsla(' + hue + ', 64%, 6%, 2)';
		ctx.fillRect(0, 0, w, h)

		//源图像和目标图像同时显示,重叠部分叠加颜色效果
		ctx.globalCompositeOperation = 'lighter';
		for (var i = 1, l = stars.length; i < l; i++) {
			stars[i].draw();
		};

		//调用该方法执行动画,并且在重绘的时候调用指定的函数来更新动画
		//回调的次数通常是每秒60次
		window.requestAnimationFrame(animation);
	}

	animation();
}

效果
在这里插入图片描述


第二种:从上而下的光点,限浏览器分辨率

html

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
	</head>
	<body style="margin: 0">
		<canvas id="cvs" style="background-color: #000;"></canvas>
	</body>
</html>

css

<style>
	#cvs{
		position: absolute;
		top: 0%;
		left: 0%;
		z-index: -6;
	}
</style>

js

<script>
	const cvs = document.querySelector('#cvs')
	const ctx = cvs.getContext('2d')
	const {clientWidth:width, clientHeight:height} = document.documentElement
	cvs.width = width
	cvs.height = height
	ctx.fillStyle = '#ffffff' //小点的颜色
	//生成小点,400是小点的数量,map里面是小点的位置和运动速度
	const bgColors = Array.from(new Array(400)).map(v => {
		return {
			x: Math.random() * width,
			y: Math.random() * height,
			step: Math.random() * 0.1 + 0.5
		}
	})

	//渲染函数
	const render = () => {
		//清空一下
		ctx.clearRect(0, 0, width, height)
		ctx.beginPath()
		//让小点动起来的数据
		bgColors.forEach(v => {
			v.y = v.y > height ? 0 : (v.y + v.step)
			ctx.rect(v.x, v.y, 3, 3)
		})
		//把小点放到画布上
		ctx.fill()
		requestAnimationFrame(render)
	}
	render()
	
	//禁止用户缩放浏览器
	const keyCodeMap = {
	    // 91: true, // command
	    61: true,
	    107: true, // 数字键盘 +
	    109: true, // 数字键盘 -
	    173: true, // 火狐 - 号
	    187: true, // +
	    189: true, // -
	};
	// 覆盖ctrl||command + ‘+’/‘-’
	document.onkeydown = function (event) {
	    const e = event || window.event;
	    const ctrlKey = e.ctrlKey || e.metaKey;
	    if (ctrlKey && keyCodeMap[e.keyCode]) {
	        e.preventDefault();
	    } else if (e.detail) { // Firefox
	        event.returnValue = false;
	    }
	};
	// 覆盖鼠标滑动
	document.body.addEventListener('wheel', (e) => {
	    if (e.ctrlKey) {
	        if (e.deltaY < 0) {
	            e.preventDefault();
	            return false;
	        }
	        if (e.deltaY > 0) {
	            e.preventDefault();
	            return false;
	        }
	    }
	}, { passive: false });
</script>

效果
在这里插入图片描述
这个背景效果,它的宽高只能设置成固定的大小,画布可以重置,但是光点没有办法重置,所以为了视觉效果,宽高设置成了canvas.width = window.innerWidth , canvas.height = window.innerHeight,这是浏览器在加载页面时的可视窗口大小,我试了半天也没有让它变成不限浏览器大小的效果,所以我在js最后写了屏蔽浏览器的缩放功能代码,大家可以自己试一试看看能不能优化成不限可视大小的


第三种:随机闪烁的光点,不限浏览器分辨率

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<canvas id="starfield"></canvas>
		<link rel="stylesheet" type="text/css" href="css/xk2.css"/>
		<script type="text/javascript" src="js/xk2.js"></script>
	</body>
</html>

css

* {
	margin: 0px;
	padding: 0px;
}

canvas {
	position: absolute;
	/*设置定位*/
	top: 0;
	left: 0;
	z-index: -6;
	/*使画布基于最低层*/
	background: #0e1729;
	/*画布背景色*/
}

js

var canvas;
var stars_count;
var stars;
ini();
makeStars();
var interval = setInterval(function() {
	drawStars();
}, 50); //定时刷新星星数据

function ini() { //初始化
	canvas = document.getElementById("starfield");
	canvas.width = window.innerWidth;
	canvas.height = window.innerHeight;
	context = canvas.getContext("2d");
	stars = Array(); //数组存放随机生成的星星数据(x,y,大小,颜色,速度)
	stars_count = 800; //星星数量
	clearInterval(interval);
}

function makeStars() { //随机生成星星数据
	for (var i = 0; i < stars_count; i++) {
		let x = Math.random() * canvas.offsetWidth;
		let y = Math.random() * canvas.offsetHeight;
		let radius = Math.random() * 0.8;
		let color = "rgba(" + Math.random() * 255 + "," + Math.random() * 255 + "," + Math.random() * 255 + ",0.8)";
		let speed = Math.random() * 0.5;
		let arr = {
			'x': x,
			'y': y,
			'radius': radius,
			'color': color,
			'speed': speed
		}; //(x,y,大小,颜色,速度)
		stars.push(arr); //随机生成的星星数据存在这里
	}
}

function drawStars() { //把星星画到画布上
	context.fillStyle = "#0e1729";
	context.fillRect(0, 0, canvas.width, canvas.height);
	for (var i = 0; i < stars.length; i++) {
		var x = stars[i]['x'] - stars[i]['speed'];
		if (x < -2 * stars[i]['radius']) x = canvas.width;
		stars[i]['x'] = x;
		var y = stars[i]['y'];
		var radius = stars[i]['radius'];
		context.beginPath();
		context.arc(x, y, radius * 2, 0, 2 * Math.PI);
		context.fillStyle = "rgba(" + Math.random() * 255 + "," + Math.random() * 255 + "," + Math.random() * 255 +
			",0.8)";
		context.fill();
	}
}

window.onresize = function() { //窗口大小发生变化时重新随机生成星星数据
	ini();
	makeStars();
	interval = setInterval(function() {
		drawStars();
	}, 50);
}

效果
在这里插入图片描述


第一种背景代码里面把星星旋转的中心点写死为屏幕中心,第三种是添加了分辨率变化时触发的onresize事件以及定时刷新光点数据,所以第一种和第三种都是可以随着浏览器分辨率的变化而重置效果的,第二种大家可以自己试试能不能把代码修改一下让它变成不限分辨率的

  • 5
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值