canvas实现一个疯狂的迷宫动画效果代码
代码语言:html
所属分类:动画
代码描述:canvas实现一个疯狂的迷宫动画效果代码,点击可切换新的迷宫
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> body { font-family: Arial, Helvetica, "Liberation Sans", FreeSans, sans-serif; background-color: #000; margin: 0; padding: 0; border-width: 0; cursor: pointer; } </style> </head> <body > <script> "use strict"; window.addEventListener("load", function () { let canv, ctx; // canvas and context let maxx, maxy; // canvas dimensions let lSegment, nbx, nby, offsx, offsy, posx, posy; let segs, nbRot, maxNbRot; let grid; let balls; const wSegment = 5; // for animation let messages; // shortcuts for Math. const mrandom = Math.random; const mfloor = Math.floor; const mround = Math.round; const mceil = Math.ceil; const mabs = Math.abs; const mmin = Math.min; const mmax = Math.max; const mPI = Math.PI; const mPIS2 = Math.PI / 2; const mPIS3 = Math.PI / 3; const m2PI = Math.PI * 2; const m2PIS3 = Math.PI * 2 / 3; const msin = Math.sin; const mcos = Math.cos; const matan2 = Math.atan2; const mhypot = Math.hypot; const msqrt = Math.sqrt; const rac3 = msqrt(3); const rac3s2 = rac3 / 2; //------------------------------------------------------------------------ function alea(mini, maxi) { // random number in given range if (typeof maxi == "undefined") return mini * mrandom(); // range 0..mini return mini + mrandom() * (maxi - mini); // range mini..maxi } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - function intAlea(mini, maxi) { // random integer in given range (mini..maxi - 1 or 0..mini - 1) // if (typeof maxi == "undefined") return mfloor(mini * mrandom()); // range 0..mini - 1 return mini + mfloor(mrandom() * (maxi - mini)); // range mini .. maxi - 1 } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - function arrayShuffle(array) { /* randomly changes the order of items in an array only the order is modified, not the elements */ let k1, temp; for (let k = array.length - 1; k >= 1; --k) { k1 = intAlea(0, k + 1); temp = array[k]; array[k] = array[k1]; array[k1] = temp; } // for k return array; } // arrayShuffle //------------------------------------------------------------------------ class EdgeLine { constructor(square, side) { this.s0 = { square, side }; this.p0 = { x: posx[square.kx + [0, 1, 0, 0][side]], y: posy[square.ky + [0, 0, 1, 0][side]] }; this.p1 = { x: posx[square.kx + [1, 1, 1, 0][side]], y: posy[square.ky + [0, 1, 1, 1][side]] }; // prevent segments from coming on outer edges of grid if (square.ky == 0 && side == 0) this.occupied = true; // top edge if (square.kx == nbx - 1 && side == 1) this.occupied = true; // right edge if (square.ky == nby - 1 && side == 2) this.occupied = true; // bottom edge if (square.kx == 0 && side == 3) this.occupied = true; // left edge }} // class EdgeLine //------------------------------------------------------------------------ class Segment { constructor() { let kx, ky, kedge; // pick random edge of random square - unouccupied do { kx = intAlea(nbx); ky = intAlea(nby); kedge = intAlea(4); } while (grid[ky][kx].edges[kedge].edgeLine.occupied); this.edgeLine = grid[ky][kx].edges[kedge].edgeLine; this.edgeLine.occupied = true; this.color = alea(1) > 0.05 ? "white" : `hsl(${intAlea(360)} 100% 50%)`; } // constructor rotate() { /* initiates a rotation returns true if successful, false if failed (rotation was not possible or already in progress) */ if (this.resting) return false; if (this.rotating) return false; let poss = [0, 1, 2, 3]; this.tInit = performance.now(); this.duration = alea(600, 800); otherPoss: while (poss.length) { let choice = poss.splice(intAlea(poss.length), 1)[0]; let ssquare = choice & 2 ? this.edgeLine.s0 : this.edgeLine.s1; // choice of the square the segment will cross if (ssquare.square.occupied) continue otherPoss; // chosen square already occupied let dSide = choice & 1 ? 1 : 3; // choice of rotation (1 means ccw, 3 = -1 % 4 means cw) let nextSide = (ssquare.side + dSide) % 4; if (ssquare.square.edges[nextSide].edgeLine.occupied) continue otherPoss; // target side already occupied // found good move ssquare.square.edges[nextSide].edgeLine.occupied = true; // will occupy next side let kcenter = (ssquare.side + (choice & 1)) % 4; .........完整代码请登录后点击上方下载按钮下载查看
网友评论0