1.介绍
canvas 是 HTML5 引入的一个强大元素,用于在网页上绘制图形。它为开发者提供了一种在网页里绘制2D图形的机制,并且可以在其上进行动态图形渲染。canvas 元素本身是一个容器,必须通过 JavaScript 来绘制图像。
一个简单的 canvas 元素示例如下:
<canvas id="myCanvas" width="400" height="300"></canvas>
1.1 如何使用
获取 Canvas 画布
在 JavaScript 中,你需要获取 canvas 元素的 2D 渲染上下文,该上下文提供了绘制线条、矩形、文本等的方法:
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
1.2 常用功能
- 图片绘制: 可以通过 drawImage() 方法在 canvas 上显示图片。
- 动画: 通过不断更新 canvas 的内容,可以创建动画效果。
- 事件处理: 可以通过 JavaScript 绑定事件监听器,以实现与用户交互。
2.代码
我们直接给chatgpt提示词,让他给我们画,大概内容就是: 使用canvas绘制一个点点星光浮动的画面,星光是朝右上角动的,星星有的小有的比小的大一点,有淡黄色的,有淡紫色的,还有偶尔几个快速划过的流星,为透明背景,然后集成到我的vue项目的首页index.vue中
然后我们创建一个组件StarAnimation.vue
<template>
<canvas ref="starCanvas" class="star-canvas"></canvas>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
const starCanvas = ref(null);
const ctx = ref(null);
const stars = ref([]);
const numStars = 300; // 减少星星数量以增加稀疏感
const numMeteors = 3; // 减少流星数量
const meteorChance = 0.005; // 流星出现的概率
class Star {
constructor() {
this.x = Math.random() * window.innerWidth;
this.y = Math.random() * window.innerHeight;
this.size = Math.random() * 1 + 0.5; // 大小在0.5到1.5之间
this.speedX = (Math.random() - 0.5) * 0.3 + 0.1; // 随机水平速度,总体朝右
this.speedY = (Math.random() - 0.5) * 0.3 - 0.1; // 随机垂直速度,总体朝上
this.color = Math.random() < 0.5 ? '#ffffcc' : '#cc99ff'; // 淡黄色或淡紫色
}
update() {
this.x += this.speedX;
this.y += this.speedY;
if (this.x > window.innerWidth || this.x < 0 || this.y > window.innerHeight || this.y < 0) {
this.x = Math.random() * window.innerWidth;
this.y = Math.random() * window.innerHeight;
}
}
draw() {
ctx.value.beginPath();
ctx.value.arc(this.x, this.y, this.size, 0, Math.PI * 2);
ctx.value.fillStyle = this.color;
ctx.value.fill();
}
}
class Meteor {
constructor() {
this.x = Math.random() * window.innerWidth;
this.y = Math.random() * window.innerHeight;
this.size = Math.random() * 2 + 1;
this.speed = Math.random() * 5 + 4; // 加快流星速度
this.angle = Math.random() * Math.PI / 4; // 随机角度
this.color = '#ffffff';
}
update() {
this.x += this.speed * Math.cos(this.angle);
this.y -= this.speed * Math.sin(this.angle);
if (this.x > window.innerWidth || this.x < 0 || this.y > window.innerHeight || this.y < 0) {
this.x = Math.random() * window.innerWidth;
this.y = Math.random() * window.innerHeight;
}
}
draw() {
ctx.value.beginPath();
ctx.value.moveTo(this.x, this.y);
ctx.value.lineTo(this.x - 10 * Math.cos(this.angle), this.y + 10 * Math.sin(this.angle));
ctx.value.strokeStyle = this.color;
ctx.value.lineWidth = this.size;
ctx.value.stroke();
}
}
function init() {
for (let i = 0; i < numStars; i++) {
stars.value.push(new Star());
}
for (let i = 0; i < numMeteors; i++) {
stars.value.push(new Meteor());
}
}
function animate() {
ctx.value.clearRect(0, 0, window.innerWidth, window.innerHeight);
stars.value.forEach(star => {
star.update();
star.draw();
});
// 偶尔生成流星
if (Math.random() < meteorChance) {
stars.value.push(new Meteor());
}
requestAnimationFrame(animate);
}
onMounted(() => {
ctx.value = starCanvas.value.getContext('2d');
starCanvas.value.width = window.innerWidth;
starCanvas.value.height = window.innerHeight;
init();
animate();
window.addEventListener('resize', () => {
starCanvas.value.width = window.innerWidth;
starCanvas.value.height = window.innerHeight;
stars.value = [];
init();
});
});
onBeforeUnmount(() => {
window.removeEventListener('resize', () => {
starCanvas.value.width = window.innerWidth;
starCanvas.value.height = window.innerHeight;
stars.value = [];
init();
});
});
</script>
<style scoped>
.star-canvas {
position: fixed;
top: 0;
left: 0;
z-index: -1;
background-color: transparent;
}
</style>
可以自己调整星星的数量 大小和流行出现的频率
然后我们在要显示的页面加上我们的组件,然后略微修改下透明度就大功告成了
<template>
<div class="home">
<StarAnimation />
<!-- 其他内容 -->
</div>
</template>
<script setup>
import StarAnimation from './components/StarAnimation.vue';
</script>
<style scoped>
.home {
position: relative;
z-index: 1;
opacity: 0.6;
}
</style>