紧跟潮流
大前端和全栈是以后前端的一个趋势,懂后端的前端,懂各端的前端更加具有竞争力,以后可以往这个方向靠拢。
这边整理了一个对标“阿里 50W”年薪企业高级前端工程师成长路线,由于图片太大仅展示一小部分
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
index.html
xezbab.css
body {
margin: 0;
overflow: hidden;
background-color: hsl(0, 0%, 8%);
// background-color: rgb(20, 20, 20);
}
.overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 100;
}
script.js
const particles = [];
const padding = 100;
function setup() {
for (let i = 0; i < 10; i++) {
const p = new Particle();
particles.push§;
}
}
function draw(e) {
// rotate(e * 0.0001);
compositeOperation(compOper.lighter);
// lineWidth(2);
for (let i = particles.length - 1; i >= 0; i–) {
const p = particles[i];
// if(p.dead) continue;
if (p.dead) {
particles.splice(i, 1);
continue;
}
beginPath();
circle(p.pos, 1);
p.pos.add(p.vel);
ctx.shadowColor = hsl(p.hue, 100, 70, 1);
ctx.shadowBlur = 10;
const t = (e - p.lastChanged) / 4000;
fill(hsl(p.hue, 100, 60, 0.3));
if (
p.pos.x < -width_half - padding ||
p.pos.x > width_half + padding ||
p.pos.y < -height_half - padding ||
p.pos.y > height_half + padding)
{
if (p.splitable) {
p.reset();
} else
{
p.dead = true;
}
} else
if (random(0.03, 1) < t) {
p.lastChanged = e;
p.pickDirection();
if (particles.length < 300 && random(0.1, 1) < t) {
const splitP = new Particle();
splitP.splitable = false;
splitP.pos.set(p.pos);
splitP.vel.set(p.vel);
splitP.pickDirection();
particles.push(splitP);
}
}
}
}
class Particle {
constructor() {
this.reset();
this.splitable = true;
this.dead = false;
}
reset() {
this.lastChanged = performance.now();
this.hue = random(130) + 180;
this.pos = createVector(0, 0);
this.vel = createVector(2, 0);
this.pickDirection([-2, -1, 0, 1, 2, 3]);
}
pickDirection(range = [-1, 0, 1]) {
this.vel.rotate(random(range) * THIRD_PI);
}}
xezbab.js
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 THIRD_PI = PI * THIRD;
const THREE_QUARTER_PI = PI * THREE_QUARTER;
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 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,
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 mouseIn = false, mouseDown = false, mouseMove = null, mousePos = null, mousePosPrev = null;
function updateMouse(e) { // Modified from p5.js
if(e && !e.clientX) {
e = e.touches ? e.touches[0] : (e.changedTouches ? e.changedTouches[0] : e);
}
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), mouseIn = true));
canvas.addEventListener(‘mouseleave’, e => (updateMouse(e), mouseIn = false, mouseDown = false));
canvas.addEventListener(‘mousemove’, e => (updateMouse(e), mouseIn = true, mouseMove = e.timeStamp));
canvas.addEventListener(‘mousedown’, e => (updateMouse(e), mouseIn = true, mouseDown = true));
canvas.addEventListener(‘mouseup’, e => (updateMouse(e), mouseDown = false));
canvas.addEventListener(‘touchstart’, e => (updateMouse(e), mouseIn = true));
canvas.addEventListener(‘touchend’, e => (updateMouse(e), mouseIn = false, mouseDown = false));
canvas.addEventListener(‘touchcancel’, e => (updateMouse(e), mouseIn = false, mouseDown = false));
canvas.addEventListener(‘touchmove’, e => (updateMouse(e), mouseIn = true));
window.addEventListener(‘resize’, _resizeCanvas);
window.addEventListener(‘load’, () => {
mousePos = createVector();
mousePosPrev = createVector();
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);
_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;
_anim = requestAnimationFrame(_draw);
}
function _resizeCanvas(specificCanvas) {
// if(_canvasOptions.width === null)
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 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 = args[0];
}
}
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[0];
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§;
}
function rotateHSL(input, amt = 90) {
if(amt === 0) return input;
let p = parseHSL(input);
p.h += amt;
return hsl§;
}
function saturateHSL(input, amt = 0.1) {
if(amt === 0) return input;
let p = parseHSL(input);
p.s *= 1 + amt;
return hsl§;
}
function lightenHSL(input, amt = 0.1) {
if(amt === 0) return input;
let p = parseHSL(input);
p.l *= 1 + amt;
return hsl§;
}
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);
}
return rgba(${r}, ${g}, ${b}, ${a})
;
}
function fill(…args) {
if(args.length) {
fillStyle(…args);
}
ctx.fill();
}
function stroke(…args) {
if(args.length) {
strokeStyle(…args);
}
ctx.stroke();
}
function clip() {
ctx.clip();
}
function createLinearGradient(x1 = -100, y1 = -100, x2 = 100, y2 = 100) {
// if(typeof x1 !== ‘number’) {
// if(‘x’ in x1) {
// }
// }
return ctx.createLinearGradient(x1, y1, x2, y2);
}
function createRadialGradient(x1 = 0, y1 = 0, r1 = 0, x2 = 0, y2 = 0, r2 = 200) {
return ctx.createRadialGradient(x1, y1, r1, x2, y2, r2);
}
function drawImage(img, x = 0, y = 0, …args) {
ctx.drawImage(img, x, y, …args);
}
function strokeText(str = ‘Hello world’, x = 0, y = 0) {
ctx.strokeText(str, x, y);
}
function fillText(str = ‘Hello world’, x = 0, y = 0) {
ctx.fillText(str, x, y);
}
function strokeFillText(str = ‘Hello world’, x = 0, y = 0) {
strokeText(str, x, y);
fillText(str, x, y);
}
function fillStrokeText(str = ‘Hello world’, x = 0, y = 0) {
fillText(str, x, y);
strokeText(str, x, y);
}
function measureText(…args) {
return ctx.measureText(…args);
}
// 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’) {
if(‘x’ in offsetX) {
ctx.translate(offsetX.x, offsetX.y);
ctx.rotate(rot);
ctx.translate(-offsetX.x, -offsetX.y);
}
}
else {
ctx.translate(offsetX, offsetY);
ctx.rotate(rot);
ctx.translate(-offsetX, -offsetY);
}
}
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;
}
function beginPath() {
ctx.beginPath();
}
function moveTo(x, y) {
if(typeof x === ‘number’) {
ctx.moveTo(x, y);
}
else if(‘x’ in x) {
ctx.moveTo(x.x, x.y);
}
}
function lineTo(x, y) {
if(typeof x === ‘number’) {
ctx.lineTo(x, y);
}
else if(‘x’ in 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(‘x’ in x) {
moveTo(x);
lineTo(y, x_);
}
}
function vertices(…verts) {
if(verts.length === 0) return;
else if(verts.length === 1 && Array.isArray(verts[0])) {
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(n instanceof Vector || (‘x’ in n && ‘y’ in n)) {
({ x, y } = n);
}
lineTo(x, y);
}
}
function arcTo(x1 = 0, y1 = 0, x2 = 0, y2 = 0, radius = 50) {
ctx.arcTo(x1, y1, x2, y2, radius);
}
function rect(x = 0, y = 0, w = 10, h = w, 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 arc(x = 0, y = 0, radius = 50, startAngle = 0, endAngle = Math.PI * 2, anticlockwise = false) {
if(radius < 0) radius = 0;
ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);
}
function circle(x = 0, y = undefined, rX = 20, rY = undefined) {
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;
}
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) {
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;
let y = sin(t) * radius;
if(i === 0) {
ctx.moveTo(x, y);
}
else {
ctx.lineTo(x, y);
}
}
ctx.closePath();
}
function genRegularPolygon(sides = 3, radius = 50, rotation = 0) {
let iSizes = 1 / sides * TAU;
let data = {
sides,
radius,
rotation,
points: []
};
for(let i = 0; i < sides; i++) {
let t = i * iSizes + rotation;
let x = cos(t) * radius;
let y = sin(t) * radius;
let point = createVector(x, y);
Object.assign(point, { i, t });
data.points.push(point);
}
return data;
}
function getCodePenID() {
if(_codepenIDRegex.test(window.location.href)) {
return _codepenIDRegex.exec(window.location.href)[1];
}
else {
let metas = document.getElementsByTagName(‘link’);
for(let i = 0; i < metas.length; i++) {
let m = metas[i];
if(m.getAttribute(‘rel’) == ‘canonical’) {
let id = _codepenIDRegex.exec(m.getAttribute(‘href’));
if(id) {
return id[1];
}
}
}
}
}
function isPreviewEmbed() {
return location.href.includes(‘/fullcpgrid/’);
}
function loadImage(url) {
return new Promise((resolve, reject) => {
let img = new Image();
img.crossOrigin = ‘Anonymous’;
img.onload = () => resolve(img);
img.src = url;
});
}
loadImage.alca = function(urlPart) {
return loadImage(‘https://alca.tv/static/’ + urlPart);
};
loadImage.alca.pen = function(urlPart) {
return loadImage.alca(‘codepen/’ + urlPart);
};
loadImage.alca.pen._ = function(urlPart) {
return loadImage.alca.pen(pens/${getCodePenID()}/${urlPart}
);
};
function loadVideo(url) {
return new Promise((resolve, reject) => {
let vid = document.createElement(‘video’);
vid.crossOrigin = ‘anonymous’;
vid.onloadeddata = () => resolve(vid);
vid.preload = true;
vid.muted = true;
vid.src = url;
vid.load();
});
}
loadVideo.alca = function(urlPart) {
return loadVideo(‘https://alca.tv/static/’ + urlPart);
};
loadVideo.alca.pen = function(urlPart) {
return loadVideo.alca(‘codepen/’ + urlPart);
};
loadVideo.alca.pen._ = function(urlPart) {
return loadVideo.alca.pen(pens/${getCodePenID()}/${urlPart}
);
};
function loadData(url) {
return fetch(url);
}
loadData.alca = function(urlPart) {
return loadData(‘https://alca.tv/static/’ + urlPart);
};
function loadText(url) {
return loadData(url)
.then(res => res.text());
}
loadText.alca = function(urlPart) {
return loadText(‘https://alca.tv/static/’ + urlPart);
};
function loadJSON(url) {
return loadData(url)
.then(res => res.json());
}
loadJSON.alca = function(urlPart) {
return loadJSON(‘https://alca.tv/static/’ + urlPart);
};
function getImageData(img, …args) {
if(img instanceof Image) {
let canvas = document.createElement(‘canvas’);
let ctx = canvas.getContext(‘2d’);
Object.assign(canvas, { width: img.width, height: img.height });
ctx.drawImage(img, 0, 0);
let data;
if(args.length) {
data = ctx.getImageData(…args);
}
else {
data = ctx.getImageData(0, 0, img.width, img.height);
}
return Object.assign(data, { canvas, ctx });
}
else {
return ctx.getImageData(img, …args);
}
}
function xyToI(x, y, w, h) {
if(typeof x !== ‘number’ && ‘x’ in x) {
h = w;
w = y;
({ x, y } = x);
}
if(w === undefined) w = 1;
// if(h === undefined) h = Infinity;
return x + w * y;
}
function iToXY(i, w, h) {
return createVector(i % w, floor(i / w));
}
function random(low = 1, high = null) {
if(Array.isArray(low)) {
return low[floor(Math.random() * low.length)];
}
if(high === null) {
return Math.random() * low;
}
return Math.random() * (high - low) + low;
}
紧跟潮流
大前端和全栈是以后前端的一个趋势,懂后端的前端,懂各端的前端更加具有竞争力,以后可以往这个方向靠拢。
这边整理了一个对标“阿里 50W”年薪企业高级前端工程师成长路线,由于图片太大仅展示一小部分