魔方js小游戏

代码语言:html

所属分类:游戏

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>The Cube</title>
    <meta name="viewport" content="width=device-width,height=device-height,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0">
    <style>
        *,*:before,*:after{-webkit-user-select:none;-moz-user-select:none;user-select:none;box-sizing:border-box;cursor:inherit;margin:0;padding:0;outline:0;font-size:inherit;font-family:inherit;font-weight:inherit;font-style:inherit;text-transform:uppercase}*:focus{outline:0}html{-webkit-tap-highlight-color:transparent;-webkit-text-size-adjust:100%;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;overflow:hidden;height:100%}body{font-family:bungeefont,sans-serif;font-weight:400;font-style:normal;line-height:1;cursor:default;overflow:hidden;height:100%;font-size:5rem}.icon{display:inline-block;font-size:inherit;overflow:visible;vertical-align:-.125em;preserveaspectratio:none}.range{position:relative;width:14em;z-index:1;opacity:0}.range:not(:last-child){margin-bottom:2em}.range__label{position:relative;font-size:.9em;line-height:.75em;padding-bottom:.5em;z-index:2}.range__track{position:relative;height:1em;margin-left:.5em;margin-right:.5em;z-index:3}.range__track-line{position:absolute;background:rgba(0,0,0,.2);height:2px;top:50%;margin-top:-1px;left:-.5em;right:-.5em;transform-origin:left center}.range__handle{position:absolute;width:0;height:0;top:50%;left:0;cursor:pointer;z-index:1}.range__handle div{transition:background 500ms ease;position:absolute;left:0;top:0;width:.9em;height:.9em;border-radius:.2em;margin-left:-.45em;margin-top:-.45em;background:#41aac8;border-bottom:2px solid rgba(0,0,0,.2)}.range.is-active .range__handle div{transform:scale(1.25)}.range__handle:after{content:"";position:absolute;left:0;top:0;width:3em;height:3em;margin-left:-1.5em;margin-top:-1.5em}.range__list{display:flex;flex-flow:row nowrap;justify-content:space-between;position:relative;padding-top:.5em;font-size:.55em;color:rgba(0,0,0,.5);z-index:1}.stats{position:relative;width:14em;z-index:1;display:flex;justify-content:space-between;opacity:0}.stats:not(:last-child){margin-bottom:1.5em}.stats i{display:inline-block;color:rgba(0,0,0,.5);font-size:.9em}.stats b{display:inline-block;font-size:.9em}.text{position:absolute;left:0;right:0;text-align:center;line-height:.75;perspective:100rem;opacity:0}.text i{display:inline-block;opacity:0;white-space:pre-wrap}.text--title{bottom:75%;font-size:4.4em;height:1.2em}.text--title span{display:block}.text--title span:first-child{font-size:.5em;margin-bottom:.2em}.text--note{top:87%;font-size:1em}.text--timer{bottom:78%;font-size:3.5em;line-height:1}.text--complete,.text--best-time{font-size:1.5em;top:83%;line-height:1em}.btn{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;border-radius:0;border-width:0;position:absolute;pointer-events:none;font-size:1.2em;color:rgba(0,0,0,.25);opacity:0}.btn:after{position:absolute;content:"";width:3em;height:3em;left:50%;top:50%;margin-left:-1.5em;margin-top:-1.5em;border-radius:100%}.btn--bl{bottom:.8em;left:.8em}.btn--br{bottom:.8em;right:.8em}.btn--bc{bottom:.8em;left:calc(50% - 0.5em)}.btn--pwa{transition:color 500ms ease;color:inherit;height:1em}.btn--pwa svg{font-size:.6em;margin:.35em 0}.btn svg{display:block}.ui{pointer-events:none;color:#070d15}.ui,.ui__background,.ui__game,.ui__texts,.ui__prefs,.ui__stats,.ui__buttons{position:absolute;top:0;left:0;width:100%;height:100%;overflow:hidden}.ui__background{z-index:1;transition:background 500ms ease;background:#d1d5db}.ui__background:after{position:absolute;top:0;left:0;width:100%;height:100%;content:"";background-image:linear-gradient(to bottom,white 50%,rgba(255,255,255,0) 100%)}.ui__game{pointer-events:all;z-index:2}.ui__game canvas{display:block;width:100%;height:100%}.ui__texts{z-index:3}.ui__prefs,.ui__stats{display:flex;flex-flow:column nowrap;justify-content:center;align-items:center;overflow:hidden;z-index:4}.ui__buttons{z-index:5}.ui__notification{transition:transform 500ms ease,opacity 500ms ease;font-family:sans-serif;position:absolute;left:50%;bottom:.6em;padding:.6em;margin-left:-9.4em;width:18.8em;z-index:6;background:rgba(17,17,17,.9);border-radius:.8em;display:flex;align-items:center;flex-flow:row nowrap;color:#fff;user-select:none;opacity:0;pointer-events:none;transform:translateY(100%)}.ui__notification.is-active{opacity:1;pointer-events:all;transform:none}.ui__notification *{text-transform:none}.ui__notification-icon{background-size:100% 100%;left:.6em;top:.6em;width:2.8em;height:2.8em;border-radius:.5em;background:#fff;margin-right:.6em;display:block}.ui__notification-text{font-size:.75em;line-height:1.4em}.ui__notification-text .icon{color:#4f82fd;font-size:1.1em}.ui__notification-text b{font-weight:700}.btn--stats{visibility:hidden}
    </style>
</head>
<body>
    <div class="ui">
        <div class="ui__background"></div>
        <div class="ui__game"></div>
        <div class="ui__texts">
            <h1 class="text text--title">
                <span>THE</span>
                <span>CUBE</span>
            </h1>
            <div class="text text--note">
                双击即可开始
            </div>
            <div class="text text--timer">
                0:00
            </div>
            <div class="text text--complete">
                <span>Complete!</span>
            </div>
            <div class="text text--best-time">
                <icon trophy></icon>
                <span>Best Time!</span>
            </div>
        </div>
        <div class="ui__prefs">
            <range name="flip" title="Flip Type" list="Swift&nbsp;,Smooth,Bounce"></range>
            <range name="scramble" title="Scramble Length" list="20,25,30"></range>
            <range name="fov" title="Camera Angle" list="Ortographic,Perspective"></range>
            <range name="theme" title="Color Scheme" list="Cube,Erno,Dust,Camo,Rain"></range>
        </div>
        <div class="ui__stats">
            <div class="stats" name="total-solves">
                <i>Total solves:</i><b>-</b>
            </div>
            <div class="stats" name="best-time">
                <i>Best time:</i><b>-</b>
            </div>
            <div class="stats" name="worst-time">
                <i>Worst time:</i><b>-</b>
            </div>
            <div class="stats" name="average-5">
                <i>Average of 5:</i><b>-</b>
            </div>
            <div class="stats" name="average-12">
                <i>Average of 12:</i><b>-</b>
            </div>
            <div class="stats" name="average-25">
                <i>Average of 25:</i><b>-</b>
            </div>
        </div>
        <div class="ui__buttons">
            <button class="btn btn--bl btn--stats">
                <icon trophy></icon>
            </button>
            <button class="btn btn--bl btn--prefs">
                <icon settings></icon>
            </button>
            <button class="btn btn--bl btn--back">
                <icon back></icon>
            </button>
            <a href="#" class="btn btn--br btn--pwa">
            </button>
        </div>
    </div>
    <script src='http://repo.bfw.wiki/bfwrepo/js/three.js'></script>
    <script >
        const animationEngine=(()=>{let uniqueID=0;class AnimationEngine{constructor(){this.ids=[];this.animations={};this.update=this.update.bind(this);this.raf=0;this.time=0;}
update(){const now=performance.now();const delta=now-this.time;this.time=now;let i=this.ids.length;this.raf=i?requestAnimationFrame(this.update):0;while(i--)
this.animations[this.ids[i]]&&this.animations[this.ids[i]].update(delta);}
add(animation){animation.id=uniqueID++;this.ids.push(animation.id);this.animations[animation.id]=animation;if(this.raf!==0)return;this.time=performance.now();this.raf=requestAnimationFrame(this.update);}
remove(animation){const index=this.ids.indexOf(animation.id);if(index<0)return;this.ids.splice(index,1);delete this.animations[animation.id];animation=null;}}
return new AnimationEngine();})();class Animation{constructor(start){if(start===true)this.start();}
start(){animationEngine.add(this);}
stop(){animationEngine.remove(this);}
update(delta){}}
class World extends Animation{constructor(game){super(true);this.game=game;this.container=this.game.dom.game;this.scene=new THREE.Scene();this.renderer=new THREE.WebGLRenderer({antialias:true,alpha:true});this.renderer.setPixelRatio(window.devicePixelRatio);this.container.appendChild(this.renderer.domElement);this.camera=new THREE.PerspectiveCamera(2,1,0.1,10000);this.stage={width:2,height:3};this.fov=10;this.createLights();this.onResize=[];this.resize();window.addEventListener('resize',()=>this.resize(),false);}
update(){this.renderer.render(this.scene,this.camera);}
resize(){this.width=this.container.offsetWidth;this.height=this.container.offsetHeight;this.renderer.setSize(this.width,this.height);this.camera.fov=this.fov;this.camera.aspect=this.width/this.height;const aspect=this.stage.width/this.stage.height;const fovRad=this.fov*THREE.Math.DEG2RAD;let distance=(aspect<this.camera.aspect)?(this.stage.height/2)/Math.tan(fovRad/2):(this.stage.width/this.camera.aspect)/(2*Math.tan(fovRad/2));distance*=0.5;this.camera.position.set(distance,distance,distance);this.camera.lookAt(this.scene.position);this.camera.updateProjectionMatrix();const docFontSize=(aspect<this.camera.aspect)?(this.height/100)*aspect:this.width/100;document.documentElement.style.fontSize=docFontSize+'px';if(this.onResize)this.onResize.forEach(cb=>cb());}
createLights(){this.lights={holder:new THREE.Object3D,ambient:new THREE.AmbientLight(0xffffff,0.69),front:new THREE.DirectionalLight(0xffffff,0.36),back:new THREE.DirectionalLight(0xffffff,0.19),};this.lights.front.position.set(1.5,5,3);this.lights.back.position.set(-1.5,-5,-3);this.lights.holder.add(this.lights.ambient);this.lights.holder.add(this.lights.front);this.lights.holder.add(this.lights.back);this.scene.add(this.lights.holder);}
enableShadows(){this.renderer.shadowMap.enabled=true;this.renderer.shadowMap.type=THREE.PCFSoftShadowMap;this.lights.front.castShadow=true;this.lights.front.shadow.mapSize.width=512;this.lights.front.shadow.mapSize.height=512;var d=1.5;this.lights.front.shadow.camera.left=-d;this.lights.front.shadow.camera.right=d;this.lights.front.shadow.camera.top=d;this.lights.front.shadow.camera.bottom=-d;this.lights.front.shadow.camera.near=1;this.lights.front.shadow.camera.far=9;this.game.cube.holder.traverse(node=>{if(node instanceof THREE.Mesh){node.castShadow=true;node.receiveShadow=true;}});}}
function RoundedBoxGeometry(size,radius,radiusSegments){THREE.BufferGeometry.call(this);this.type='RoundedBoxGeometry';radiusSegments=!isNaN(radiusSegments)?Math.max(1,Math.floor(radiusSegments)):1;var width,height,depth;width=height=depth=size;radius=size*radius;radius=Math.min(radius,Math.min(width,Math.min(height,Math.min(depth)))/2);var edgeHalfWidth=width/2-radius;var edgeHalfHeight=height/2-radius;var edgeHalfDepth=depth/2-radius;this.parameters={width:width,height:height,depth:depth,radius:radius,radiusSegments:radiusSegments};var rs1=radiusSegments+1;var totalVertexCount=(rs1*radiusSegments+1)<<3;var positions=new THREE.BufferAttribute(new Float32Array(totalVertexCount*3),3);var normals=new THREE.BufferAttribute(new Float32Array(totalVertexCount*3),3);var
cornerVerts=[],cornerNormals=[],normal=new THREE.Vector3(),vertex=new THREE.Vector3(),vertexPool=[],normalPool=[],indices=[];var
lastVertex=rs1*radiusSegments,cornerVertNumber=rs1*radiusSegments+1;doVertices();doFaces();doCorners();doHeightEdges();doWidthEdges();doDepthEdges();function doVertices(){var cornerLayout=[new THREE.Vector3(1,1,1),new THREE.Vector3(1,1,-1),new THREE.Vector3(-1,1,-1),new THREE.Vector3(-1,1,1),new THREE.Vector3(1,-1,1),new THREE.Vector3(1,-1,-1),new THREE.Vector3(-1,-1,-1),new THREE.Vector3(-1,-1,1)];for(var j=0;j<8;j++){cornerVerts.push([]);cornerNormals.push([]);}
var PIhalf=Math.PI/2;var cornerOffset=new THREE.Vector3(edgeHalfWidth,edgeHalfHeight,edgeHalfDepth);for(var y=0;y<=radiusSegments;y++){var v=y/radiusSegments;var va=v*PIhalf;var cosVa=Math.cos(va);var sinVa=Math.sin(va);if(y==radiusSegments){vertex.set(0,1,0);var vert=vertex.clone().multiplyScalar(radius).add(cornerOffset);cornerVerts[0].push(vert);vertexPool.push(vert);var norm=vertex.clone();cornerNormals[0].push(norm);normalPool.push(norm);continue;}
for(var x=0;x<=radiusSegments;x++){var u=x/radiusSegments;var ha=u*PIhalf;vertex.x=cosVa*Math.cos(ha);vertex.y=sinVa;vertex.z=cosVa*Math.sin(ha);var vert=vertex.clone().multiplyScalar(radius).add(cornerOffset);cornerVerts[0].push(vert);vertexPool.push(vert);var norm=vertex.clone().normalize();cornerNormals[0].push(norm);normalPool.push(norm);}}
for(var i=1;i<8;i++){for(var j=0;j<cornerVerts[0].length;j++){var vert=cornerVerts[0][j].clone().multiply(cornerLayout[i]);cornerVerts[i].push(vert);vertexPool.push(vert);var norm=cornerNormals[0][j].clone().multiply(cornerLayout[i]);cornerNormals[i].push(norm);normalPool.push(norm);}}}
function doCorners(){var flips=[true,false,true,false,false,true,false,true];var lastRowOffset=rs1*(radiusSegments-1);for(var i=0;i<8;i++){var cornerOffset=cornerVertNumber*i;for(var v=0;v<radiusSegments-1;v++){var r1=v*rs1;var r2=(v+1)*rs1;for(var u=0;u<radiusSegments;u++){var u1=u+1;var a=cornerOffset+r1+u;var b=cornerOffset+r1+u1;var c=cornerOffset+r2+u;var d=cornerOffset+r2+u1;if(!flips[i]){indices.push(a);indices.push(b);indices.push(c);indices.push(b);indices.push(d);indices.push(c);}else{indices.push(a);indices.push(c);indices.push(b);indices.push(b);indices.push(c);indices.push(d);}}}
for(var u=0;u<radiusSegments;u++){var a=cornerOffset+lastRowOffset+u;var b=cornerOffset+lastRowOffset+u+1;var c=cornerOffset+lastVertex;if(!flips[i]){indices.push(a);indices.push(b);indices.push(c);}else{indices.push(a);indices.push(c);indices.push(b);}}}}
function doFaces(){var a=lastVertex;var b=lastVertex+cornerVertNumber;var c=lastVertex+cornerVertNumber*2;var d=lastVertex+cornerVertNumber*3;indices.push(a);indices.push(b);indices.push(c);indices.push(a);indices.push(c);indices.push(d);a=lastVertex+cornerVertNumber*4;b=lastVertex+cornerVertNumber*5;c=lastVertex+cornerVertNumber*6;d=lastVertex+cornerVertNumber*7;indices.push(a);indices.push(c);indices.push(b);indices.push(a);indices.push(d);indices.push(c);a=0;b=cornerVertNumber;c=cornerVertNumber*4;d=cornerVertNumber*5;indices.push(a);indices.push(c);indices.push(b);indices.push(b);indices.push(c);indices.push(d);a=cornerVertNumber*2;b=cornerVertNumber*3;c=cornerVertNumber*6;d=cornerVertNumber*7;indices.push(a);indices.push(c);indices.push(b);indices.push(b);indices.push(c);indices.push(d);a=radiusSegments;b=radiusSegments+cornerVertNumber*3;c=radiusSegments+cornerVertNumber*4;d=radiusSegments+cornerVertNumber*7;indices.push(a);indices.push(b);indices.push(c);indices.push(b);indices.push(d);indices.push(c);a=radiusSegments+cornerVertNumber;b=radiusSegments+cornerVertNumber*2;c=radiusSegments+cornerVertNumber*5;d=radiusSegments+cornerVertNumber*6;indices.push(a);indices.push(c);indices.push(b);indices.push(b);indices.push(c);indices.push(d);}
function doHeightEdges(){for(var i=0;i<4;i++){var cOffset=i*cornerVertNumber;var cRowOffset=4*cornerVertNumber+cOffset;var needsFlip=i&1===1;for(var u=0;u<radiusSegments;u++){var u1=u+1;var a=cOffset+u;var b=cOffset+u1;var c=cRowOffset+u;var d=cRowOffset+u1;if(!needsFlip){indices.push(a);indices.push(b);indices.push(c);indices.push(b);indices.push(d);indices.push(c);}else{indices.push(a);indices.push(c);indices.push(b);indices.push(b);indices.push(c);indices.push(d);}}}}
function doDepthEdges(){var cStarts=[0,2,4,6];var cEnds=[1,3,5,7];for(var i=0;i<4;i++){var cStart=cornerVertNumber*cStarts[i];var cEnd=cornerVertNumber*cEnds[i];var needsFlip=1>=i;for(var u=0;u<radiusSegments;u++){var urs1=u*rs1;var u1rs1=(u+1)*rs1;var a=cStart+urs1;var b=cStart+u1rs1;var c=cEnd+urs1;var d=cEnd+u1rs1;if(needsFlip){indices.push(a);indices.push(c);indices.push(b);indices.push(b);indices.push(c);indices.push(d);}else{indices.push(a);indices.push(b);indices.push(c);indices.push(b);indices.push(d);indices.push(c);}}}}
function doWidthEdges(){var end=radiusSegments-1;var cStarts=[0,1,4,5];var cEnds=[3,2,7,6];var needsFlip=[0,1,1,0];for(var i=0;i<4;i++){var cStart=cStarts[i]*cornerVertNumber;var cEnd=cEnds[i]*cornerVertNumber;for(var u=0;u<=end;u++){var a=cStart+radiusSegments+u*rs1;var b=cStart+(u!=end?radiusSegments+(u+1)*rs1:cornerVertNumber-1);var c=cEnd+radiusSegments+u*rs1;var d=cEnd+(u!=end?radiusSegments+(u+1)*rs1:cornerVertNumber-1);if(!needsFlip[i]){indices.push(a);indices.push(b);indices.push(c);indices.push(b);indices.push(d);indices.push(c);}else{indices.push(a);indices.push(c);indices.push(b);indices.push(b);indices.push(c);indices.push(d);}}}}
var index=0;for(var i=0;i<vertexPool.length;i++){positions.setXYZ(index,vertexPool[i].x,vertexPool[i].y,vertexPool[i].z);normals.setXYZ(index,normalPool[i].x,normalPool[i].y,normalPool[i].z);index++;}
this.setIndex(new THREE.BufferAttribute(new Uint16Array(indices),1));this.addAttribute('position',positions);this.addAttribute('normal',normals);}
RoundedBoxGeometry.prototype=Object.create(THREE.BufferGeometry.prototype);RoundedBoxGeometry.constructor=RoundedBoxGeometry;function RoundedPlaneGeometry(size,radius,depth){var x,y,width,height;x=y=-size/2;width=height=size;radius=size*radius;const shape=new THREE.Shape();shape.moveTo(x,y+radius);shape.lineTo(x,y+height-radius);shape.quadraticCurveTo(x,y+height,x+radius,y+height);shape.lineTo(x+width-radius,y+height);shape.quadraticCurveTo(x+width,y+height,x+width,y+height-radius);shape.lineTo(x+width,y+radius);shape.quadraticCurveTo(x+width,y,x+width-radius,y);shape.lineTo(x+radius,y);shape.quadraticCurveTo(x,y,x,y+radius);const geometry=new THREE.ExtrudeBufferGeometry(shape,{depth:depth,bevelEnabled:false,curveSegments:3});return geometry;}
class Cube{constructor(game){this.game=game;this.geometry={pieceSize:1/3,pieceCornerRadius:0.12,edgeCornerRoundness:0.15,edgeScale:0.82,edgeDepth:0.01,};this.holder=new THREE.Object3D();this.object=new THREE.Object3D();this.animator=new THREE.Object3D();this.holder.add(this.animator);this.animator.add(this.object);this.cubes=[];this.generatePositions();this.generateModel();this.pieces.forEach(piece=>{this.cubes.push(piece.userData.cube);this.object.add(piece);});this.holder.traverse(node=>{if(node.frustumCulled)node.frustumCulled=false;});this.game.world.scene.add(this.holder);}
reset(){this.game.controls.edges.rotation.set(0,0,0);this.holder.rotation.set(0,0,0);this.object.rotation.set(0,0,0);this.animator.rotation.set(0,0,0);this.pieces.forEach(piece=>{piece.position.copy(piece.userData.start.position);piece.rotation.copy(piece.userData.start.rotation);});}
generatePositions(){let x,y,z;this.positions=[];for(x=0;x<3;x++){for(y=0;y<3;y++){for(z=0;z<3;z++){let position=new THREE.Vector3(x-1,y-1,z-1);let edges=[];if(x==0)edges.push(0);if(x==2)edges.push(1);if(y==0)edges.push(2);if(y==2)edges.push(3);if(z==0)edges.push(4);if(z==2)edges.push(5);position.edges=edges;this.positions.push(position);}}}}
generateModel(){this.pieces=[];this.edges=[];const pieceSize=1/3;const mainMaterial=new THREE.MeshLambertMaterial();const pieceMesh=new THREE.Mesh(new RoundedBoxGeometry(pieceSize,this.geometry.pieceCornerRadius,3),mainMaterial.clone());const edgeGeometry=RoundedPlaneGeometry(pieceSize,this.geometry.edgeCornerRoundness,this.geometry.edgeDepth);this.positions.forEach((position,index)=>{const piece=new THREE.Object3D();const pieceCube=pieceMesh.clone();const pieceEdges=[];piece.position.copy(position.clone().divideScalar(3));piece.add(pieceCube);piece.name=index;piece.edgesName='';position.edges.forEach(position=>{const edge=new THREE.Mesh(edgeGeometry,mainMaterial.clone());const name=['L','R','D','U','B','F'][position];const distance=pieceSize/2;edge.position.set(distance*[-1,1,0,0,0,0][position],distance*[0,0,-1,1,0,0][position],distance*[0,0,0,0,-1,1][position]);edge.rotation.set(Math.PI/2*[0,0,1,-1,0,0][position],Math.PI/2*[-1,1,0,0,2,0][position],0);edge.scale.set(this.geometry.edgeScale,this.geometry.edgeScale,this.geometry.edgeScale);edge.name=name;piece.add(edge);pieceEdges.push(name);this.edges.push(edge);});piece.userData.edges=pieceEdges;piece.userData.cube=pieceCube;piece.userData.start={position:piece.position.clone(),rotation:piece.rotation.clone(),};this.pieces.push(piece);});}}
const Easing={Power:{In:power=>{power=Math.round(power||1);return t=>Math.pow(t,power);},Out:power=>{power=Math.round(power||1);return t=>1-Math.abs(Math.pow(t-1,power));},InOut:power=>{power=Math.round(power||1);return t=>(t<0.5)?Math.pow(t*2,power)/2:(1-Math.abs(Math.pow((t*2-1)-1,power)))/2+0.5;},},Sine:{In:()=>t=>1+Math.sin(Math.PI/2*t-Math.PI/2),Out:()=>t=>Math.sin(Math.PI/2*t),InOut:()=>t=>(1+Math.sin(Math.PI*t-Math.PI/2))/2,},Back:{Out:s=>{s=s||1.70158;return t=>{return(t-=1)*t*((s+1)*t+s)+1;};},In:s=>{s=s||1.70158;return t=>{return t*t*((s+1)*t-s);};}},Elastic:{Out:(amplitude,period)=>{let PI2=Math.PI*2;let p1=(amplitude>=1)?amplitude:1;let p2=(period||0.3)/(amplitude<1?amplitude:1);let p3=p2/PI2*(Math.asin(1/p1)||0);p2=PI2/p2;return t=>{return p1*Math.pow(2,-10*t)*Math.sin((t-p3)*p2)+1}},},};class Tween extends Animation{constructor(options){super(false);this.duration=options.duration||500.........完整代码请登录后点击上方下载按钮下载查看

网友评论0