js实现canvas光源跟随鼠标交互照射方块盒子影子效果代码
代码语言:html
所属分类:动画
代码描述:js实现canvas光源跟随鼠标交互照射方块盒子影子效果代码
代码标签: canvas 光源 跟随 鼠标 交互 照射 方块 盒子 影子
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> #canvas1 { width: 100%; height: 100%; outline: 2px slateblue solid; margin: auto; cursor: none; } body { background: linear-gradient(129deg, #3f5efb 0%, #fc466b 100%); } /* ~~~~~ IGNORE... Mini CSS-Reset + Placement ~~~~~~ */ *, *::before, *::after { padding: 0; margin: 0 auto; box-sizing: border-box; font-family: inherit; } html, body { width: 100%; height: 100%; } body { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; } </style> </head> <body> <canvas id="canvas1"></canvas> <script > /** @type {HTMLCanvasElement} **/ const canv = document.getElementById("canvas1"); const ctx = canv.getContext("2d"); const BOX_CORNER_ANGLE = (2 * Math.PI) / 4; // == 90°*(π/180) == (2*π)/4 == 90deg in rad const NUM_BOXES = 20; // Nice if it can be 360 % ___ === 0 const SHADOW_COLOR = "#00000030"; // Some opacity for overlay effect const SHADOW_LENGTH = 2000; // Arbitrary Large # const BASE_HUE = Math.floor(Math.random() * 360); const HUE_ROTATION = Math.floor(360 / NUM_BOXES); // const canvasFillColor = window.getComputedStyle(canv).backgroundColor; let boxesArr = []; const light = { x: 0, y: 0 }; // is set to Canvas' center in init() const updateCanvasSize = () => { const canv = document.getElementById("canvas1"); const boundingRect = canv.getBoundingClientRect(); canv.width = boundingRect.width; canv.height = boundingRect.height; canvasStartX = boundingRect.x; canvasStartY = boundingRect.y; }; const generateHslColorString = (i) => { let hue = BASE_HUE + i * HUE_ROTATION; if (hue > 360) { hue = Math.floor(hue % 360); } const saturation = Math.floor(Math.random() * 60) + 40; // between 40 - 100 return `hsl(${hue}, ${saturation}%, 50%)`; }; function Box(color) { this.size = Math.floor(Math.random() * 20 + 10); // between 10 + 30 this.x = Math.floor(Math.random() * (canv.width - this.size) + 1); // initial random placement this.y = Math.floor(Math.random() * (canv.height - this.size) + 1); // initial random placement this.velocity = (60 - this.size) / 40; // 🤷♂️ (why not?) this.r = Math.random() * Math.PI; this.color = color; this.directionY = Math.random() < 0.5 ? -1 : 1; // -1 or +1 this.directionX = Math.random() < 0.5 ? -1 : 1; // -1 or +1 this.directionR = Math.random() < 0.5 ? -1 : 1; // -1 (clockwise) or +1 (counter-clockwise) this.generateBoxCoords = function () { const p1 = { x: this.x + this.size * Math.sin(this.r), y: this.y + this.size * Math.cos(this.r) }; const p2 = { x: this.x + this.size * Math.sin(this.r + BOX_CORNER_ANGLE), y: this.y + this.size * Math.cos(this.r + BOX_CORNER_ANGLE) }; const p3 = { x: this.x + this.size * Math.sin(this.r + BOX_CORNER_ANGLE * 2), y: this.y + this.size * Math.cos(this.r + BOX_CORNER_ANGLE * 2) }; const p4 = { x: this.x + this.size * Math.sin(this.r + BOX_CORNER_ANGLE * 3), y: this.y + this.size * Math.cos(this.r + BOX_CORNER_ANGLE * 3) }; return { p1, p2, p3, p4 }; }; this.rotate = function () { this.r += this.directionR * this.velocity * 0.01; this.x += this.directionX * this.velocity; this.y += this.directionY * this.velocity; }; this.draw = function () { ctx.save(); const points = this.generateBoxCoords(); ctx.beginPath(); ctx.moveTo(points.p1.x, points.p1.y); ctx.lineTo(points.p2.x, points.p2.y); ctx.lineTo(points.p3.x, points.p3.y); ctx.lineTo(points.p4.x, points.p4.y); ctx?.closePath(); ctx.globalAlpha = 0.8; // Some opacity for boxes overlapping ctx.fillStyle = this.color; ctx.fill(); ctx?.stroke(); ctx.restore(); }; this.drawShadow = function () { const coords = this.generateBoxCoords(); var pointsArr = []; // var angles = []; ??? for (point in coords) { const angle = Math.atan2(light.y - coords[point].y, light.x - coords[point].x) * -1; // angles.push(angle); ??? pointsArr.push({ startX: coords[point].x, startY: coords[point].y, .........完整代码请登录后点击上方下载按钮下载查看
网友评论0