canvas实现鱼鳞片翻转动画效果代码

代码语言:html

所属分类:动画

代码描述:canvas实现鱼鳞片翻转动画效果代码

代码标签: 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
          };
  
    </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;


// 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 parseHex(input) {
  if (typeof input === 'number') {
    input = input.toString(16);
  } else
  if (typeof input !== 'string') {
    return input;
  }
  if (input.length % 3) {
    input = input.slice(1);
  }
  if (input.length === 3) {
    const [r, g, b] = input;
    return { r: parseInt(r + r, 16), g: parseInt(g + g, 16), b: parseInt(b + b, 16) };
  }
  const [r1, r2, g1, g2, b1, b2] = input.split(/(\w\w)/);
  return { r: parseInt(r1 + r2, 16), g: parseInt(g1 + g2, 16), b: parseInt(b1 + b2, 16) };
}

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.........完整代码请登录后点击上方下载按钮下载查看

网友评论0