前一段参与了一个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);
onMouseEnter: function(e) { this._showUscale = true; this._showGarnish = true; this._network.invalidateElementUIs(); }, onMouseLeave: function(e) { this._showUscale = false; this._showGarnish = false; this._network.invalidateElementUIs(); },
交互式U位
如果鼠标在机柜上移动,移到不同的U位就突出显示一下当前U位,那必然是极好的。说干就干:
onMouseMove: 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 = 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); } } },
这样的机柜,可还入您的法眼?