gsap结合svg实现ps钢笔绘画效果代码
代码语言:html
所属分类:拖放
代码描述:gsap结合svg实现ps钢笔绘画效果代码,有音效
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <style> * { margin: 0; padding: 0; box-sizing: border-box; } html { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } body { height: 100vh; display: grid; place-items: center; color: #1f2933; background: hsl(0, 0%, 100%); } .canvas { position: relative; /* max-width: 32rem; aspect-ratio: 1/1; */ width: 100vw; height: 100vh; } .canvas__svg { position: absolute; top: 0; left: 0; width: 100%; height: 100%; overflow: visible; } .canvas__svg-bg {} .canvas__controls { position: absolute; bottom: 1.5rem; left: 50%; display: flex; transform: translateX(-50%); z-index: 2; } .canvas__btn { width: 2.75rem; height: 2.75rem; margin-right: 1rem; border: none; cursor: pointer; background: none; } .canvas__btn:last-of-type { margin-right: 0; } .canvas__btn-icon { width: 24px; height: 24px; fill: none; stroke-width: 1.5; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; } .canvas__shape { fill: none; stroke: currentColor; stroke-width: 3; } .canvas__dummy-shape { fill: none; stroke: #7b8794; stroke-dasharray: 4; stroke-width: 2; vector-effect: non-scaling-stroke; pointer-events: none; } .canvas__point { stroke: #000; stroke-width: 3; fill: #fff; /* vector-effect: non-scaling-stroke; */ } .closed .canvas__point[data-index="0"] { fill: #fff; } .canvas__btn--active { color: #1f2933; } </style> </head> <body> <div class="canvas"> <svg class="canvas__svg" viewBox="0 0 1920 1080" preserveAspectRatio="xMidYMid slice"></svg> <div class="canvas__controls"> <button class="canvas__btn canvas__btn--fill canvas__btn--active"> <svg class="canvas__btn-icon"> <path d="M12 2.69l5.66 5.66a8 8 0 1 1-11.31 0z"></path> </svg> </button> <button class="canvas__btn canvas__btn--delete"> <svg viewBox="0 0 24 24" class="canvas__btn-icon"> <polyline points="3 6 5 6 21 6"></polyline> <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path> <line x1="10" y1="11" x2="10" y2="17"></line> <line x1="14" y1="11" x2="14" y2="17"></line> </svg> </button> </div> </div> <script type="module"> import { gsap } from "https://cdn.skypack.dev/gsap"; import { Draggable } from "https://cdn.skypack.dev/gsap/Draggable"; import { SVG } from "https://cdn.skypack.dev/@svgdotjs/svg.js"; import { v4 as uuidv4 } from "https://cdn.skypack.dev/uuid"; import { spline } from "https://cdn.skypack.dev/@georgedoescode/spline"; console.clear(); const pop = document.createElement("audio"); pop.src = "//repo.bfw.wiki/bfwrepo/sound/60443505d58d8.wav"; const create = document.createElement("audio"); create.src = "//repo.bfw.wiki/bfwrepo/sound/6044351a38de4.wav"; const btnClickSound = document.createElement("audio"); btnClickSound.src = "//repo.bfw.wiki/bfwrepo/sound/6044352a25ba7.wav"; // GSAP gsap.registerPlugin(Draggable); gsap.registerEffect({ name: "elasticIn", effect: (targets, config) => gsap.to(targets, { ...config }), defaults: { scale: 1, transformOrigin: "50%", duration: 1.5, ease: "elastic.out(1, 0.3)" } }); gsap.registerEffect({ name: "scaleOut", effect: (targets, config) => gsap.to(targets, { ...config }), defaults: { scale: 0, transformOrigin: "50%", duration: 0.25, overwrite: true } }); // Create canvas instance const canvas = { svg: SVG(".canvas__svg"), cursorMode: "DRAW", buttons: { copy: document.querySelector(".canvas__btn--copy"), delete: document.querySelector(".canvas__btn--delete"), fill: document.querySelector(".canvas__btn--fill") }, currentShape: null, shapes: [] }; canvas.shapes.push(createShape()); canvas.currentShape = canvas.shapes[0]; // Event listeners canvas.buttons.delete.addEventListener("click", () => { btnClickSound.play(); gsap.to(canvas.currentShape.group.node, { opacity: 0, onComplete: () => { canvas.currentShape.group.remove(); canvas.shapes.push(createShape()); canvas.currentShape = canvas.shapes[canvas.shapes.length - 1]; } }); }); canvas.buttons.fill.addEventListener("click", e => { e.stopPropagation(); btnClickSound.play(); if (canvas.currentShape.isClosed) { gsap.set(canvas.currentShape.pathEl.node, { fill: `hsl(${Math.random() * 260}, 100%, 80%)` }); } }); canvas.svg.node.addEventListener("click", e => { if (e.target.classList.contains("canvas__svg")) { if (canvas.currentShape.isClosed) { gsap.effects.scaleOut(".canvas__point"); canvas.shapes.push(createShape()); canvas.currentShape = canvas.shapes[canvas.shapes.length - 1]; } addPointToShape(e); setShapePathOpen(); renderShapePath(); } if (e.target.classList.contains("canvas__point")) { if (e.target.getAttribute("data-index") === "0") { closeShape(); } } }); window.addEventListener("mousemove", event => { const { .........完整代码请登录后点击上方下载按钮下载查看
网友评论0