tagCould3d 移动端优化版

针对https://github.com/bitjjj/JS-3D-TagCloud这个版本的做了移动端性能优化(使用transform做偏移及缩放,优化帧)。基本原理一致。
class  TagCould {
     mcList = [];
     active =  false;  // 事件控制
     lasta =  1;
     lastb =  1;
     distr =  true;
     mouseX =  0;
     mouseY =  0;
     aA =  null;
     oDiv =  null;
     _now =  0;
     _then =  Date. now();
     _delta =  0;
     isStart =  false;
     defaultOptions = {
         dtr :  Math. PI /  180,
         d :  500,
         tspeed :  5,
         size :  250,
         howElliptical :  1,
         fps :  30,
         radius : ( window. innerWidth +  25) /  2 >  300 ?  300 : ( window. innerWidth +  25) /  2
    };
     constructor( container,  tags = [],  options = {}) {
         this. container =  container;
         this. tags =  tags;
         options =  Object. assign( this. defaultOptions,  options);
         for ( var  p  in  options) {
             this[ p] =  options[ p];
        }
         this. _interval =  1000 /  this. fps;
         window. requestAnimationFrame =
             window. requestAnimationFrame ||
             window. mozRequestAnimationFrame ||
             window. webkitRequestAnimationFrame ||
             window. msRequestAnimationFrame;
         this. init();
    }
     init() {
         this. createTag();
         this. setOffset();
         this. sineCosine( 0,  0,  0);
         this. positionAll();
         this. tick();
         this. bindEvent();
    }
     start() {
         this. isStart =  true;
    }
     pause() {
         this. isStart =  false;
    }
     createTag() {
         this. oDiv =  typeof  this. container ==  'string' ?  document. getElementById( this. container) :  this. container;
         for ( let  i =  0;  i <  this. tags. length;  i++) {
             const  item =  this. tags[ i];
             let  aElE =  document. createElement( 'a');
             aElE. innerHTML =  item. text;
             aElE. classList. add( `tag ${ i } `);
             aElE. classList. add( `tag`);
             item. className &&  aElE. classList. add( item. className);
             aElE. setAttribute( 'href',  item. url ||  'javascript:;');
             this. oDiv. appendChild( aElE);
        }
    }
     setOffset() {
         this. oDiv =  typeof  this. container ==  'string' ?  document. getElementById( this. container) :  this. container;
         let  i =  0,
             oTag =  null;
         this. aA =  this. oDiv. getElementsByTagName( 'a');
         for ( i =  0;  i <  this. aA. length;  i++) {
             oTag = {};
             oTag. offsetWidth =  this. aA[ i]. offsetWidth;
             oTag. offsetHeight =  this. aA[ i]. offsetHeight;
             this. mcList. push( oTag);
        }
    }
     bindEvent() {
         let  self =  this;
         document. addEventListener(
             'mouseover',
             function() {
                 self. active =  true;
            },
             false
        );
         document. addEventListener(
             'mouseout',
             function() {
                 self. active =  false;
            },
             false
        );
         document. addEventListener(
             'mousemove',
             function( evt) {
                 //var oEvent=window.event || evt;
                 self. onmove( window. event ||  evt);
            },
             false
        );
         document. addEventListener(
             'touchstart',
             function() {
                 self. active =  true;
            },
             false
        );
         document. addEventListener(
             'touchmove',
             function( evt) {
                 self. onmove( window. event ||  evt);
            },
             false
        );
         document. addEventListener(
             'touchend',
             function() {
                 self. active =  false;
            },
             false
        );
    }
     tick() {
         if ( window. requestAnimationFrame) {
             window. requestAnimationFrame( this. tick. bind( this));
             this. _now =  Date. now();
             this. _delta =  this. _now -  this. _then;
             if ( this. _delta >  this. _interval) {
                 // 这里不能简单then=now,否则还会出现上边简单做法的细微时间差问题。例如fps=10,每帧100ms,而现在每16ms(60fps)执行一次draw。16*7=112>100,需要7次才实际绘制一次。这个情况下,实际10帧需要112*10=1120ms>1000ms才绘制完成。
                 this. _then =  this. _now -  this. _delta %  this. _interval;
                 this. update();  // ... Code for Drawing the Frame ...
            }
        }  else {
             setTimeout( this. _tick,  this. _interval);
             this. update();
        }
    }
     onmove( oEvent) {
         oEvent. preventDefault();
         if ( oEvent. touches &&  oEvent. touches. length >  0) {
             oEvent. clientX =  oEvent. touches[ 0]. clientX;
             oEvent. clientY =  oEvent. touches[ 0]. clientY;
        }
         this. mouseX =  oEvent. clientX - ( this. oDiv. offsetLeft +  this. oDiv. offsetWidth /  2);
         this. mouseY =  oEvent. clientY - ( this. oDiv. offsetTop +  this. oDiv. offsetHeight /  2);
         this. mouseX /=  5;
         this. mouseY /=  5;
    }
     update() {
         if (! this. isStart) {
             return  false;
        }
         var  a,  b;
         if ( this. active) {
             a = - Math. min( Math. max(- this. mouseY, - this. size),  this. size) /  this. radius *  this. tspeed;
             b =  Math. min( Math. max(- this. mouseX, - this. size),  this. size) /  this. radius *  this. tspeed;
        }  else {
             a =  this. lasta *  0.999;
             b =  this. lastb *  0.999;
        }
         this. lasta =  a;
         this. lastb =  b;
         if ( Math. abs( a) <=  0.01 &&  Math. abs( b) <=  0.01) {
             return;
        }
         var  c =  0;
         this. sineCosine( a,  b,  c);
         for ( var  j =  0;  j <  this. mcList. length;  j++) {
             var  rx1 =  this. mcList[ j]. cx,
                 ry1 =  this. mcList[ j]. cy *  this. ca +  this. mcList[ j]. cz * - this. sa,
                 rz1 =  this. mcList[ j]. cy *  this. sa +  this. mcList[ j]. cz *  this. ca,
                 rx2 =  rx1 *  this. cb +  rz1 *  this. sb,
                 ry2 =  ry1,
                 rz2 =  rx1 * - this. sb +  rz1 *  this. cb,
                 rx3 =  rx2 *  this. cc +  ry2 * - this. sc,
                 ry3 =  rx2 *  this. sc +  ry2 *  this. cc,
                 rz3 =  rz2;
             this. mcList[ j]. cx =  rx3;
             this. mcList[ j]. cy =  ry3;
             this. mcList[ j]. cz =  rz3;
             var  per =  this. d / ( this. d +  rz3);
             this. mcList[ j]. x =  this. howElliptical *  rx3 *  per -  this. howElliptical *  2;
             this. mcList[ j]. y =  ry3 *  per;
             this. mcList[ j]. scale =  per;
             this. mcList[ j]. alpha =  per;
             this. mcList[ j]. alpha = ( this. mcList[ j]. alpha -  0.6) * ( 10 /  6);
        }
         this. doPosition();
         this. depthSort();
    }
     depthSort() {
         var  i =  0,
             aTmp = [];
         for ( i =  0;  i <  this. aA. length;  i++) {
             aTmp. push( this. aA[ i]);
        }
         aTmp. sort( function( vItem1,  vItem2) {
             if ( vItem1. cz >  vItem2. cz) {
                 return - 1;
            }  else  if ( vItem1. cz <  vItem2. cz) {
                 return  1;
            }  else {
                 return  0;
            }
        });
         for ( i =  0;  i <  aTmp. length;  i++) {
             aTmp[ i]. style. zIndex =  i;
        }
    }
     positionAll() {
         var  phi =  0,
             theta =  0,
             max =  this. mcList. length,
             i =  0,
             aTmp = [],
             oFragment =  document. createDocumentFragment();
         //随机排序
         for ( i =  0;  i <  this. aA. length;  i++) {
             aTmp. push( this. aA[ i]);
        }
         aTmp. sort( function() {
             return  Math. random() <  0.5 ?  1 : - 1;
        });
         for ( i =  0;  i <  aTmp. length;  i++) {
             oFragment. appendChild( aTmp[ i]);
        }
         this. oDiv. appendChild( oFragment);
         for ( var  i =  1;  i <  max +  1;  i++) {
             if ( this. distr) {
                 phi =  Math. acos(- 1 + ( 2 *  i -  1) /  max);
                 theta =  Math. sqrt( max *  Math. PI) *  phi;
            }  else {
                 phi =  Math. random() *  Math. PI;
                 theta =  Math. random() * ( 2 *  Math. PI);
            }
             //坐标变换
             this. mcList[ i -  1]. cx =  this. radius *  Math. cos( theta) *  Math. sin( phi);
             this. mcList[ i -  1]. cy =  this. radius *  Math. sin( theta) *  Math. sin( phi);
             this. mcList[ i -  1]. cz =  this. radius *  Math. cos( phi);
             this. aA[ i -  1]. style. webkitTransform =  `translate( ${ this. mcList[ i -  1]. cx +
                 this. oDiv. offsetWidth /  2 -
                 this. mcList[ i -  1]. offsetWidth /  2 +
                 'px' } , ${ this. mcList[ i -  1]. cy +
                 this. oDiv. offsetHeight /  2 -
                 this. mcList[ i -  1]. offsetHeight /  2 +
                 'px' } ) scale( ${ this. mcList[ i -  1]. scale ||  1 } )`;
        }
    }
     doPosition() {
         var  l =  this. oDiv. offsetWidth /  2,
             t =  this. oDiv. offsetHeight /  2;
         for ( var  i =  0;  i <  this. mcList. length;  i++) {
             this. aA[ i]. style. webkitTransform =  `translate( ${ this. mcList[ i]. cx +
                 l -
                 this. mcList[ i]. offsetWidth /  2 +
                 'px' } , ${ this. mcList[ i]. cy +  t -  this. mcList[ i]. offsetHeight /  2 +  'px' } ) scale( ${ this. mcList[ i]
                . scale } )`;
             this. aA[ i]. style. opacity =  this. mcList[ i]. alpha;
        }
    }
     sineCosine( a,  b,  c) {
         this. sa =  Math. sin( a *  this. dtr);
         this. ca =  Math. cos( a *  this. dtr);
         this. sb =  Math. sin( b *  this. dtr);
         this. cb =  Math. cos( b *  this. dtr);
         this. sc =  Math. sin( c *  this. dtr);
         this. cc =  Math. cos( c *  this. dtr);
    }
}
export  default  TagCould;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值