Toggle navigation
在线编辑器
在线代码
文本比较
jQuery下载
前端库
在线手册
登录/注册
下载代码
html
css
js
分享到微信朋友圈
X
html
css
body { margin: 0; }
JavaScript
const CONSTANTS = { rad2deg: 57.295779513082320, }; class LV2 { // x: number // y: number constructor(x, y) { this.x = x; this.y = y; } // return: string // eg. [1,2] toString() { return '[' + this.x + ',' + this.y + ']'; } // return: LV2 copy() { return new LV2(this.x, this.y); } // o: { x, y } setAs(o) { this.x = o.x; this.y = o.y; } // x: number // y: number setValues(x, y) { this.x = x; this.y = y; } // o: { x: number, y: number } // return: LV2 add(o) { return new LV2(this.x + o.x, this.y + o.y); } // o: { x: number, y: number } iadd(o) { this.x += o.x; this.y += o.y; } // o: { x: number, y: number } // return: LV2 sub(o) { return new LV2(this.x - o.x, this.y - o.y); } // o: { x: number, y: number } isub(o) { this.x -= o.x; this.y -= o.y; } // s: number // return: LV2 scale(s) { return new LV2(this.x * s, this.y * s); } // s: number iscale(s) { this.x *= s; this.y *= s; } // s: number // return: LV2 div(s) { return new LV2(this.x / s, this.y / s); } // s: number idiv(s) { this.x /= s; this.y /= s; } // o: { x: number, y: number } // return: number dot(o) { return this.x * o.x + this.y * o.y; } // o: { x: number, y: number } // return: number dist(o) { var dx = this.x - o.x; var dy = this.y - o.y; return Math.sqrt(dx * dx + dy * dy); } // return: number mag() { return Math.sqrt(this.x * this.x + this.y * this.y); } // return: LV2 round() { return new LV2(Math.round(this.x), Math.round(this.y)); } // return: LV2 floor() { return new LV2(Math.floor(this.x), Math.floor(this.y)); } iround() { this.x = Math.round(this.x); this.y = Math.round(this.y); } ifloor() { this.x = Math.floor(this.x); this.y = Math.floor(this.y); } // return: LV2 unit() { var m = Math.sqrt(this.x * this.x + this.y * this.y); return new LV2(this.x / m, this.y / m); } iunit() { var m = Math.sqrt(this.x * this.x + this.y * this.y); this.x /= m; this.y /= m; } // target: LV2 // time: number [0-1] // return: LV2 interpolateTo(target, time) { var to = target.copy(); to.isub(this); to.iscale(time); to.iadd(this); return to; } // return: number getAngle() { var angle = CONSTANTS.rad2deg * Math.atan(this.y / this.x); if(this.x < 0.0) angle += 180.0; else if(this.y < 0.0) angle += 360.0; return angle; } // angle: number // return: LV2 static fromAngle(angle) { var rv = new LV2(0,0); angle /= CONSTANTS.rad2deg; rv.x = Math.cos(angle); rv.y = Math.sin(angle); return rv; } } class LV3 { // x: number // y: number // z: number constructor(x, y, z) { this.x = x; this.y = y; this.z = z; } // return: string toString() { return '[' + this.x + ',' + this.y + ',' + this.z + ']'; } // return: LV3 copy() { return new LV3(this.x, this.y, this.z); } // o: LV3 setAs(o) { this.x = o.x; this.y = o.y; this.z = o.z; } // x: number // y: number // z: number setValues(x, y, z) { this.x = x; this.y = y; this.z = z; } // o: LV3 // return: LV3 add(o) { return new LV3(this.x + o.x, this.y + o.y, this.z + o.z); } // o: LV3 iadd(o) { this.x += o.x; this.y += o.y; this.z += o.z; } // o: LV3 // return: LV3 sub(o) { return new LV3(this.x - o.x, this.y - o.y, this.z - o.z); } // o: LV3 isub(o) { this.x -= o.x; this.y -= o.y; this.z -= o.z; } // s: number // return: LV3 scale(s) { return new LV3(this.x * s, this.y * s, this.z * s); } // s: number // return: LV3 iscale(s) { this.x *= s; this.y *= s; this.z *= s; } // s: number // return: LV3 div(s) { return new LV3(this.x / s, this.y / s, this.z / s); } // s: number idiv(s) { this.x /= s; this.y /= s; this.z /= s; } // o: LV3 // return: number dot(o) { return this.x * o.x + this.y * o.y + this.z * o.z; } // o: LV3 // return: LV3 cross(o) { return new LV3( this.y * o.z - this.z * o.y, this.z * o.x - this.x * o.z, this.x * o.y - this.y * o.x ); } // o: LV3 icross(o) { var x = this.x; var y = this.y; var z = this.z; this.x = y * o.z - z * o.y; this.y = z * o.x - x * o.z; this.z = x * o.y - y * o.x; } // o: LV3 // return: number dist(o) { var dx = this.x - o.x; var dy = this.y - o.y; var dz = this.z - o.z; return Math.sqrt(dx * dx + dy * dy + dz * dz); } // return: number mag() { return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); } // return: LV3 round() { return new LV3(Math.round(this.x), Math.round(this.y), Math.round(this.z)); } // return: LV3 floor() { return new LV3(Math.floor(this.x), Math.floor(this.y), Math.floor(this.z)); } iround() { this.x = Math.round(this.x); this.y = Math.round(this.y); this.z = Math.round(this.z); } ifloor() { this.x = Math.floor(this.x); this.y = Math.floor(this.y); this.z = Math.floor(this.z); } // return: LV3 unit() { var m = Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); return new LV3(this.x / m, this.y / m, this.z / m); } iunit() { var m = Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); this.x /= m; this.y /= m; this.z /= m; } } class LMat3 { // inp?: number[9] constructor(inp) { if(!inp) this.arr = [0, 0, 0, 0, 0, 0, 0, 0, 0]; else this.arr = inp; } // return: string toString() { return '|' + this.arr[0] + ',' + this.arr[1] + ',' + this.arr[2] + '|\n' + '|' + this.arr[3] + ',' + this.arr[4] + ',' + this.arr[5] + '|\n' + '|' + this.arr[6] + ',' + this.arr[7] + ',' + this.arr[8] + '|\n'; } // return: LMat3 copy() { return new LMat3(this.arr.slice()); } itranspose() { this.arr = [ this.arr[0], this.arr[3], this.arr[6], this.arr[1], this.arr[4], this.arr[7], this.arr[2], this.arr[5], this.arr[8] ]; } // return: LMat3 transpose() { return new LMat3([ this.arr[0], this.arr[3], this.arr[6], this.arr[1], this.arr[4], this.arr[7], this.arr[2], this.arr[5], this.arr[8] ]); } // m: LMat3 imult(m) { this.arr = [ this.arr[0] * m.arr[0] + this.arr[1] * m.arr[3] + this.arr[2] * m.arr[6], this.arr[0] * m.arr[1] + this.arr[1] * m.arr[4] + this.arr[2] * m.arr[7], this.arr[0] * m.arr[2] + this.arr[1] * m.arr[5] + this.arr[2] * m.arr[8], this.arr[3] * m.arr[0] + this.arr[4] * m.arr[3] + this.arr[5] * m.arr[6], this.arr[3] * m.arr[1] + this.arr[4] * m.arr[4] + this.arr[5] * m.arr[7], this.arr[3] * m.arr[2] + this.arr[4] * m.arr[5] + this.arr[5] * m.arr[8], this.arr[6] * m.arr[0] + this.arr[7] * m.arr[3] + this.arr[8] * m.arr[6], this.arr[6] * m.arr[1] + this.arr[7] * m.arr[4] + this.arr[8] * m.arr[7], this.arr[6] * m.arr[2] + this.arr[7] * m.arr[5] + this.arr[8] * m.arr[8], ]; } // m: LMat3 // return: LMat3 mult(m) { return new LMat3([ this.arr[0] * m.arr[0] + this.arr[1] * m.arr[3] + this.arr[2] * m.arr[6], this.arr[0] * m.arr[1] + this.arr[1] * m.arr[4] + this.arr[2] * m.arr[7], this.arr[0] * m.arr[2] + this.arr[1] * m.arr[5] + this.arr[2] * m.arr[8], this.arr[3] * m.arr[0] + this.arr[4] * m.arr[3] + this.arr[5] * m.arr[6], this.arr[3] * m.arr[1] + this.arr[4] * m.arr[4] + this.arr[5] * m.arr[7], this.arr[3] * m.arr[2] + this.arr[4] * m.arr[5] + this.arr[5] * m.arr[8], this.arr[6] * m.arr[0] + this.arr[7] * m.arr[3] + this.arr[8] * m.arr[6], this.arr[6] * m.arr[1] + this.arr[7] * m.arr[4] + this.arr[8] * m.arr[7], this.arr[6] * m.arr[2] + this.arr[7] * m.arr[5] + this.arr[8] * m.arr[8], ]); } // p: LV2 // return: LV2 multLV2(p) { return new LV2(p.x * this.arr[0] + p.y * this.arr[1] + 1 * this.arr[2], p.x * this.arr[3] + p.y * this.arr[4] + 1 * this.arr[5]); } // p: LV3 // return: LV3 multLV3(p) { return new LV3(p.x * this.arr[0] + p.y * this.arr[1] + p.z * this.arr[2], p.x * this.arr[3] + p.y * this.arr[4] + p.z * this.arr[5], p.x * this.arr[6] + p.y * this.arr[7] + p.z * this.arr[8]); } // return: LMat3 static zero() { return new LMat3(); } // return: LMat3 static identity() { return new LMat3([1, 0, 0, 0, 1, 0, 0, 0, 1]); } // scalar: number // return: LMat3 static scale(scalar) { return new LMat3([scalar, 0, 0, 0, scalar, 0, 0, 0, 1]); } // x: number // y: number // return: LMat3 static trans(x, y) { return new LMat3([1, 0, x, 0, 1, y, 0, 0, 1]); } // angle: number // return: LMat3 static rotate(angle) { angle *= 0.0174533; var cosine = Math.cos(angle); var sinus = Math.sin(angle); return new LMat3([cosine, -sinus, 0, sinus, cosine, 0, 0, 0, 1]); } // angle: number // return: LMat3 static rotateX(angle) { angle *= 0.0174533; var cosine = Math.cos(angle); var sinus = Math.sin(angle); return new LMat3([1, 0, 0, 0, cosine, -sinus, 0, sinus, cosine]); } // angle: number // return: LMat3 static rotateY(angle) { angle *= 0.0174533; var cosine = Math.cos(angle); var sinus = Math.sin(angle); return new LMat3([cosine, 0, sinus, 0, 1, 0, -sinus, 0, cosine]); } // angle: number // return: LMat3 static rotateZ(angle) { angle *= 0.0174533; var cosine = Math.cos(angle); var sinus = Math.sin(angle); return new LMat3([cosine, -sinue, 0, sinus, cosine, 0, 0, 0, 1]); } } class LMat4 { // inp?: [number * 16] constructor(inp) { if(inp === undefined) { this.arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; } else this.arr = inp; } // return: string toString() { return '|' + this.arr[0] + ',' + this.arr[1] + ',' + this.arr[2] + ',' + this.arr[3] + '|\n' + '|' + this.arr[4] + ',' + this.arr[5] + ',' + this.arr[6] + ',' + this.arr[7] + '|\n' + '|' + this.arr[8] + ',' + this.arr[9] + ',' + this.arr[10] + ',' + this.arr[11] + '|\n' + '|' + this.arr[12] + ',' + this.arr[13] + ',' + this.arr[14] + ',' + this.arr[15] + '|\n'; } // return: LMat4 copy() { return new LMat4(this.arr.slice()); } itranspose() { this.arr = [ this.arr[0], this.arr[4], this.arr[8], this.arr[12], this.arr[1], this.arr[5], this.arr[9], this.arr[13], this.arr[2], this.arr[6], this.arr[10], this.arr[14], this.arr[3], this.arr[7], this.arr[11], this.arr[15] ]; } // return: LMat4 transpose() { return new LMat4([ this.arr[0], this.arr[4], this.arr[8], this.arr[12], this.arr[1], this.arr[5], this.arr[9], this.arr[13], this.arr[2], this.arr[6], this.arr[10], this.arr[14], this.arr[3], this.arr[7], this.arr[11], this.arr[15] ]); } // m: LMat4 imult(m) { this.arr = [ this.arr[0]*m.arr[0] + this.arr[1]*m.arr[4] + this.arr[2]*m.arr[8] + this.arr[3]*m.arr[12], this.arr[0]*m.arr[1] + this.arr[1]*m.arr[5] + this.arr[2]*m.arr[9] + this.arr[3]*m.arr[13], this.arr[0]*m.arr[2] + this.arr[1]*m.arr[6] + this.arr[2]*m.arr[10] + this.arr[3]*m.arr[14], this.arr[0]*m.arr[3] + this.arr[1]*m.arr[7] + this.arr[2]*m.arr[11] + this.arr[3]*m.arr[15], this.arr[4]*m.arr[0] + this.arr[5]*m.arr[4] + this.arr[6]*m.arr[8] + this.arr[7]*m.arr[12], this.arr[4]*m.arr[1] + this.arr[5]*m.arr[5] + this.arr[6]*m.arr[9] + this.arr[7]*m.arr[13], this.arr[4]*m.arr[2] + this.arr[5]*m.arr[6] + this.arr[6]*m.arr[10] + this.arr[7]*m.arr[14], this.arr[4]*m.arr[3] + this.arr[5]*m.arr[7] + this.arr[6]*m.arr[11] + this.arr[7]*m.arr[15], this.arr[8]*m.arr[0] + this.arr[9]*m.arr[4] + this.arr[10]*m.arr[8] + this.arr[11]*m.arr[12], this.arr[8]*m.arr[1] + this.arr[9]*m.arr[5] + this.arr[10]*m.arr[9] + this.arr[11]*m.arr[13], this.arr[8]*m.arr[2] + this.arr[9]*m.arr[6] + this.arr[10]*m.arr[10] + this.arr[11]*m.arr[14], this.arr[8]*m.arr[3] + this.arr[9]*m.arr[7] + this.arr[10]*m.arr[11] + this.arr[11]*m.arr[15], this.arr[12]*m.arr[0] + this.arr[13]*m.arr[4] + this.arr[14]*m.arr[8] + this.arr[15]*m.arr[12], this.arr[12]*m.arr[1] + this.arr[13]*m.arr[5] + this.arr[14]*m.arr[9] + this.arr[15]*m.arr[13], this.arr[12]*m.arr[2] + this.arr[13]*m.arr[6] + this.arr[14]*m.arr[10] + this.arr[15]*m.arr[14], this.arr[12]*m.arr[3] + this.arr[13]*m.arr[7] + this.arr[14]*m.arr[11] + this.arr[15]*m.arr[15] ]; } // m: LMat4 // return: LMat4 mult(m) { return new LMat4([ this.arr[0]*m.arr[0] + this.arr[1]*m.arr[4] + this.arr[2]*m.arr[8] + this.arr[3]*m.arr[12], this.arr[0]*m.arr[1] + this.arr[1]*m.arr[5] + this.arr[2]*m.arr[9] + this.arr[3]*m.arr[13], this.arr[0]*m.arr[2] + this.arr[1]*m.arr[6] + this.arr[2]*m.arr[10] + this.arr[3]*m.arr[14], this.arr[0]*m.arr[3] + this.arr[1]*m.arr[7] + this.arr[2]*m.arr[11] + this.arr[3]*m.arr[15], this.arr[4]*m.arr[0] + this.arr[5]*m.arr[4] + this.arr[6]*m.arr[8] + this.arr[7]*m.arr[12], this.arr[4]*m.arr[1] + this.arr[5]*m.arr[5] + this.arr[6]*m.arr[9] + this.arr[7]*m.arr[13], this.arr[4]*m.arr[2] + this.arr[5]*m.arr[6] + this.arr[6]*m.arr[10] + this.arr[7]*m.arr[14], this.arr[4]*m.arr[3] + this.arr[5]*m.arr[7] + this.arr[6]*m.arr[11] + this.arr[7]*m.arr[15], this.arr[8]*m.arr[0] + this.arr[9]*m.arr[4] + this.arr[10]*m.arr[8] + this.arr[11]*m.arr[12], this.arr[8]*m.arr[1] + this.arr[9]*m.arr[5] + this.arr[10]*m.arr[9] + this.arr[11]*m.arr[13], this.arr[8]*m.arr[2] + this.arr[9]*m.arr[6] + this.arr[10]*m.arr[10] + this.arr[11]*m.arr[14], this.arr[8]*m.arr[3] + this.arr[9]*m.arr[7] + this.arr[10]*m.arr[11] + this.arr[11]*m.arr[15], this.arr[12]*m.arr[0] + this.arr[13]*m.arr[4] + this.arr[14]*m.arr[8] + this.arr[15]*m.arr[12], this.arr[12]*m.arr[1] + this.arr[13]*m.arr[5] + this.arr[14]*m.arr[9] + this.arr[15]*m.arr[13], this.arr[12]*m.arr[2] + this.arr[13]*m.arr[6] + this.arr[14]*m.arr[10] + this.arr[15]*m.arr[14], this.arr[12]*m.arr[3] + this.arr[13]*m.arr[7] + this.arr[14]*m.arr[11] + this.arr[15]*m.arr[15] ]); } // p: LV3 // return: LV3 multLV3(p) { return new LV3(p.x * this.arr[0] + p.y * this.arr[1] + p.z * this.arr[2] + this.arr[3], p.x * this.arr[4] + p.y * this.arr[5] + p.z * this.arr[6] + this.arr[7], p.x * this.arr[8] + p.y * this.arr[9] + p.z * this.arr[10] + this.arr[11]); } // scalar: number // return: LMat4 static scale(scalar) { return new LMat4([scalar, 0, 0, 0, 0, scalar, 0, 0, 0, 0, scalar, 0, 0, 0, 0, 1]); } // scalar: x // scalar: y // scalar: z // return: LMat4 static scaleXYZ(x, y, z) { return new LMat4([x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1]); } // x: number // y: number // z: number // return: LMat4 static trans(x, y, z) { return new LMat4([1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1]); } // angle: number // return: LMat4 static rotateX(angle) { angle *= 0.0174533; var cosine = Math.cos(angle); var sinus = Math.sin(angle); return new LMat4([1, 0, 0, 0, 0, cosine, -sinus, 0, 0, sinus, cosine, 0, 0, 0, 0, 1 ]); } // angle: number // return: LMat4 static rotateY(angle) { angle *= 0.0174533; var cosine = Math.cos(angle); var sinus = Math.sin(angle); return new LMat4([cosine, 0, sinus, 0, 0, 1, 0, 0, -sinus, 0, cosine, 0, 0, 0, 0, 1 ]); } // angle: number // return: LMat4 static rotateZ(angle) { angle *= 0.0174533; var cosine = Math.cos(angle); var sinus = Math.sin(angle); return new LMat4([cosine, -sinus, 0, 0, sinus, cosine, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ]); } // return: LMat4 static zero() { return new LMat4(); } // return: LMat4 static identity() { return new LMat4([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); } } const rawColor = chooseRandomColor(); const stairsColor = rawColor; const ballColor = getColorWithOpacity(rawColor); function chooseRandomColor() { const colorsList = [ [241, 54, 173], [54, 241, 122], [72, 205, 180], [205, 72, 98], [59, 146, 233], [244, 39, 89], ]; return colorsList[Math.floor(Math.random() * colorsList.length)]; } const canvas = document.querySelector('canvas'); let canvasSize = { width: 500, height: 500, drawScale: 1, dpi: 1, }; let drawMat = buildMatrix([ LMat3.trans(700, 700), ]); function setCanvasSettings() { const dpi = window.devicePixelRatio; const SSS = Math.min(window.innerWidth, window.innerHeight); const drawScale = (SSS * dpi) * 0.0037; const screen = { width: window.innerWidth * dpi, height: window.innerHeight * dpi, drawScale, styleWidth: window.innerWidth, styleHeight: window.innerHeight, dpi, }; drawMat = buildMatrix([ LMat3.trans(screen.width / 2, screen.height / 2), LMat3.scale(drawScale), ]); canvas.width = screen.width; canvas.height = screen.height; canvas.style.width = `${screen.styleWidth}px`; canvas.style.height = `${screen.styleHeight}px`; canvasSize = screen; } setCanvasSettings(); window.onresize = setCanvasSettings; const ctx = canvas.getContext('2d'); const originOfStairs = new LV2(-40, 40); const SS = 20; // stair size const stairs = [ new LV2(0, 0), new LV2(0, -SS), new LV2(SS, -SS), new LV2(SS, -SS*2), new LV2(SS*2, -SS*2), new LV2(SS*2, -SS*3), new LV2(SS*3, -SS*3), new LV2(SS*3, -SS*4), new LV2(SS*4, -SS*4), new LV2(SS*4, 0), ].map(x => x.add(originOfStairs)); function makeFunctionOfStairs(stairs) { let a = []; let last = 0; for (let i = 0; i < stairs.length; i++) { const j = (i+1) % stairs.length; const dist = stairs[i].dist(stairs[j]); a.push({ p1: stairs[i], p2: stairs[j], dist, cumulative: last + dist, }); last += dist; } const totalDistance = a.reduce((p, c) => p + c.dist, 0); a.forEach((x, i) => { x.t2 = x.cumulative / totalDistance; x.t1 = a[i-1] ? a[i-1].t2 : 0; x.t = 0; }); const fos = (t) => { if (t === 1) return a[0].p1.copy(); for (let i = 0; i < a.length; i++) { const u = a[i]; if (t >= u.t1 && t < u.t2) { const T = (t-u.t1) / (u.t2-u.t1); return u.p1.add(u.p2.sub(u.p1).scale(T)); } } return new LV2(0, 0); }; return fos; } const fos = makeFunctionOfStairs(stairs); let ball = { position: new LV2(originOfStairs.x, originOfStairs.y - SS*2.2), v: new LV3(-0.3, 0.35), reset() { this.position = new LV2(SS*4 + originOfStairs.x, originOfStairs.y - SS*5.2); this.v = new LV3(-0.3, -0.1); }, stairsMinX: 10000, stepIndices: [ [1, 2], [3, 4], [5, 6], [7, 8], ], init() { let stairsMn = stairs[1].x; stairs.forEach(s => { stairsMn = Math.min(s.x, stairsMn); }); this.stairsMinX = stairsMn; }, isWithinXAxis() { return this.position.x >= this.stairsMinX; }, integrate(t = 1) { this.position.iadd(this.v.scale(t)); this.v.iadd(new LV2(0, 0.045).scale(t)); }, getCurrentPlatformHeight() { const p = this.position; const steps = this.stepIndices; let y = undefined; for (let i = 0; i < steps.length; i++) { const ia = steps[i][0]; const ib = steps[i][1]; const sta = stairs[ia]; const stb = stairs[ib]; if(p.x >= sta.x && p.x <= stb.x) { y = sta.y; break; } } return y; }, reactToCollisions() { const p = this.position; const height = this.getCurrentPlatformHeight(); if (height !== undefined && p.y > height) { this.v.y = this.v.y * -0.70; const dist = Math.abs(height - p.y); p.y -= dist * 1.0001; } } }; ball.init(); ball.reset(); let state = { t: 0, p: new LV2(0, 0), type: 'fast', // fast | med | slow count: 0, first: 0, lastSwitched: false, switchUp() { this.first++; if (this.lastSwitched) return; this.count++; this.lastSwitched = true; if (this.count === 4) { this.count = 0; } this.type = 'slow'; }, switchDown() { this.type = this.count === 0 && this.first !== 0 ? 'med' : 'fast'; this.lastSwitched = false; }, getSpeed() { switch(this.type) { case 'slow': return 0.002; case 'fast': return 0.0175; case 'med': return 0.007; } }, }; function drawStairs(drawMat) { ctx.lineWidth = 1.4 * canvasSize.drawScale; let beh = 0.001; const offset = -0.008; const mt = state.t; let prev = fos(mmod(mt + offset)); const N = 400; for (let i = 0; i < N; i++) { let T = mmod((mt - i * beh) + offset); if (T < 0 || T > 1) continue; const n = fos(T); const opac = ((N - i) / N); drawLine(ctx, drawMat.multLV2(n), drawMat.multLV2(prev), getColorWithOpacity(stairsColor, opac)); prev = n; } } function integrateStairs(dt) { const last = state.p.copy(); state.p = fos(state.t); const p = state.p; const ballX = ball.position.x - 4; const movingRight = p.x > last.x; const movingUp = p.y < last.y; const pressingFwd = movingRight || movingUp; const reason2 = pressingFwd && Math.abs(p.x - ballX) < 15 && p.x >= ballX; if (reason2) state.switchUp(); else state.switchDown(); const vel = state.getSpeed(); state.t += vel * dt; state.t %= 1; } function integrate(dt) { // integrate ball if (!ball.isWithinXAxis()) { ball.reset(); } ball.reactToCollisions(); ball.integrate(dt); // intgrate stairs integrateStairs(dt); } let prevDelta = 0; function render(delta) { const dt = Math.min( (delta - prevDelta) * 0.065, 4, ); prevDelta = delta; if (dt > 2) { integrate(dt/2); integrate(dt/2); } else integrate(dt); // clear screen ctx.fillStyle = 'black'; ctx.fillRect(0, 0, canvasSize.width, canvasSize.height); // draw drawStairs(drawMat); drawCircle(ctx, drawMat.multLV2(ball.position), canvasSize.drawScale * 3, ballColor); requestAnimationFrame(render); } requestAnimationFrame(render); function mmod(t) { if (t < 0) return 1 + t; return t % 1; } function getColorWithOpacity(color, opacity = 1) { return `rgba(${color[0]}, ${color[1]}, ${color[2]}, ${opacity})`; } function drawLine(ctx, p1, p2, color = 'black') { ctx.beginPath(); ctx.strokeStyle = color; ctx.moveTo(p1.x, p1.y); ctx.lineTo(p2.x, p2.y); ctx.stroke(); ctx.closePath(); } function drawCircle(ctx, p, r, color = 'black') { ctx.beginPath(); ctx.fillStyle = color; ctx.arc(p.x, p.y, r, 0, 360); ctx.fill(); ctx.closePath(); } function drawPath(ctx, points, closePath = true) { ctx.beginPath(); ctx.moveTo(points[0].x, points[0].y); for (let i = 0; i < points.length; i++) { const p = points[i]; ctx.lineTo(p.x, p.y) } if (closePath) ctx.closePath(); ctx.stroke(); ctx.fill(); } function buildMatrix(arr) { return arr.reduce((p, c) => p.mult(c), LMat3.identity()); }
粒子
时间
文字
hover
canvas
3d
游戏
音乐
火焰
水波
轮播图
鼠标跟随
动画
css
加载动画
导航
菜单
按钮
滑块
tab
弹出层
统计图
svg
×
Close
在线代码下载提示
开通在线代码永久免费下载,需支付20jQ币
开通后,在线代码模块中所有代码可终身免费下!
您已开通在线代码永久免费下载,关闭提示框后,点下载代码可直接下载!
您已经开通过在线代码永久免费下载
对不起,您的jQ币不足!可通过发布资源 或
直接充值获取jQ币
取消
开通下载
<!doctype html> <html> <head> <meta charset="utf-8"> <title>canvas力场楼梯-jq22.com</title> <script src="https://www.jq22.com/jquery/jquery-1.10.2.js"></script> <style>
</style> </head> <body>
<script>
</script>
</body> </html>
2012-2021 jQuery插件库版权所有
jquery插件
|
jq22工具库
|
网页技术
|
广告合作
|
在线反馈
|
版权声明
沪ICP备13043785号-1
浙公网安备 33041102000314号