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;
上一篇:使用Css,JavaScript实现轮播效果图


下一篇:显示与隐藏