使用JS实现一个跟随鼠标移动洒落的星星特效

yizhihongxing

实现跟随鼠标移动洒落的星星特效,需要通过以下步骤实现:

  1. 在HTML文件中创建一个画布(canvas)元素
<canvas id="canvas"></canvas>
  1. 在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'
  1. 定义一个星星类(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
    }
  }
}
  1. 创建星星实例(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()
  1. 绑定鼠标移动事件,并实时更新鼠标位置
// 定义鼠标事件处理函数,并在画布上绑定该事件
const mouse = {
  x: undefined,
  y: undefined
}

canvas.addEventListener('mousemove', e => {
  mouse.x = e.clientX
  mouse.y = e.clientY
})
  1. 运行代码,查看效果

下面是跟随鼠标移动洒落的星星特效的完整代码示例:

<!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





跟随鼠标移动洒落的星星特效




  • CSS样式分离之再分离达到精简与重用

    即使现代浏览器几乎可以处理任意大小的CSS,仍然有许多好处将CSS与HTML代码分离。首先,这使得HTML代码具有更高的可读性,使其更易于阅读和理解。其次,它允许您在需要的时候更轻松地重用CSS代码,并且可以使您的代码更易于维护。 以下是“CSS样式分离之再分离达到精简与重用”的完整攻略: 步骤1:将CSS从HTML中分离出来 将CSS分离出HTML代码的最…

    css 2023年6月10日
    00
  • 合作推广
    合作推广
    分享本页
    返回顶部