zoukankan      html  css  js  c++  java
  • 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(containertags = [], options = {}) {
            this.container = container;
            this.tags = tags;
            options = Object.assign(this.defaultOptionsoptions);
            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(000);
            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 = 0i < this.tags.lengthi++) {
                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 = 0i < this.aA.lengthi++) {
                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._tickthis._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 ab;
            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(abc);
            for (var j = 0j < this.mcList.lengthj++) {
                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 = 0i < this.aA.lengthi++) {
                aTmp.push(this.aA[i]);
            }

            aTmp.sort(function(vItem1vItem2) {
                if (vItem1.cz > vItem2.cz) {
                    return -1;
                } else if (vItem1.cz < vItem2.cz) {
                    return 1;
                } else {
                    return 0;
                }
            });

            for (i = 0i < aTmp.lengthi++) {
                aTmp[i].style.zIndex = i;
            }
        }
        positionAll() {
            var phi = 0,
                theta = 0,
                max = this.mcList.length,
                i = 0,
                aTmp = [],
                oFragment = document.createDocumentFragment();

            //随机排序
            for (i = 0i < this.aA.lengthi++) {
                aTmp.push(this.aA[i]);
            }

            aTmp.sort(function() {
                return Math.random() < 0.5 ? 1 : -1;
            });

            for (i = 0i < aTmp.lengthi++) {
                oFragment.appendChild(aTmp[i]);
            }

            this.oDiv.appendChild(oFragment);

            for (var i = 1i < max + 1i++) {
                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 = 0i < this.mcList.lengthi++) {
                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(abc) {
            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;
  • 相关阅读:
    SVN集中式版本控制器的安装、使用与常见问题汇总
    Angular指令渗透式理解
    Angular双向数据绑定MVVM以及基本模式分析
    Angular自定义指令(directive)
    Angular作用域的层级概念(scope)
    json 序列化
    cookies session 知识点
    mvc基础知识
    cookies 练习1
    MySQL教程
  • 原文地址:https://www.cnblogs.com/qianduanjingying/p/13693042.html
Copyright © 2011-2022 走看看