canvas实现鼠标跟随粒子连线圈圈冒泡交互动画效果代码

代码语言:html

所属分类:动画

代码描述:canvas实现鼠标跟随粒子连线圈圈冒泡交互动画效果代码

代码标签: canvas 鼠标 跟随 粒子 连线 圈圈 冒泡 交互 动画

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  

  <meta name="viewport" content="width=device-width, initial-scale=1">
  
  
  
<style>
body,
html {
  margin: 0;
  padding: 0;
  overflow: hidden;
}
canvas {
  display: block;
}
</style>


  
</head>

<body translate="no">
  <canvas id="canvas"></canvas>
  
      <script  >

// Grab the canvas element from the DOM
const canvas = document.getElementById("canvas");
// Get a 2D drawing context from the canvas
const ctx = canvas.getContext("2d");

// Arrays to hold various particle types
// (General particles, fireworks, dusty background, and ripples)
const particles = [];
const fireworkParticles = [];
const dustParticles = [];
const ripples = [];
const techRipples = [];

// A simple mouse state object to track the user's cursor
const mouse = (() => {
  let state = { x: null, y: null };
  return {
    get x() {
      return state.x;
    },
    get y() {
      return state.y;
    },
    set({ x, y }) {
      // Update the mouse position whenever the user moves the cursor
      state = { x, y };
    },
    reset() {
      // Clear mouse position when it leaves the canvas
      state = { x: null, y: null };
    } };

})();

// Some global state variables for background shifting and frame counting
let backgroundHue = 0;
let frameCount = 0;
let autoDrift = true; // If true, particles gently drift on their own

// Dynamically adjust the number of particles based on canvas size
function adjustParticleCount() {
  const particleConfig = {
    heightConditions: [200, 300, 400, 500, 600],
    widthConditions: [450, 600, 900, 1200, 1600],
    particlesForHeight: [40, 60, 70, 90, 110],
    particlesForWidth: [40, 50, 70, 90, 110] };


  let numParticles = 130;

  // Check the height and pick a suitable particle count
  for (let i = 0; i < particleConfig.heightConditions.length; i++) {
    if (canvas.height < particleConfig.heightConditions[i]) {
      numParticles = particleConfig.particlesForHeight[i];
      break;
    }
  }

  // Check the width and try to lower the particle count if needed
  for (let i = 0; i < particleConfig.widthConditions.length; i++) {
    if (canvas.width < particleConfig.widthConditions[i]) {
      numParticles = Math.min(
      numParticles,
      particleConfig.particlesForWidth[i]);

      break;
    }
  }

  return numParticles;
}

// Particle class handles both "normal" and "firework" particles
// I ended up combining them to avoid duplicating similar code
class Particle {
  constructor(x, y, isFirework = false) {
    const baseSpeed = isFirework ?
    Math.random() * 2 + 1 // fireworks move faster
    : Math.random() * 0.5 + 0.3; // regular particles move slowly

    // Assign various properties to give each particle some randomness
    Object.assign(this, {
      isFirework,
      x,
      y,
      vx: Math.cos(Math.random() * Math.PI * 2) * baseSpeed,
      vy: Math.sin(Math.random() * Math.PI * 2) * baseSpeed,
      size: isFirework ? Math.random() * 2 + 2 : Math.random() * 3 + 1,
      hue: Math.random() * 360,
      alpha: 1,
      sizeDirection: Math.random() < 0.5 ? -1 : 1,
      trail: [] });

  }

  update(mouse) {
    // Calculate distance from mouse to apply interactive forces (if any)
    const dist =
    mouse.x !== null ? (mouse.x - this.x) ** 2 + (mouse.y - this.y) ** 2 : 0;

    if (!this.isFirework) {
      // Apply a force pushing particles away or toward the mouse if it's on screen
      const force = dist && dist < 22500 ? (22500 - dist) / 22500 : 0;

      // If mouse is not present and autoDrift is true, particles gently meander
      if (mouse.x === null && autoDrift) {
        this.vx += (Math.random() - 0.5) * 0.03;
        this.vy += (Math.random() - 0.5) * 0.03;
      }

      if (dist) {
        const sqrtDist = Math.sqrt(dist);
        // Slightly nudge particles toward the mouse position
        this.vx += (mouse.x - this.x) / sqrtDist * force * 0.1;
        this.vy += (mouse.y - this.y) / sqrtDist * force * 0.1;
      }

      // Dampen velocities a bit so they don't run off too wildly
      this.vx *= mouse.x !== null ? 0.99 : .........完整代码请登录后点击上方下载按钮下载查看

网友评论0