canvas正方体粒子运动动画效果代码
代码语言:html
所属分类:粒子
代码描述:canvas正方体粒子运动动画效果代码
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> body { margin: 0; overflow: hidden; background-color: #141414; } .overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 100; } </style> </head> <body > <script> window.canvasOptions = { autoClear: true, autoCompensate: false, autoPushPop: true, canvas: true, centered: true, desynchronized: false, width: null, height: null }; /* requestAnimationFrame */ </script> <script > const { E, LN10, LN2, LOG10E, LOG2E, PI, SQRT1_2, SQRT2, abs, acos, acosh, asin, asinh, atan, atan2, atanh, cbrt, ceil, clz32, cosh, exp, expm1, floor, fround, hypot, imul, log, log10, log1p, log2, max, min, pow, /* random, */round, sign, sinh, sqrt, tan, tanh, trunc } = Math; let _codepenIDRegex = /codepen\.io\/[^/]+\/(?:pen|debug|fullpage|fullembedgrid)\/([^?#]+)/; // Why not? const ZERO = 0.0; const ONE = 1.0; const TWO = 2.0; const THREE = 3.0; const FOUR = 4.0; const FIVE = 5.0; const SIX = 6.0; const SEVEN = 7.0; const EIGHT = 8.0; const NINE = 9.0; const TEN = 10.0; const ELEVEN = 11.0; const TWELVE = 12.0; const SIXTEEN = 16.0; const THIRTY = 30.0; const THIRTY_TWO = 32.0; const SIXTY = 60.0; const HUNDRED = 100.0; const THOUSAND = 1000.0; const HALF = ONE / TWO; const THIRD = ONE / THREE; const TWO_THIRDS = THIRD * TWO; const QUARTER = ONE / FOUR; const THREE_QUARTER = QUARTER * THREE; const FIFTH = ONE / FIVE; const SIXTH = ONE / SIX; const SEVENTH = ONE / SEVEN; const EIGHTH = ONE / EIGHT; const TWELFTH = ONE / TWELVE; const SIXTEENTH = ONE / SIXTEEN; const ONE_THIRTIETH = ONE / THIRTY; const THIRTY_SECONDTH = ONE / THIRTY_TWO; const SIXTIETH = ONE / SIXTY; const TENTH = 1e-1; const HUNDREDTH = 1e-2; const THOUSANDTH = 1e-3; const TEN_THOUSANDTH = 1e-4; const HUNDRED_THOUSANDTH = 1e-5; const MILLIONTH = 1e-6; const TEN_MILLIONTH = 1e-7; const HUNDRED_MILLIONTH = 1e-8; const BILLIONTH = 1e-9; const TEN_BILLIONTH = 1e-10; const HUNDRED_BILLIONTH = 1e-11; const HALF_PI = PI * HALF; const THREE_QUARTER_PI = PI * THREE_QUARTER; const THIRD_PI = PI * THIRD; const QUARTER_PI = PI * QUARTER; const FIFTH_PI = PI * FIFTH; const SIXTH_PI = PI * SIXTH; const SEVENTH_PI = PI * SEVENTH; const EIGHTH_PI = PI * EIGHTH; const TWELFTH_PI = PI * TWELFTH; const SIXTEENTH_PI = PI * SIXTEENTH; const THIRTY_SECONDTH_PI = PI * THIRTY_SECONDTH; const TAU = PI * TWO; const TWO_TAU = TAU * TWO; const THREE_QUARTER_TAU = TAU * THREE_QUARTER; const HALF_TAU = PI; const THIRD_TAU = TAU * THIRD; const QUARTER_TAU = HALF_PI; const FIFTH_TAU = TAU * FIFTH; const SIXTH_TAU = THIRD_PI; const EIGHTH_TAU = QUARTER_PI; const TWELFTH_TAU = SIXTH_PI; const SIXTEENTH_TAU = EIGHTH_PI; const THIRTY_SECONDTH_TAU = SIXTEENTH_PI; const SQRT_3 = sqrt(THREE); const SQRT_4 = sqrt(FOUR); const SQRT_5 = sqrt(FIVE); const PHI = (1 + sqrt(5)) * 0.5; const GOLDEN_ANGLE = 1 / (PHI * PHI); const COLOR_BLACK = hsl(0, 0, 0); const COLOR_WHITE = hsl(0, 0, 100); const COLOR_RED = hsl(0, 100, 50); const COLOR_ORANGE = hsl(30, 100, 50); const COLOR_YELLOW = hsl(60, 100, 50); const COLOR_GREEN = hsl(120, 100, 50); const COLOR_CYAN = hsl(180, 100, 50); const COLOR_BLUE = hsl(240, 100, 50); const COLOR_PURPLE = hsl(280, 100, 50); const COLOR_MAGENTA = hsl(300, 100, 50); const TEXTALIGN_LEFT = 'left'; const TEXTALIGN_CENTER = 'center'; const TEXTALIGN_RIGHT = 'right'; const TEXTBASELINE_TOP = 'top'; const TEXTBASELINE_MIDDLE = 'middle'; const TEXTBASELINE_BOTTOM = 'bottom'; let _defaulCanvasOptions = { autoClear: false, autoCompensate: true, autoPushPop: false, canvas: true, centered: false, desynchronized: false, drawAndStop: false, width: null, height: null }; let _canvasOptions = {}; let canvas = document.getElementById('canvas'); if (canvas === null) { canvas = document.createElement('canvas'); canvas.id = 'canvas'; document.body.appendChild(canvas); } let ctx = canvas.getContext('2d', { desynchronized: window.canvasOptions && window.canvasOptions.desynchronized !== undefined ? window.canvasOptions.desynchronized : _defaulCanvasOptions.desynchronized // preserveDrawingBuffer: true // WebGL }); const _originalCtx = ctx; let _anim, _lastCanvasTime, canvasFrameRate, frameCount, width, height, width_half, height_half, width_quarter, height_quarter; let _canvasCurrentlyCentered = false; let _logMouseEvents = false; let _mouseUpdateTimeThreshold = 12; let mouseUpdate = -Infinity,mouseIn = false,mouseDown = false,mouseButton = -1, mouseMove = null,mousePos = null,mousePosPrev = null, mouseDownTime = -Infinity,mouseDownPos = null, mouseEnterPos = null,mouseExitPos = null, mouseUpTime = -Infinity,mouseUpPos = null, mouseEnterTime = -Infinity,mouseExitTime = -Infinity; function updateMouse(e, eventName) {// Modified from p5.js if (_logMouseEvents) { console.log('Mouse event', eventName, e); } if (e && !e.clientX) { e = e.touches && e.touches.length ? e.touches[0] : e.changedTouches ? e.changedTouches[0] : e; } if (!e) { if (_logMouseEvents) { console.log('Missing event data'); } return; } const _mouseUpdate = e.timeStamp === undefined ? performance.now() : e.timeStamp; if (mouseUpdate > 0 && _mouseUpdate - mouseUpdate < _mouseUpdateTimeThreshold) { if (_logMouseEvents) { // https://nolanlawson.com/2019/08/11/high-performance-input-handling-on-the-web/ // https://bugs.chromium.org/p/chromium/issues/detail?id=992954 // http://event-timing.glitch.me/ console.log('Skipping mouse event, are the dev tools open?'); } return; } mouseUpdate = _mouseUpdate; let rect = canvas.getBoundingClientRect(); let sx = canvas.scrollWidth / width; let sy = canvas.scrollHeight / height; let x = (e.clientX - rect.left) / sx; let y = (e.clientY - rect.top) / sy; if (x < 0) x = 0;else if (x > width) x = width; if (y < 0) y = 0;else if (y > height) y = height; if (mousePos) { mousePosPrev.set(mousePos); mousePos.set(x, y); } // return { x, y, winX: e.clientX, winY: e.clientY, id: e.identifier }; } // let mouseIn = false, mouseDown = false, mouseMove = null, mousePos = { x: 0, y: 0 }; // function updateMouse(e) { // if(e && !e.clientX) { // e = e.touches ? e.touches[0] : (e.changedTouches ? e.changedTouches[0] : e); // } // const { innerWidth: width, innerHeight: height } = window; // uniforms.mouse.value.set(e.clientX / width, 1 - e.clientY / height); // } // [ // [ 'mouseenter', e => mouseIn = true ], // [ 'mouseleave', e => (mouseIn = false, mouseDown = false) ], // [ 'mousemove', e => (mouseIn = true, mouseMove = e.timeStamp) ], // [ 'mousedown', e => (mouseIn = true, mouseDown = true) ], // [ 'mouseup', e => mouseDown = false ], // [ 'touchstart', e => mouseIn = true ], // [ 'touchend', e => (mouseIn = false, mouseDown = false) ], // [ 'touchcancel', e => (mouseIn = false, mouseDown = false) ], // [ 'touchmove', e => (mouseIn = true, mouseMove = e.timeStamp) ] // ].forEach(([ eventName, cb ]) => document.body.addEventListener(eventName, e => { // updateMouse(e); // cb(e); // })); canvas.addEventListener('mouseenter', e => { updateMouse(e, 'mouseenter'); mouseIn = true; mouseEnterTime = e.timeStamp; // mouseExitTime = -Infinity; }); canvas.addEventListener('mouseleave', e => { updateMouse(e, 'mouseleave'); mouseIn = mouseDown = false; // mouseEnterTime = -Infinity; mouseExitTime = e.timeStamp; }); canvas.addEventListener('mousemove', e => { updateMouse(e, 'mousemove'); mouseIn = true; mouseMove = e.timeStamp; }); canvas.addEventListener('mousedown', e => { updateMouse(e, 'mousedown'); mouseIn = mouseDown = true; mouseButton = e.button; mouseDownTime = e.timeStamp; mouseDownPos = mousePos.copy(); }); canvas.addEventListener('mouseup', e => { updateMouse(e, 'mouseup'); mouseDown = false; mouseButton = e.button; mouseUpTime = e.timeStamp; mouseUpPos = mousePos.copy(); }); canvas.addEventListener('touchstart', e => (updateMouse(e, 'touchstart'), mouseIn = true)); canvas.addEventListener('touchend', e => (updateMouse(e, 'touchend'), mouseIn = mouseDown = false)); canvas.addEventListener('touchcancel', e => (updateMouse(e, 'touchcancel'), mouseIn = mouseDown = false)); canvas.addEventListener('touchmove', e => (updateMouse(e, 'touchmove'), mouseIn = true)); window.addEventListener('resize', _resizeCanvas); window.addEventListener('load', () => { mousePos = new Vector(); mousePosPrev = new Vector(); mouseUpPos = new Vector(); mouseDownPos = new Vector(); mouseEnterPos = new Vector(); mouseExitPos = new Vector(); Object.assign( _canvasOptions, _defaulCanvasOptions, 'canvasOptions' in window ? window.canvasOptions : {}); if (_canvasOptions.canvas === false) { document.body.removeChild(canvas); } _resizeCanvas(); if ('setup' in window) { window.setup(); } frameCount = 0; _anim = requestAnimationFrame(_draw); }); function _draw(timestamp) { frameCount++; canvasFrameRate = 1000.0 / (timestamp - _lastCanvasTime); if (!_lastCanvasTime) { _lastCanvasTime = timestamp; } // _lastCanvasTime = timestamp; ctx = _originalCtx; _canvasOptions.autoClear && clear(null); if (_canvasOptions.autoPushPop) { push(); _canvasOptions.centered && (_canvasCurrentlyCentered = true) && translateCenter(); _canvasOptions.autoCompensate && compensateCanvas(); } 'draw' in window && window.draw(timestamp); _canvasOptions.autoPushPop && pop(); _canvasCurrentlyCentered = false; _lastCanvasTime = timestamp; if (_canvasOptions.drawAndStop) { return; } // beginPath(); // rect(width_half - 20, height_half - 20, 120, 30); // fill(hsl(0, 0, 0)); // fillStyle(hsl(0, 0, 100)); // font('24px monospace'); // fillText(canvasFrameRate.toFixed(2), width_half, height_half); _anim = requestAnimationFrame(_draw); } function _resizeCanvas(specificCanvas) { width = canvas.width = _canvasOptions.width !== null ? _canvasOptions.width : window.innerWidth; height = canvas.height = _canvasOptions.height !== null ? _canvasOptions.height : window.innerHeight; width_quarter = (width_half = width * HALF) * HALF; height_quarter = (height_half = height * HALF) * HALF; ctx.fillStyle = 'hsl(0, 0%, 100%)'; ctx.strokeStyle = 'hsl(0, 0%, 100%)'; if ('onResize' in window) { window.onResize(); } } function clear(x, y, w, h) { if (x !== undefined && typeof x === 'number') { ctx.clearRect(x, y, w, h); } else if (_canvasOptions.centered && _canvasCurrentlyCentered /* && x !== null */) { ctx.clearRect(-width_half, -height_half, width, height); } else { ctx.clearRect(0, 0, width, height); } } function isVectorish(n) { return n instanceof Vector || typeof n === 'object' && 'x' in n && 'y' in n; } function _resolveVectorArgs(x, y) { if (arguments.length === 0 || typeof x === 'undefined') return []; if (typeof x === 'number') return [x, ..._resolveVectorArgs(y)];else if (isVectorish(x)) return [x.x, x.y, ..._resolveVectorArgs(y)];else if (Array.isArray(x)) return [...x, ..._resolveVectorArgs(y)]; throw new Error(`Could not understand arguments with types [ ${typeof x}, ${typeof y} ]`); } function background(a) { push(); if (typeof a !== 'number') { fillStyle(a); } if (_canvasOptions.centered && _canvasCurrentlyCentered) { ctx.fillRect(-width_half, -height_half, width, height); } else { ctx.fillRect(0, 0, width, height); } pop(); } function globalAlpha(alpha = ctx.globalAlpha) { return ctx.globalAlpha = alpha; } function fillStyle(...args) { if (args.length === 1) { let a = args[0]; if (typeof a === 'string' || a instanceof CanvasGradient || a instanceof CanvasPattern) { ctx.fillStyle = a; } } return ctx.fillStyle; } function lineWidth(w) { if (typeof w === 'number') { ctx.lineWidth = w; } return ctx.lineWidth; } // "butt" || "round" || "square"; function lineCap(style = 'butt') { ctx.lineCap = style; } // "bevel" || "round" || "miter" function lineJoin(style) { ctx.lineJoin = style; } function miterLimit(value = 10) { ctx.miterLimit = value; } function strokeStyle(...args) { if (args.length === 1) { let [a] = args; if (typeof a === 'string' || a instanceof CanvasGradient) { ctx.strokeStyle = a; } } else if (args.length === 2) { strokeStyle(args[0]); lineWidth(args[1]); } return ctx.strokeStyle; } function lerpRGB(...args) { let r1 = 255; let b1 = 255; let g1 = 255; let a1 = 1; let r2 = 0; let g2 = 0; let b2 = 0; let a2 = 1; let t = 0.5; if (args.length === 3) { if (Array.isArray(args[0]) && Array.isArray(args[1])) { return lerpRGB(...args[0], ...args[1], args[2]); } [ { r: r1 = 255, b: b1 = 255, g: g1 = 255, a: a1 = 1 }, { r: r2 = 0, b: b2 = 0, g: g2 = 0, a: a2 = 1 }, t] = args; } else if (args.length === 7) { [ r1, g1, b1, r2, g2, b2, t] = args; } else if (args.length === 9) { [ r1, g1, b1, a1, r2, g2, b2, a2, t] = args; } else if (args.length === 2 && Array.isArray(args[0])) { if (args[0].length === 2) { return lerpRGB(...args[0], args[1]); } // TODO: Allow (possibly weighted) lerping between n-count RGBs at specified positions } else { return { r: 127.5, g: 127.5, b: 127.5, a: 1 }; } let r = lerp(r1, r2, t); let g = lerp(g1, g2, t); let b = lerp(b1, b2, t); let a = lerp(a1, a2, t); return { r, g, b, a }; } function hsl(hue, sat, light, alpha = 1) { if (typeof hue !== 'number') { if (Array.isArray(hue)) { [hue, sat, light, alpha = alpha] = hue; } else if ('h' in hue) { ({ h: hue, s: sat, l: light, a: alpha = alpha } = hue); } } hue = hue % 360; if (hue < 0) { hue += 360; } return `hsl(${hue} ${sat}% ${light}% / ${alpha})`; } function parseHSL(input) { if (typeof input !== 'string') { return input; } let result = input.match(/hsla?\(([\d.]+)\s*,?\s*([\d.]+)%\s*,?\s*([\d.]+)%\s*[/,]?\s*([\d.]*)?\)/); if (result) { let [i, h, s, l, a] = result; return { input, h, s, l, a }; } return null; } function setHueHSL(input, val) { if (val === undefined) return input; let p = parseHSL(input); p.h = val; return hsl(p); } function rotateHSL(input, amt = 90) { if (amt === 0) return input; let p = parseHSL(input); p.h += amt; return hsl(p); } function saturateHSL(input, amt = 0.1) { if (amt === 0) return input; let p = parseHSL(input); p.s *= 1 + amt; return hsl(p); } function lightenHSL(input, amt = 0.1) { if (amt === 0) return input; let p = parseHSL(input); p.l *= 1 + amt; return hsl(p); } function rgb(r = 255, g = 255, b = 255, a = 1) { if (typeof r !== 'number' && 'r' in r) { ({ r = 255, g = 255, b = 255, a = 1 } = r); } else if (isVectorish(r)) { ({ x: r = 255, y: g = 255, z: b = 255, a = 1 } = r); } return `rgba(${[r, g, b, a]})`; } function fill(...args) { let path; if (args.length) { if (args[0] instanceof Path2D) { path = args.shift(); } fillStyle(...args); } // Must branch the fill/stroke call as it // recognizes the undefined argument path ? ctx.fill(path) : ctx.fill(); } function stroke(...args) { let path; if (args.length) { if (args[0] instanceof Path2D) { path = args.shift(); } strokeStyle(...args); } // Must branch the fill/stroke call as it // recognizes the undefined argument path ? ctx.stroke(path) : ctx.stroke(); } function clip(...args) { ctx.clip(...args); } function createLinearGradient(x1 = -100, y1 = -100, x2 = 100, y2 = 100, stops = []) { // Vector, Vector [stops] if (typeof x1 !== 'number' && typeof y1 !== 'number') { stops = x2; ({ x: x2, y: y2 } = y1); ({ x: x1, y: y1 } = x1); } // Vector, number, number, [stops] else if (typeof x1 !== 'number' && typeof y1 === 'number' && typeof x2 === 'number') { stops = y2; [x2, y2] = [y1, x2]; ({ x: x1, y: y1 } = x1); } // Number, number, Vector, [stops] else if (typeof x1 === 'number' && typeof y1 === 'number' && typeof x2 !== 'number') { stops = y2; ({ x: x2, y: y2 } = x2); } const grad = ctx.createLinearGradient(x1, y1, x2, y2); if (stops && Array.isArray(stops) && stops.length) { stops.forEach(stop => { // offset: number, color: string try { if (Array.isArray(stop)) { grad.addColorStop(stop[0], stop[1]); } // { offset: number, color: string } else if (stop.offset && stop.color) { grad.addColorStop(stop.offset, stop.color); } } catch (err) { console.error(err); console.error(stop); } }); } return grad; } function createRadialGradient(x1 = 0, y1 = 0, r1 = 0, x2 = 0, y2 = 0, r2 = 200) { return ctx.createRadialGradient(x1, y1, r1, x2, y2, r2); } function createPattern(image, repetition = null) { return ctx.createPattern(image, repetition); } /* void ctx.drawImage(image, dx, dy); void ctx.drawImage(image, dx, dy, dWidth, dHeight); void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight); */ function drawImage(img, ...inputArgs) { const finalArgs = []; if (inputArgs.length === 0) { finalArgs.push(0, 0); } else { for (let i = 0; i < inputArgs.length; i += 2) { const result = _resolveVectorArgs(...inputArgs.slice(i, i + 2)); finalArgs.push(...result); } } if (img) { if (img instanceof AlcaImage) { img = img.image; } } if (img) { ctx.drawImage(img, ...finalArgs); } } // function getImageAlphaBounds(img, opts) { // if(!img) return new Vector(); // const alphaMin = opts.alphaMin === undefined ? 10 : opts.alphaMin; // const { data, width, height, canvas, ctx } = getImageData(img); // const bound = new Vector(); // for(let i = 0; i < imgData.data.length; i += 4) { // if(imgData.data[i + 3] > alphaMin) { // const { x, y } = iToXY(i * 0.25, sizeHalf, sizeHalf); // if(x < bound.h) { // bound.h = x; // } // if(y < bound.v) { // bound.v = y; // } // } // } // } function strokeText(str = 'Hello world', ...pos) { const [x = 0, y = 0] = _resolveVectorArgs(...pos); ctx.strokeText(str, x, y); } function fillText(str = 'Hello world', ...pos) { const [x = 0, y = 0] = _resolveVectorArgs(...pos); ctx.fillText(str, x, y); } function strokeFillText(str = 'Hello world', ...pos) { const [x = 0, y = 0] = _resolveVectorArgs(...pos); strokeText(str, x, y); fillText(str, x, y); } function fillStrokeText(str = 'Hello world', ...pos) { const [x = 0, y = 0] = _resolveVectorArgs(...pos); fillText(str, x, y); strokeText(str, x, y); } function measureText(text, fontSettings, backupFontSettings) { const hasFontSettings = fontSettings !== undefined; if (hasFontSettings) { push(); font(fontSettings, backupFontSettings); } const measure = ctx.measureText(text); if (hasFontSettings) { pop(); } return measure; } // ctx.textAlign = "left" || "right" || "center" || "start" || "end"; function textAlign(str = 'left') { ctx.textAlign = str; } // ctx.textBaseline = "top" || "hanging" || "middle" || "alphabetic" || "ideographic" || "bottom"; function textBaseline(str = 'left') { if (str === 'center') str = 'middle'; ctx.textBaseline = str; } function push() { ctx.save(); } function pop() { ctx.restore(); } function resetTransform() { ctx.resetTransform(); } function translate(x = 0, y = 0) { if (typeof x === 'number') { ctx.translate(x, y); } else if ('x' in x) { ctx.translate(x.x, x.y); } } function translateCenter(x = 0, y = 0) { ctx.translate(width_half + x, height_half + y); } function rotate(rot, offsetX, offsetY) { rot = rot % TAU; if (offsetX === undefined) { ctx.rotate(rot); } else if (typeof offsetX === 'number') { ctx.translate(offsetX, offsetY); ctx.rotate(rot); ctx.translate(-offsetX, -offsetY); } else if (isVectorish(offsetX)) { ctx.translate(offsetX.x, offsetX.y); ctx.rotate(rot); ctx.translate(-offsetX.x, -offsetX.y); } } function scale(x = 1, y = x) { ctx.scale(x, y); } function shearX(rad) { ctx.transform(1, 0, tan(rad), 1, 0, 0); } function shearY(rad) { ctx.transform(1, tan(rad), 0, 1, 0, 0); } function compensateCanvas() { let offX = 0; let offY = 0; if (width % 2) offX += 0.5; if (height % 2) offY += 0.5; if (offX || offY) { translate(offX, offY); } } const compOper = { default: 'source-over', sourceOver: 'source-over', sourceIn: 'source-in', sourceOut: 'source-out', sourceAtop: 'source-atop', destinationOver: 'destination-over', destinationIn: 'destination-in', destinationOut: 'destination-out', destinationAtop: 'destination-atop', lighter: 'lighter', copy: 'copy', xor: 'xor', multiply: 'multiply', screen: 'screen', overlay: 'overlay', darken: 'darken', lighten: 'lighten', colorDodge: 'color-dodge', colorBurn: 'color-burn', hardLight: 'hard-light', softLight: 'soft-light', difference: 'difference', exclusion: 'exclusion', hue: 'hue', saturation: 'saturation', color: 'color', luminosity: 'luminosity', source: { over: 'source-over', in: 'source-in', out: 'source-out', atop: 'source-atop' }, destination: { over: 'destination-over', in: 'destination-in', out: 'destination-out', atop: 'destination-atop' }, light: { hard: 'hard-light', soft: 'soft-light' } }; function compositeOperation(type = compOper.default) {// https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation ctx.globalCompositeOperation = type; } // const filters = [ // [ 'url', [ 'url' ] ], // [ 'blur', [ 'length' ] ], // [ 'brightness', [ 'percentage' ] ], // [ 'contrast', [ 'percentage' ] ] // ]; function filter(filterFuncs = 'none') { ctx.filter = filterFuncs || 'none'; } function beginPath() { ctx.beginPath(); } function moveTo(x, y) { if (typeof x === 'number') { ctx.moveTo(x, y); } else if (isVectorish(x)) { ctx.moveTo(x.x, x.y); } } function lineTo(x, y) { if (typeof x === 'number') { ctx.lineTo(x, y); } else if (isVectorish(x)) { ctx.lineTo(x.x, x.y); } } function quadraticCurveTo(cpX, cpY, x, y) { // ctx.quadraticCurveTo(cpX, cpY, x, y); let a = []; let b = []; if (typeof cpX === 'number') { a = [cpX, cpY]; if (typeof x === 'number') { b = [x, y]; } else if ('x' in x) { b = x.xy; } } else if ('x' in cpX) { a = cpX.xy; if (typeof cpY === 'number') { b = [cpY, x]; } else if ('x' in cpY) { b = cpY.xy; } } ctx.quadraticCurveTo(a[0], a[1], b[0], b[1]); } function bezierCurveTo(cp1X, cp1Y, cp2X, cp2Y, x, y) { let a = []; let b = []; let c = []; if (typeof cp1X === 'number') { a = [cp1X, cp1Y]; if (typeof cp2X === 'number') { b = [cp2X, cp2Y]; if (typeof x === 'number') { c = [x, y]; } else if ('x' in x) { c = x.xy; } } else if ('x' in cp2X) { b = cp2X.xy; if (typeof cp2Y === 'number') { c = [cp2Y, x]; } else if ('x' in cp2Y) { c = cp2Y.xy; } } } else if ('x' in cp1X) { a = cp1X.xy; if (typeof cp1Y === 'number') { b = [cp1Y, cp2X]; if (typeof cp2Y === 'number') { c = [cp2Y, x]; } else if ('x' in cp2Y) { c = cp2Y.xy; } } else if ('x' in cp1Y) { b = cp1Y.xy; if (typeof cp2X === 'number') { c = [cp2X, cp2Y]; } else if ('x' in cp2X) { c = cp2X.xy; } } } ctx.bezierCurveTo(a[0], a[1], b[0], b[1], c[0], c[1]); } function closePath() { ctx.closePath(); } function point(x = 0, y = 0, r = 0, g = 0, b = 0, a = 255, doPut_ = true) { // let imgData = ctx.createImageData(1, 1); // imgData.data[0] = r; // imgData.data[1] = g; // imgData.data[2] = b; // imgData.data[3] = a; // if(doPut_) { // ctx.putImageData(imgData, x, y); // } // return imgData; } function line(x = 0, y = 0, x_ = 0, y_ = 0) { if (typeof x === 'number') { moveTo(x, y); lineTo(x_, y_); } else if (isVectorish(x)) { moveTo(x); lineTo(y, x_); } } function vertices(...verts) { let shouldMoveFirst = false; if (verts.length === 0) return;else if (verts.length === 1 && Array.isArray(verts[0])) { verts = verts[0]; } else if (verts.length === 2 && Array.isArray(verts[0]) && typeof verts[1] === 'boolean') { shouldMoveFirst = verts[1]; verts = verts[0]; } for (let i = 0; i < verts.length; i++) { let n = verts[i]; let x = 0; let y = 0; if (Array.isArray(n)) { [x, y] = n; } else if (isVectorish(n)) { ({ x, y } = n); } if (!shouldMoveFirst || i !== 0) { lineTo(x, y); } else { moveTo(x, y); } } } function rect(x, y, w, h, r) {var _x2, _y2, _w, _h, _r; if (isVectorish(x)) { // Shift args down 1 [w, h, r] = [y, w, h]; ({ x, y } = x); } if (isVectorish(w)) { r = h; ({ x: w, y: h } = w); } // x = 0, y = 0, w = 10, h = w, r = 0 x = (_x2 = x) !== null && _x2 !== void 0 ? _x2 : 0; y = (_y2 = y) !== null && _y2 !== void 0 ? _y2 : 0; w = (_w = w) !== null && _w !== void 0 ? _w : 10; h = (_h = h) !== null && _h !== void 0 ? _h : w; r = (_r = r) !== null && _r !== void 0 ? _r : 0; if (r > 0) { moveTo(x + r, y); arcTo(x + w, y, x + w, y + h, r); arcTo(x + w, y + h, x, y + h, r); arcTo(x, y + h, x, y, r); arcTo(x, y, x + w, y, r); closePath(); } else { ctx.rect(x, y, w, h); } } function rectCentered(x, y, w, h, r) {var _x3, _y3, _w2, _h2, _r2; if (isVectorish(x)) { // Shift args down 1 [w, h, r] = [y, w, h]; ({ x, y } = x); } if (isVectorish(w)) { r = h; ({ x: w, y: h } = w); } // x = 0, y = 0, w = 10, h = w, r = 0 x = (_x3 = x) !== null && _x3 !== void 0 ? _x3 : 0; y = (_y3 = y) !== null && _y3 !== void 0 ? _y3 : 0; w = (_w2 = w) !== null && _w2 !== void 0 ? _w2 : 10; h = (_h2 = h) !== null && _h2 !== void 0 ? _h2 : w; r = (_r2 = r) !== null && _r2 !== void 0 ? _r2 : 0; x -= w * 0.5; y -= h * 0.5; if (r > 0) { moveTo(x + r, y); arcTo(x + w, y, x + w, y + h, r); arcTo(x + w, y + h, x, y + h, r); arcTo(x, y + h, x, y, r); arcTo(x, y, x + w, y, r); closePath(); } else { ctx.rect(x, y, w, h); } } function arc(x, y, radius, startAngle, endAngle, anticlockwise) {var _x4, _y4, _radius, _startAngle, _endAngle, _anticlockwise; if (isVectorish(x)) { // Shift args down 1 [radius, startAngle, endAngle, anticlockwise] = [y, radius, startAngle, endAngle]; ({ x, y } = x); } // x = 0, y = 0, radius = 50, startAngle = 0, endAngle = Math.PI * 2, anticlockwise = false x = (_x4 = x) !== null && _x4 !== void 0 ? _x4 : 0; y = (_y4 = y) !== null && _y4 !== void 0 ? _y4 : 0; radius = (_radius = radius) !== null && _radius !== void 0 ? _radius : 50; startAngle = (_startAngle = startAngle) !== null && _startAngle !== void 0 ? _startAngle : 0; endAngle = (_endAngle = endAngle) !== null && _endAngle !== void 0 ? _endAngle : TAU; anticlockwise = (_anticlockwise = anticlockwise) !== null && _anticlockwise !== void 0 ? _anticlockwise : false; if (radius < 0) radius = 0; ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise); } function arcTo(x1 = 0, y1 = 0, x2 = 0, y2 = 0, radius = 50) { ctx.arcTo(x1, y1, x2, y2, radius); } // function circle(x = 0, y = undefined, rX = 20, rY = undefined) { function circle(x, y, rX, rY) {var _x5, _y5, _rX; // if(typeof x !== 'number' && 'x' in x) { // if(y !== undefined) { // rX = y; // } // y = x.y; // x = x.x; // } // else if(y === undefined) { // y = 0; // } // if(typeof rX !== 'number' && 'x' in rX) { // rY = rX.y; // rX = rX.x; // } if (isVectorish(x)) { [rX, rY] = [y, rX]; ({ x, y } = x); } if (isVectorish(rX)) { ({ x: rX, y: rY } = rX); } x = (_x5 = x) !== null && _x5 !== void 0 ? _x5 : 0; y = (_y5 = y) !== null && _y5 !== void 0 ? _y5 : 0; rX = (_rX = rX) !== null && _rX !== void 0 ? _rX : 20; ctx.moveTo(x + rX, y); if (rY !== undefined) { ellipse(x, y, rX, rY); } else { if (rX < 0) rX = 0; ctx.arc(x, y, rX, 0, TAU); } } // function ellipse(x = 0, y = 0, rX = 50, rY = 50, rot = 0, angStart = 0, angEnd = Math.PI * 2, antiCw = false) { function ellipse(x, y, rX, rY, rot, angStart, angEnd, antiCw) {var _x6, _y6, _rX2, _rY, _rot, _angStart, _angEnd, _antiCw; if (isVectorish(x)) { [rX, rY, rot, angStart, angEnd, antiCw] = [y, rX, rY, rot, angStart, angEnd]; ({ x, y } = x); } if (isVectorish(rX)) { [rot, angStart, angEnd, antiCw] = [rY, rot, angStart, angEnd]; ({ x: rX, y: rY } = rX); } x = (_x6 = x) !== null && _x6 !== void 0 ? _x6 : 0; y = (_y6 = y) !== null && _y6 !== void 0 ? _y6 : 0; rX = (_rX2 = rX) !== null && _rX2 !== void 0 ? _rX2 : 50; rY = (_rY = rY) !== null && _rY !== void 0 ? _rY : rX; rot = (_rot = rot) !== null && _rot !== void 0 ? _rot : 0; angStart = (_angStart = angStart) !== null && _angStart !== void 0 ? _angStart : 0; angEnd = (_angEnd = angEnd) !== null && _angEnd !== void 0 ? _angEnd : TAU; antiCw = (_antiCw = antiCw) !== null && _antiCw !== void 0 ? _antiCw : false; if (rX < 0) rX = 0; if (rY < 0) rY = 0; ctx.ellipse(x, y, rX, rY, rot, angStart, angEnd, antiCw); } function regularPolygon(sides, radius = 50, rotation = 0) { let circumference = TAU * radius; let count = min(sides, circumference); for (let i = 0; i < count; i++) { let t = i / count * TAU + rotation; let x = cos(t) * radius.........完整代码请登录后点击上方下载按钮下载查看
网友评论0