canvas实现鼠标点线跟随交互效果代码
代码语言:html
所属分类:其他
代码描述:canvas实现鼠标点线跟随交互效果代码
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> /* global */ *, *::before, *::after { margin: 0; padding: 0; border: 0; box-sizing: border-box; } *:focus { outline: none; } body { display: flex; align-items: center; justify-content: center; height: 100vh; background: radial-gradient(#333333, #000000); overflow: hidden; } canvas { touch-action: none; } </style> </head> <body translate="no"> <script > //--- 'use strict'; //--- console.clear(); //--- let w = 0; let h = 0; let animationFrame = null; let isTouchDevice = false; const canvas = document.createElement('canvas'); const context = canvas.getContext('2d'); let imageData = null; let data = null; const center = { x: w / 2, y: h / 2 }; const border = { left: 1, top: 1, right: w, bottom: h }; let pointerPos = { x: center.x, y: center.y }; let pointerDown = false; let pointerMoveTimeout; const pointerMoveTimeoutTime = 2500; //--- const dotColorR = 25; const dotColorG = 155; const dotColorB = 200; const dotColorA = 255; const dotsRadius = 4; const dotsDistance = 10; const dotsDiameter = dotsRadius * 2; const dotsSpeed = 10; const dotsWobbleFactor = 0.95; const dotsWobbleSpeed = 0.05; const dotsMaxEscapeRouteLengthBasis = 100; let dotsMaxEscapeRouteLength = 100; const dotsMouseDistanceSensitivitySpeed = 5; const dotsMouseDistanceSensitivityMax = 250; const dotsMouseDistanceSensitivityMinBasis = 100; let dotsMouseDistanceSensitivityMin = 100; let dotsMouseDistanceSensitivity = dotsMouseDistanceSensitivityMin; let dotsHolder = []; let dotsCount = 0; let introPath = []; let introInterval = null; let introIndex = 0; let introPathCoordinatesCount = 256; let introSpeedBasis = 10; let introSpeed = introSpeedBasis; //--- function init() { isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0; //--- if (isTouchDevice === true) { canvas.addEventListener('touchmove', cursorMoveHandler, false); canvas.addEventListener('touchend', cursorLeaveHandler, false); canvas.addEventListener('touchcancel ', cursorLeaveHandler, false); } else { canvas.addEventListener('pointermove', cursorMoveHandler, false); canvas.addEventListener('pointerdown', cursorDownHandler, false); canvas.addEventListener('pointerup', cursorUpHandler, false); canvas.addEventListener('pointerleave', cursorLeaveHandler, false); } //--- document.body.appendChild(canvas); window.addEventListener('resize', onResize, false); restart(); } function onResize(event) { restart(); } function restart() { const innerWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; const innerHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; //--- w = innerWidth; h = innerHeight; //--- canvas.width = w; canvas.height = h; imageData = context.getImageData(0, 0, w, h); data = imageData.data; //--- center.x = w / 2; center.y = h / 2; pointerPos.x = -10000; pointerPos.y = -10000; border.right = w; border.bottom = h; //--- removeDots(); addDots(); //--- if (animationFrame != null) { cancelAnimFrame(animationFrame); } render(); //--- initIntroPath(introPathCoordinatesCount); stopIntro(); playIntro(); } //--- function addDots() { const dotsPerRow = Math.floor(w / (dotsDiameter + dotsDistance)) + dotsDiameter * 2; const dotsPerColumn = Math.floor(h / (dotsDiameter + dotsDistance)) + dotsDiameter * 2; const dotsCount = dotsPerRow * dotsPerColumn; const xs = -dotsDiameter; const ys = -dotsDiameter; let dotIndex = 0; for (let i = 0; i < dotsPerColumn; i++) { for (let j = 0; j < dotsPerRow; j++) { const x = xs + j * (dotsDistance + dotsDiameter); const y = ys + i * (dotsDistance + dotsDiameter); const dot = addDot(x, y, dotsRadius, dotsDiameter, dotColorR, dotColorG, dotColorB, dotColorA); dot.neighborRightIndex = j < dotsPerRow - 1 ? dotIndex + 1 : -1; dot.neighborBottomIndex = i < dotsPerColumn - 1 ? dotIndex + dotsPerRow : -1; dotsHolder.push(dot); dotIndex++; } } for (let i = 0, l = dotsHolder.length; i < l; i++) { const dot = dotsHolder[i]; if (dot.neighborRightIndex > -1) { dot.neighborRight = dotsHolder[dot.neighborRightIndex]; } if (dot.neighborBottomIndex > -1) { dot.neighborBottom = dotsHolder[dot.neighborBottomIndex]; } } } function addDot(x, y, radius, diameter, r, g, b, a) { const dot = {}; dot.cx = x; dot.cy = y; dot.x = x; dot.y = y; dot.sx = 0; dot.sy = 0; dot.radius = radius; dot.r = radius; dot.minRadius = radius * 0.75; dot.maxRadius = radius * 2.5; dot.diameter = diameter; dot.color = {}; dot.color.r = r; dot.color.g = g; dot.color.b = b; dot.color.a = a; dot.colorDark = {}; dot.colorDark.r = Math.floor(r * 0.75); dot.colorDark.g = Math.floor(g * 0.75); dot.colorDark.b = Math.floor(b * 0.75); dot.colorDark.a = Math.floor(a * 0.5); dot.colorDraw = {}; dot.colorDraw.r = r; dot.colorDraw.g = g; dot.colorDraw.b = b; dot.colorDraw.a = a; dot.activeTime = 0; dot.distance = 0; dot.neighborRightIndex = 0; dot.neighborBottomIndex = 0; dot.neighborRight = null; dot.neighborBottom = null; return dot; } function removeDots() { if (dotsHolder.length > 0) { dotsHolder = []; } } //--- function initIntroPath(numPoints) { introPath = []; const radiusX = w / 4; const radiusY = h / 3; const centerX = w / 2; const centerY = h / 2; for (let i = 0; i < numPoints; i++) { const angle = i / numPoints * 2 * Math.PI; const x = centerX + radiusX * Math.cos(angle); const y = centerY + radiusY * Math.sin(2 * angle) / 2; introPath.push({ x, y }); } } function playIntro() { introInterval = setInterval(() => { const pos = introPath[introIndex]; pointerPos = pos; introIndex++; if (introIndex >= introPath.length - 1) { introIndex = 0; } }, introSpeed); } function stopIntro() { clearTimeout(pointerMoveTimeout); if (introInterval !== null) { clearInterval(introInterval); introInterval = null; } } //--- function cursorDownHandler(event) { pointerDown = true; } function cursorUpHandler(event) { pointerDown = false; } function cursorLeaveHandler(event) { pointerPos = { x: -10000, y:.........完整代码请登录后点击上方下载按钮下载查看
网友评论0