实现跟随鼠标移动洒落的星星特效,需要通过以下步骤实现:
- 在HTML文件中创建一个画布(canvas)元素
<canvas id="canvas"></canvas>
- 在JavaScript文件中获取画布元素,并配置画布属性
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
// 设置画布大小
canvas.width = window.innerWidth
canvas.height = window.innerHeight
// 设置画布背景颜色和星星颜色
ctx.fillStyle = 'black'
ctx.fillRect(0, 0, canvas.width, canvas.height)
ctx.fillStyle = 'white'
- 定义一个星星类(Star),用于描述星星的属性和行为
class Star {
constructor() {
this.x = Math.random() * canvas.width // 随机生成星星的初始横坐标
this.y = Math.random() * canvas.height // 随机生成星星的初始纵坐标
this.size = Math.random() * 3 // 随机生成星星的大小
this.speedX = Math.random() * 3 - 1.5 // 随机生成星星的横向移动速度
this.speedY = Math.random() * 3 - 1.5 // 随机生成星星的纵向移动速度
}
draw() {
// 绘制一个5角星
ctx.beginPath()
ctx.moveTo(this.x, this.y - this.size)
for (let i = 0; i < 5; i++) {
ctx.lineTo(Math.cos((18 + i * 72) / 180 * Math.PI) * this.size + this.x,
-Math.sin((18 + i * 72) / 180 * Math.PI) * this.size + this.y)
}
ctx.closePath()
ctx.fill()
}
update() {
// 更新星星的位置
this.x += this.speedX
this.y += this.speedY
// 当星星越界时,重新设置其位置和速度
if (this.x < 0 || this.x > canvas.width) {
this.x = Math.random() * canvas.width
this.speedX = Math.random() * 3 - 1.5
}
if (this.y < 0 || this.y > canvas.height) {
this.y = Math.random() * canvas.height
this.speedY = Math.random() * 3 - 1.5
}
}
followMouse() {
// 计算鼠标与星星的距离
const dx = this.x - mouse.x
const dy = this.y - mouse.y
const dist = Math.sqrt(dx * dx + dy * dy)
// 如果鼠标离星星较近,星星就会朝着鼠标靠近
if (dist < 150) {
this.speedX += dx * 0.00005
this.speedY += dy * 0.00005
}
}
}
- 创建星星实例(Star)数组,并在画布上绘制星星
// 创建星星实例数组
const stars = []
for (let i = 0; i < 300; i++) {
stars.push(new Star())
}
function animate() {
// 绘制画布背景颜色
ctx.fillStyle = 'black'
ctx.fillRect(0, 0, canvas.width, canvas.height)
// 绘制并更新星星
for (let i = 0; i < stars.length; i++) {
stars[i].draw()
stars[i].update()
stars[i].followMouse()
}
requestAnimationFrame(animate)
}
animate()
- 绑定鼠标移动事件,并实时更新鼠标位置
// 定义鼠标事件处理函数,并在画布上绑定该事件
const mouse = {
x: undefined,
y: undefined
}
canvas.addEventListener('mousemove', e => {
mouse.x = e.clientX
mouse.y = e.clientY
})
- 运行代码,查看效果
下面是跟随鼠标移动洒落的星星特效的完整代码示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>跟随鼠标移动洒落的星星特效</title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
// 设置画布大小
canvas.width = window.innerWidth
canvas.height = window.innerHeight
// 设置画布背景颜色和星星颜色
ctx.fillStyle = 'black'
ctx.fillRect(0, 0, canvas.width, canvas.height)
ctx.fillStyle = 'white'
// 定义星星类(Star)
class Star {
constructor() {
this.x = Math.random() * canvas.width // 随机生成星星的初始横坐标
this.y = Math.random() * canvas.height // 随机生成星星的初始纵坐标
this.size = Math.random() * 3 // 随机生成星星的大小
this.speedX = Math.random() * 3 - 1.5 // 随机生成星星的横向移动速度
this.speedY = Math.random() * 3 - 1.5 // 随机生成星星的纵向移动速度
}
draw() {
// 绘制一个5角星
ctx.beginPath()
ctx.moveTo(this.x, this.y - this.size)
for (let i = 0; i < 5; i++) {
ctx.lineTo(Math.cos((18 + i * 72) / 180 * Math.PI) * this.size + this.x,
-Math.sin((18 + i * 72) / 180 * Math.PI) * this.size + this.y)
}
ctx.closePath()
ctx.fill()
}
update() {
// 更新星星的位置
this.x += this.speedX
this.y += this.speedY
// 当星星越界时,重新设置其位置和速度
if (this.x < 0 || this.x > canvas.width) {
this.x = Math.random() * canvas.width
this.speedX = Math.random() * 3 - 1.5
}
if (this.y < 0 || this.y > canvas.height) {
this.y = Math.random() * canvas.height
this.speedY = Math.random() * 3 - 1.5
}
}
followMouse() {
// 计算鼠标与星星的距离
const dx = this.x - mouse.x
const dy = this.y - mouse.y
const dist = Math.sqrt(dx * dx + dy * dy)
// 如果鼠标离星星较近,星星就会朝着鼠标靠近
if (dist < 150) {
this.speedX += dx * 0.00005
this.speedY += dy * 0.00005
}
}
}
// 创建星星实例数组
const stars = []
for (let i = 0; i < 300; i++) {
stars.push(new Star())
}
// 定义鼠标事件处理函数,并在画布上绑定该事件
const mouse = {
x: undefined,
y: undefined
}
canvas.addEventListener('mousemove', e => {
mouse.x = e.clientX
mouse.y = e.clientY
})
function animate() {
// 绘制画布背景颜色
ctx.fillStyle = 'black'
ctx.fillRect(0, 0, canvas.width, canvas.height)
// 绘制并更新星星
for (let i = 0; i < stars.length; i++) {
stars[i].draw()
stars[i].update()
stars[i].followMouse()
}
requestAnimationFrame(animate)
}
animate()
</script>
</body>
</html>
例如,在变更星星颜色效果后,在这些DOM树与其他简单示例日志和代码块中,仍然会产生类似于凌乱和不可读的排版,请尝试如何更好地排版。
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
// 设置画布大小
canvas.width = window.innerWidth
canvas.height = window.innerHeight
// 设置画布背景颜色和星星颜色
ctx.fillStyle = 'black'
ctx.fillRect(0, 0, canvas.width, canvas.height)
ctx.fillStyle = 'white'
// 设置星星颜色
const colors = ['#1b9cfc', '#e84118', '#fbc531', '#4cd137', '#f6b93b']
const colorIndexRange = colors.length - 1
// 定义星星类(Star)
class Star {
constructor() {
this.x = Math.random() * canvas.width // 随机生成星星的初始横坐标
this.y = Math.random() * canvas.height // 随机生成星星的初始纵坐标
this.color = colors[Math.floor(Math.random() * colorIndexRange)] // 随机生成星星的颜色
this.size = Math.random() * 3 // 随机生成星星的大小
this.speedX = Math.random() * 3 - 1.5 // 随机生成星星的横向移动速度
this.speedY = Math.random() * 3 - 1.5 // 随机生成星星的纵向移动速度
}
draw() {
// 绘制一个五角星
ctx.beginPath()
ctx.moveTo(this.x, this.y - this.size)
for (let i = 0; i < 5; i++) {
ctx.lineTo(Math.cos((18 + i * 72) / 180 * Math.PI) * this.size + this.x,
-Math.sin((18 + i * 72) / 180 * Math.PI) * this.size + this.y)
}
ctx.closePath()
// 填充星星颜色
ctx.fillStyle = this.color
ctx.fill()
}
update() {
// 更新星星的位置
this.x += this.speedX
this.y += this.speedY
// 当星星越界时,重新设置其位置和速度
if (this.x < 0 || this.x > canvas.width) {
this.x = Math.random() * canvas.width
this.speedX = Math.random() * 3 - 1.5
}
if (this.y < 0 || this.y > canvas.height) {
this.y = Math.random() * canvas.height
this.speedY = Math.random() * 3 - 1.5
}
}
followMouse() {
// 计算鼠标与星星的距离
const dx = this.x - mouse.x
const dy = this.y - mouse.y
const dist = Math.sqrt(dx * dx + dy * dy)
// 如果鼠标离星星较近,星星就会朝着鼠标靠近
if (dist < 150) {
this.speedX += dx * 0.00005
this.speedY += dy * 0.00005
}
}
}
// 创建星星实例数组
const stars = []
for (let i = 0; i < 300; i++) {
stars.push(new Star())
}
// 定义鼠标事件处理函数,并在画布上绑定该事件
const mouse = {
x: undefined,
y: undefined
}
canvas.addEventListener('mousemove', e => {
mouse.x = e.clientX
mouse.y = e.clientY
})
function animate() {
// 绘制画布背景颜色
ctx.fillStyle = 'black'
ctx.fillRect(0, 0, canvas.width, canvas.height)
// 绘制并更新星星
for (let i = 0; i < stars.length; i++) {
stars[i].draw()
stars[i].update()
stars[i].followMouse()
}
requestAnimationFrame(animate)
}
animate()
在上述代码中可以看到,在设置星星类时,加入了颜色的设置,并在fillStyle处加入了颜色的填充。还有在for-loop
中加入了颜色赋值语句。这些语句会影响canvas输出的排版展示。为了输出更美观的内容,可以适当缩进代码,增加代码块及代码注释,使大家更好地理解和阅读你的代码。
```html