| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577 | $(function () {    // 初始化界面    function init() {        placeholderPic()        sd1('.sd1')        sd1('.sd2')        sd2('.sd3')        sd2('.sd4')        jz()        animate()    }    init()    // 自定义字体大小    function placeholderPic() {        w = document.documentElement.clientWidth / 80;        document.documentElement.style.fontSize = w + 'px';    }    // 闪电一,二    function sd1(ele) {        var width, height        var step = 0;        var canvas = document.createElement('canvas')        var ctx = canvas.getContext('2d')        var bg = [4, 10, 11]        document.querySelector(ele).appendChild(canvas)        setTimeout(() => {            var timeID = setInterval(() => {                pt1.x += 10;                if (pt1.x > width - 10) {                    clearInterval(timeID)                }            }, 60);        }, 1000)        var pt1        var pt2        window.addEventListener('resize', setup)        setup()        function setup() {            canvas.width = width = document.querySelector(ele).clientWidth            canvas.height = height = document.querySelector(ele).clientHeight            ctx.beginPath();            ctx.rect(0, 0, width, height)            ctx.fillStyle = `rgba(${bg[0]}, ${bg[1]}, ${bg[2]}, ${1})`            ctx.fill()            pt1 = { x: -20, y: height / 2 }//闪电起点            pt2 = { x: -20, y: height / 2 } //闪电终点            // draw()        }        setInterval(animate, 60)        // window.requestAnimationFrame(animate);        function blur(ctx, canvas, amt) {            ctx.filter = `blur(${amt}px)`            ctx.drawImage(canvas, 0, 0)            ctx.filter = 'none'        }        function fade(ctx, amt, width, height) {            ctx.beginPath();            ctx.rect(0, 0, width, height)            ctx.fillStyle = `rgba(${bg[0]}, ${bg[1]}, ${bg[2]}, ${amt})`            ctx.fill()        }        function animate() {            step++            blur(ctx, canvas, 1)            draw()            fade(ctx, 0.1, width, height)            // window.requestAnimationFrame(function(){animate()})        }        function draw() {            var iterations = [pt1, pt2]            var newiterations, i, j            for (i = 0; i < 8; i++) {                newiterations = [iterations[0]]                for (j = 1; j < iterations.length; j++) {                    newiterations.push(getRandMidpoint(iterations[j - 1], iterations[j], 200 / (i * i + 1)))                    newiterations.push(iterations[j])                }                iterations = newiterations.concat([])            }            ctx.beginPath();            ctx.moveTo(iterations[0].x, iterations[0].y);            ctx.lineWidth = 2;            ctx.strokeStyle = '#04e4c9';            // ctx.strokeStyle = `hsla(${Math.sin( step / 30) * 120 + 50},${90}%,${70}%,1)`            for (i = 1; i < iterations.length; i++) {                ctx.lineTo(iterations[i].x, iterations[i].y);            }            ctx.stroke()            ctx.closePath()        }        function getRandMidpoint(pa, pb, range) {            var a = Math.atan2(pb.y - pa.y, pb.x - pa.x) + Math.PI / 2            var half = { y: (pb.y - pa.y) / 2 + pa.y, x: (pb.x - pa.x) / 2 + pa.x }            var offset = Math.random() * range / 3 - range / 6  //这里控制闪电的抖动幅度            var ho = {                x: Math.cos(a) * offset + half.x,                y: Math.sin(a) * offset + half.y            }            return ho        }    }    //    //    //    // 闪电三,四    function sd2(ele) {        var width, height        var step = 0;        var canvas = document.createElement('canvas')        var ctx = canvas.getContext('2d')        var bg = [4, 10, 11]        document.querySelector(ele).appendChild(canvas)        setTimeout(() => {            var timeID = setInterval(() => {                pt1.x -= 10;                if (pt1.x < 10) {                    clearInterval(timeID)                }            }, 60);        }, 1000)        var pt1        var pt2        window.addEventListener('resize', setup)        setup()        function setup() {            canvas.width = width = document.querySelector(ele).clientWidth            canvas.height = height = document.querySelector(ele).clientHeight            ctx.beginPath();            ctx.rect(0, 0, width, height)            ctx.fillStyle = `rgba(${bg[0]}, ${bg[1]}, ${bg[2]}, ${1})`            ctx.fill()            pt1 = { x: width + 20, y: height / 2 }//闪电起点            pt2 = { x: width + 20, y: height / 2 } //闪电终点            // draw()        }        setInterval(animate, 60)        // window.requestAnimationFrame(animate);        function blur(ctx, canvas, amt) {            ctx.filter = `blur(${amt}px)`            ctx.drawImage(canvas, 0, 0)            ctx.filter = 'none'        }        function fade(ctx, amt, width, height) {            ctx.beginPath();            ctx.rect(0, 0, width, height)            ctx.fillStyle = `rgba(${bg[0]}, ${bg[1]}, ${bg[2]}, ${amt})`            ctx.fill()        }        function animate() {            step++            blur(ctx, canvas, 1)            draw()            fade(ctx, 0.1, width, height)            // window.requestAnimationFrame(function(){animate()})        }        function draw() {            var iterations = [pt1, pt2]            var newiterations, i, j            for (i = 0; i < 8; i++) {                newiterations = [iterations[0]]                for (j = 1; j < iterations.length; j++) {                    newiterations.push(getRandMidpoint(iterations[j - 1], iterations[j], 200 / (i * i + 1)))                    newiterations.push(iterations[j])                }                iterations = newiterations.concat([])            }            ctx.beginPath();            ctx.moveTo(iterations[0].x, iterations[0].y);            ctx.lineWidth = 2;            ctx.strokeStyle = '#04e4c9';            // ctx.strokeStyle = `hsla(${Math.sin( step / 30) * 120 + 50},${90}%,${70}%,1)`            for (i = 1; i < iterations.length; i++) {                ctx.lineTo(iterations[i].x, iterations[i].y);            }            ctx.stroke()            ctx.closePath()        }        function getRandMidpoint(pa, pb, range) {            var a = Math.atan2(pb.y - pa.y, pb.x - pa.x) + Math.PI / 2            var half = { y: (pb.y - pa.y) / 2 + pa.y, x: (pb.x - pa.x) / 2 + pa.x }            var offset = Math.random() * range / 3 - range / 6  //这里控制闪电的抖动幅度            var ho = {                x: Math.cos(a) * offset + half.x,                y: Math.sin(a) * offset + half.y            }            return ho        }    }    // 加载动画    function jz() {        $('.jz1 ul li').each((index, item) => {            item.style.opacity = 1 - index / 10;        })        setInterval(() => {            $('.jz1 ul li').each((index, item) => {                if (item.style.opacity == 0) {                    item.style.opacity = 1                }                item.style.opacity = parseFloat(item.style.opacity) - 0.1            })        }, 100)        $('.jz2 ul li').each((index, item) => {            item.style.opacity = 1 - index / 10;        })        setInterval(() => {            $('.jz2 ul li').each((index, item) => {                if (item.style.opacity == 0) {                    item.style.opacity = 1                }                item.style.opacity = parseFloat(item.style.opacity) - 0.1            })        }, 100)    }    // 中间背景动画    function animate() {        var App = {};        App.setup = function () {          // 创建canvas元素,并加入body中          var canvas = document.createElement('canvas');          this.filename = "spipa";          // 控制canvas幕布的大小          canvas.width = document.querySelector('.animate').clientWidth;          canvas.height = document.querySelector('.animate').clientHeight;          this.canvas = canvas;          document.querySelector('.animate').appendChild(canvas);          this.ctx = this.canvas.getContext('2d');          this.width = this.canvas.width;          this.height = this.canvas.height;          this.dataToImageRatio = 1;          this.ctx.imageSmoothingEnabled = false;          this.ctx.webkitImageSmoothingEnabled = false;          this.ctx.msImageSmoothingEnabled = false;          this.xC = this.width / 2;          this.yC = this.height / 2;              this.stepCount = 0;          this.particles = [];          this.lifespan = 1000;          this.popPerBirth = 1;          this.maxPop = 200;          this.birthFreq = 5;              // Build grid          this.gridSize = 8;// 运动坐标          this.gridSteps = Math.floor(1000 / this.gridSize);          this.grid = [];          var i = 0;          for (var xx = -500; xx < 500; xx += this.gridSize) {            for (var yy = -500; yy < 500; yy += this.gridSize) {              // 径向场,r的三角函数,最大值在r0附近              var r = Math.abs(xx) + Math.abs(yy),//Math.sqrt(xx*xx+yy*yy),                r0 = 3*w, //中间方形的大小                field;                  if (r < r0) field = 255 / r0 * r;              else if (r > r0) field = 255 - Math.min(255, (r - r0) / 2);                  this.grid.push({                x: xx,                y: yy,                busyAge: 0,                spotIndex: i,                isEdge: (xx == -500 ? 'left' :                  (xx == (-500 + this.gridSize * (this.gridSteps - 1)) ? 'right' :                    (yy == -500 ? 'top' :                      (yy == (-500 + this.gridSize * (this.gridSteps - 1)) ? 'bottom' :                        false                      )                    )                  )                ),                field: field              });              i++;            }          }          this.gridMaxIndex = i;                      this.initDraw();        };        App.evolve = function () {          var time1 = performance.now();              this.stepCount++;              // Increment all grid ages          this.grid.forEach(function (e) {            if (e.busyAge > 0) e.busyAge++;          });              if (this.stepCount % this.birthFreq == 0 && (this.particles.length + this.popPerBirth) < this.maxPop) {            this.birth();          }          App.move();          App.draw();              var time2 = performance.now();                    };        App.birth = function () {          var x, y;          var gridSpotIndex = Math.floor(Math.random() * this.gridMaxIndex),            gridSpot = this.grid[gridSpotIndex],            x = gridSpot.x, y = gridSpot.y;              var particle = {            hue: -10,// + Math.floor(50*Math.random()),            sat: 95,//30 + Math.floor(70*Math.random()),            lum: 20 + Math.floor(40 * Math.random()),            x: x, y: y,            xLast: x, yLast: y,            xSpeed: 0, ySpeed: 0,            age: 0,            ageSinceStuck: 0,            attractor: {              oldIndex: gridSpotIndex,              gridSpotIndex: gridSpotIndex,// Pop at random position on grid            },            name: 'seed-' + Math.ceil(10000000 * Math.random())          };          this.particles.push(particle);        };        App.kill = function (particleName) {          var newArray = _.reject(this.particles, function (seed) {            return (seed.name == particleName);          });          this.particles = _.cloneDeep(newArray);        };        App.move = function () {          for (var i = 0; i < this.particles.length; i++) {            // Get particle            var p = this.particles[i];                // Save last position            p.xLast = p.x; p.yLast = p.y;                // Attractor and corresponding grid spot            var index = p.attractor.gridSpotIndex,              gridSpot = this.grid[index];                // Maybe move attractor and with certain constraints            if (Math.random() < 0.5) {              // Move attractor              if (!gridSpot.isEdge) {                // Change particle's attractor grid spot and local move function's grid spot                var topIndex = index - 1,                  bottomIndex = index + 1,                  leftIndex = index - this.gridSteps,                  rightIndex = index + this.gridSteps,                  topSpot = this.grid[topIndex],                  bottomSpot = this.grid[bottomIndex],                  leftSpot = this.grid[leftIndex],                  rightSpot = this.grid[rightIndex];                    // Choose neighbour with highest field value (with some desobedience...)                var chaos = 30;                var maxFieldSpot = _.maxBy([topSpot, bottomSpot, leftSpot, rightSpot], function (e) {                  return e.field + chaos * Math.random()                });                    var potentialNewGridSpot = maxFieldSpot;                if (potentialNewGridSpot.busyAge == 0 || potentialNewGridSpot.busyAge > 15) {// Allow wall fading                  //if (potentialNewGridSpot.busyAge == 0) {// Spots busy forever                  // Ok it's free let's go there                  p.ageSinceStuck = 0;// Not stuck anymore yay                  p.attractor.oldIndex = index;                  p.attractor.gridSpotIndex = potentialNewGridSpot.spotIndex;                  gridSpot = potentialNewGridSpot;                  gridSpot.busyAge = 1;                } else p.ageSinceStuck++;                  } else p.ageSinceStuck++;                  if (p.ageSinceStuck == 10) this.kill(p.name);            }                // Spring attractor to center with viscosity            var k = 8, visc = 0.4;            var dx = p.x - gridSpot.x,              dy = p.y - gridSpot.y,              dist = Math.sqrt(dx * dx + dy * dy);                // Spring            var xAcc = -k * dx,              yAcc = -k * dy;                p.xSpeed += xAcc; p.ySpeed += yAcc;                // Calm the f*ck down            p.xSpeed *= visc; p.ySpeed *= visc;                // Store stuff in particle brain            p.speed = Math.sqrt(p.xSpeed * p.xSpeed + p.ySpeed * p.ySpeed);            p.dist = dist;                // Update position            p.x += 0.1 * p.xSpeed; p.y += 0.1 * p.ySpeed;                // Get older            p.age++;                // Kill if too old            if (p.age > this.lifespan) {              this.kill(p.name);              this.deathCount++;            }          }        };        App.initDraw = function () {          this.ctx.beginPath();          this.ctx.rect(0, 0, this.width, this.height);          this.ctx.fillStyle = 'transparent';          this.ctx.fill();          this.ctx.closePath();        };            App.draw = function () {          this.drawnInLastFrame = 0;          if (!this.particles.length) return false;              this.ctx.beginPath();          this.ctx.rect(0, 0, this.width, this.height);          // this.ctx.fillStyle = 'transparent';          this.ctx.fillStyle = 'rgba(12, 22, 25, 0.1)';          this.ctx.fill();          this.ctx.closePath();          for (var i = 0; i < this.particles.length; i++) {            // Draw particle            var p = this.particles[i];                var h, s, l, a;                h = p.hue + this.stepCount / 30;            s = p.sat;            l = p.lum;            a = 1;                var last = this.dataXYtoCanvasXY(p.xLast, p.yLast),              now = this.dataXYtoCanvasXY(p.x, p.y);            var attracSpot = this.grid[p.attractor.gridSpotIndex],              attracXY = this.dataXYtoCanvasXY(attracSpot.x, attracSpot.y);            var oldAttracSpot = this.grid[p.attractor.oldIndex],              oldAttracXY = this.dataXYtoCanvasXY(oldAttracSpot.x, oldAttracSpot.y);                this.ctx.beginPath();                this.ctx.strokeStyle = 'green';            this.ctx.fillStyle = 'hsla(' + h + ', ' + s + '%, ' + l + '%, ' + a + ')';                // Particle trail            this.ctx.moveTo(last.x, last.y);            this.ctx.lineTo(now.x, now.y);                this.ctx.lineWidth = 1.5 * this.dataToImageRatio;            this.ctx.stroke();            this.ctx.closePath();                // Attractor positions            this.ctx.beginPath();            this.ctx.lineWidth = 1.5 * this.dataToImageRatio;            this.ctx.moveTo(oldAttracXY.x, oldAttracXY.y);            this.ctx.lineTo(attracXY.x, attracXY.y);            this.ctx.arc(attracXY.x, attracXY.y, 1.5 * this.dataToImageRatio, 0, 2 * Math.PI, false);                //a /= 20;            this.ctx.strokeStyle = 'green';            this.ctx.fillStyle = 'green';            //this.ctx.stroke();            this.ctx.fill();                this.ctx.closePath();                // UI counter            this.drawnInLastFrame++;          }            };        App.dataXYtoCanvasXY = function (x, y) {          var zoom = 1.6;          var xx = this.xC + x * zoom * this.dataToImageRatio,            yy = this.yC + y * zoom * this.dataToImageRatio;              return { x: xx, y: yy };        };            setTimeout(function(){            console.log(1123)            App.setup();            App.draw();                  var frame = function () {              App.evolve();              requestAnimationFrame(frame);            };            frame();        },5000)                /**         * Some old util I use at times         *         * @param {Number} Xstart X value of the segment starting point         * @param {Number} Ystart Y value of the segment starting point         * @param {Number} Xtarget X value of the segment target point         * @param {Number} Ytarget Y value of the segment target point         * @param {Boolean} realOrWeb true if Real (Y towards top), false if Web (Y towards bottom)         * @returns {Number} Angle between 0 and 2PI         */        segmentAngleRad = function (Xstart, Ystart, Xtarget, Ytarget, realOrWeb) {          var result;// Will range between 0 and 2PI          if (Xstart == Xtarget) {            if (Ystart == Ytarget) {              result = 0;            } else if (Ystart < Ytarget) {              result = Math.PI / 2;            } else if (Ystart > Ytarget) {              result = 3 * Math.PI / 2;            } else { }          } else if (Xstart < Xtarget) {            result = Math.atan((Ytarget - Ystart) / (Xtarget - Xstart));          } else if (Xstart > Xtarget) {            result = Math.PI + Math.atan((Ytarget - Ystart) / (Xtarget - Xstart));          }              result = (result + 2 * Math.PI) % (2 * Math.PI);              if (!realOrWeb) {            result = 2 * Math.PI - result;          }              return result;        }    }})
 |