首页 > 代码库 > TWaver初学实战——2D机房之机柜篇

TWaver初学实战——2D机房之机柜篇

前一段参与了一个2D机房的项目,但是这种“命题作文”总感觉憋屈,那就回咱这主场再发挥发挥!

第一篇,咱就从机柜下手。

……机柜似乎有点太简单了,因为

机柜就是个大灰框

    drawBorder: function(ctx) {
        ctx.fillStyle = ‘gray‘;
        ctx.fillRect(
            this._rackX,
            this._rackY,
            this._rackOuterWidth,
            this._rackOuterHeight);
        ctx.clearRect(
            this._rackX + this._rackGapLR + this._rackInnerGapLR,
            this._rackY + this._rackGapTB + this._rackInnerGapTB,
            this._rackInnerWidth,
            this._rackInnerHeight);
    },

技术分享

当然我不可能到此为止啊,起码给大灰框加点过渡色吧:

        this._gradient = this._ctx.createLinearGradient(
            this._rackX,
            this._rackY,
            this._rackX + this._rackOuterWidth,
            this._rackY);
        this._gradient.addColorStop(0, ‘#888888‘);
        this._gradient.addColorStop(0.05, ‘#555555‘);
        this._gradient.addColorStop(0.2, ‘#999999‘);
        this._gradient.addColorStop(0.5, ‘#333333‘);
        this._gradient.addColorStop(0.8, ‘#999999‘);
        this._gradient.addColorStop(0.95, ‘#555555‘);
        this._gradient.addColorStop(1, ‘#888888‘);

 技术分享

机柜要有U位

    drawUspace: function(ctx) {
        ctx.lineWidth = 0.5;
        var uCount = this._uCount;
        while(uCount--) {
            ctx.strokeStyle = this._lineColor;
            ctx.lineWidth = 1;
            ctx.beginPath();
            ctx.moveTo(
                this._rackX + this._rackGapLR,
                this._rackY + this._rackGapTB + this._uHeight * uCount)
            ctx.lineTo(
                this._rackX + this._rackGapLR + this._uWidth,
                this._rackY + this._rackGapTB + this._uHeight * uCount)
            ctx.stroke();
        }
        ctx.lineWidth = this._lineWidth;
        ctx.strokeStyle = this._lineColor;
        ctx.strokeRect(
            this._rackX + this._rackGapLR,
            this._rackY + this._rackGapTB,
            this._uWidth,
            this._uHeight * this._uCount);
    },

技术分享

 U位要有编号

        if(this._element._showUscale) {
            ctx.textAlign = ‘right‘;
            ctx.fillText(
                this._uCount - uCount,
                this._rackX - 2,
                this._rackY + this._rackGapTB + this._uHeight * uCount + this._uHeight / 2);
            ctx.textAlign = ‘left‘;
            ctx.fillText(
                this._uCount - uCount,
                this._rackX + this._rackOuterWidth + 2,
                this._rackY + this._rackGapTB + this._uHeight * uCount + this._uHeight / 2);

        }

 技术分享

再加点小细节 

    drawGarnish: function(ctx) {
        var signCount = this._uCount * 3;
        while(signCount--) {
            ctx.fillStyle = ‘#333333‘;
            ctx.fillRect(
                this._rackX + this._rackGapLR - this._uHeight / 2,
                this._rackY + this._rackGapTB + 0.5 + this._uHeight / 3 * signCount,
                this._uHeight / 3 - 1,
                this._uHeight / 3 - 1);
            ctx.fillRect(
                this._rackX + this._rackGapLR + this._uWidth + this._uHeight / 6 + 1,
                this._rackY + this._rackGapTB + 0.5 + this._uHeight / 3 * signCount,
                this._uHeight / 3 - 1,
                this._uHeight / 3 - 1);
            ctx.beginPath();
            ctx.strokeStyle = ‘#FFFFFF‘;
            ctx.lineWidth = 1;
            ctx.moveTo(
                this._rackX + this._rackGapLR + 2,
                this._rackY + this._rackGapTB + ((this._uHeight / 3 - 1) / 2 + 0.5) + this._uHeight / 3 * signCount)
            ctx.lineTo(
                this._rackX + this._rackGapLR + this._uWidth - 2,
                this._rackY + this._rackGapTB + ((this._uHeight / 3 - 1) / 2 + 0.5) + this._uHeight / 3 * signCount)
            ctx.stroke();
        }
    },

技术分享

技术分享

交互式细节

添加了细节虽然逼真了一些,但也会多消耗资源,还显得有点乱,尤其是多个机柜同时展示的时候。

能不能只有我关注的机柜才显示细节,而不关注的就清清爽爽的呢?当然可以,比如我们就把鼠标移入作为“关注”,鼠标移出就“不关注”:

    this.getView().addEventListener(‘mousemove‘, function(e) {
        var elements = self.getElementsAt(e) && self.getElementsAt(e)._as;
        var currentRack = getCurrentRack();
        if(currentRack) {
            if(currentRack != self._currentRack) {
                self._currentRack && self._currentRack.onMouseLeave(e);
                currentRack.onMouseEnter(e);
                self._currentRack = currentRack;
            }
        } else if (self._currentRack) {
            self._currentRack.onMouseLeave(e);
            self._currentRack = null;
        }
        function getCurrentRack() {
            if(elements && elements.length) {
                for(var i = 0; i < elements.length; i++) {
                    elements[i].onMouseMove(e);
                    if(elements[i] instanceof RackBin) {
                        return elements[i];
                    }
                }
                return null;
            }
            return null;
        }
    }, this);
    onm ouseEnter: function(e) {
        this._showUscale = true;
        this._showGarnish = true;
        this._network.invalidateElementUIs();
    },
    onm ouseLeave: function(e) {
        this._showUscale = false;
        this._showGarnish = false;
        this._network.invalidateElementUIs();
    },

技术分享

交互式U位

 如果鼠标在机柜上移动,移到不同的U位就突出显示一下当前U位,那必然是极好的。说干就干:

    onm ouseMove: function(e) {
        var eLoc = this._network.zoomManager._getLogicalPoint(e);
        this.setFocusUnum(eLoc);
    },
    setFocusUnum: function(x, y) {
        if(x && (x.x || x.y || x.x == 0 || x.y == 0)) {
            y = x.y;
            x = x.x;
        }
        this._UI._focusUnum = this.getUnum(x, y);
        this._UI.checkRackUAttachment();
    },
    checkAttachments: function() {
        RackBinUI.superClass.checkAttachments.call(this);
        this.checkRackUAttachment();
    },
    checkRackUAttachment: function() {
        if(this._focusUnum) {
            var data = http://www.mamicode.com/this._rackUdatas[this._focusUnum];
            if(data) {
                if(this._rackUAttachment) {
                    if(this._rackUAttachment._id != data.id) {
                        this._rackUAttachment.setData(data);
                        this._network.invalidateElementUI(this._element, true);
                    }
                } else {
                    this._rackUAttachment = new RackUAttachment(this, true, data);
                    this.addAttachment(this._rackUAttachment);
                    this._network.invalidateElementUI(this._element, true);
                }
            }
        } else {
            if(this._rackUAttachment) {
                this.removeAttachment(this._rackUAttachment, true);
                this._rackUAttachment = null;
            }
        }
    }

技术分享

这里的“当前U位”使用了自定义附件的方式,至于为什么用这种方式……大概就是我会的太多了吧^-^

对了,我之前提到过什么来着——

多机柜展示

    arrangeRacks: function() {
        var count = this._racks.length;
        if(count) {
            var spacing = this._rackWidth + 40;
            var viewRect = this.getViewRect();
            var startX = viewRect.x + viewRect.width / 2 - this._rackWidth / 2;
            if(count > 1) {
                startX -= spacing * (count - 1) / 2;
            }
            if(startX < viewRect.x) {
                startX = viewRect.x + 20;
            }
            for(var i = 0; i < this._racks.length; i++) {
                var x = startX + spacing * i;
                var y = viewRect.y + viewRect.height / 2 + this._rackHeight / 2 - this._racks[i].getHeight();
                if(y < viewRect.y) {
                    y = viewRect.y + 10;
                }
                this._racks[i].setLocation(x, y);
            }
        }
    },

技术分享

这样的机柜,可还入您的法眼?

TWaver初学实战——2D机房之机柜篇