• TWaver初学实战——炫动2D机房之设备篇


    有了机柜,下面就该上设备了。不过,这似乎也太简单,因为

    设备面板就是个小灰块

    ……呃,还是再分几个区吧,要不实在太单调:

    	drawPane: function(ctx) {
    		ctx.fillStyle = this._borderColor;
    		ctx.fillRect(
    			this._panelData.x,
    			this._panelData.y,
    			this._panelData.w,
    			this._panelData.h);
    		ctx.fillStyle = this._centerPanelColor;
    		ctx.fillRect(
    			this._panelData.center.x,
    			this._panelData.center.y,
    			this._panelData.center.w,
    			this._panelData.center.h);
    		ctx.fillStyle = this._sidePaneColor;
    		ctx.fillRect(
    			this._panelData.left.x,
    			this._panelData.left.y,
    			this._panelData.left.w,
    			this._panelData.left.h);
    		ctx.fillRect(
    			this._panelData.right.x,
    			this._panelData.right.y,
    			this._panelData.right.w,
    			this._panelData.right.h);
    	},
    

    还是老路子,再

    添加交互变化

    	drawPane: function(ctx) {
    		ctx.fillStyle = this._element._isFocus ? this._borderFocusColor : this._borderColor;
    		……
    		if(this._element._isFocus) {
    			ctx.lineWidth = this._outlineWidth;
    			ctx.strokeStyle = this._outlineColor;
    			ctx.strokeRect(
    				this._panelData.x - this._outlineWidth / 2,
    				this._panelData.y - this._outlineWidth / 2,
    				this._panelData.w + this._outlineWidth,
    				this._panelData.h + this._outlineWidth);
    		}
    	},
    

      

    接下来才是重点,那就是设备端口的绘制。首先

    绘制电源端口

    电源端口绘制在左右面板,单列纵向均匀排列:

    	initPowerPorts: function() {
    		var self = this;
    		var count = this._element._powerPortAmount;
    		var lCount = count && Math.ceil(count / 2);
    		if(lCount) {
    			for(i = 0; i < lCount; i++) {
    				var number = i * 2 + 1;
    				initPowerPort(this._panelData.left, lCount, number, i);
    			}
    		}
    		var rCount = count && Math.floor(count / 2);
    		if(rCount) {
    			for(i = 0; i < rCount; i++) {
    				var number = (i + 1) * 2;
    				initPowerPort(this._panelData.right, rCount, number, i);
    			}
    		}
    		function initPowerPort(panel, count, number, i) {
    			var ph = 4;
    			var gap = (panel.h0 - ph * count) / (count + 1);
    			var start = gap + ph / 2;
    			var offset = (panel.h0 - gap) / count;
    			var port = 'p' + number;
    			var data = {
    				x0: panel.x0 + panel.w0 / 2,
    				y0: panel.y0 + start + offset * i,
    				number: number,
    				connected: self._element._connectedPowerPorts.indexOf(port) >= 0
    			}
    			self._portsData[port] = data;
    			self.refreshPortLoc(port);
    		}
    	},
    

    再用黄色标识出已连通的端口,一目了然:

    			var data = port && this._portsData[port];
    			if(data && port.charAt(0) == 'p') {
    				ctx.strokeStyle = data.connected ? this._powerPortColor : this._powerPortConnectedColor;
    				ctx.lineWidth = 0.1;
    				ctx.fillStyle = data.connected ? this._powerPortConnectedColor : this._powerPortColor;
    				if(port == this._focusPort) {
    					ctx.fillStyle = this._powerPortFocusColor;
    				}
    				this.drawPowerPort(ctx, data);
    			}
    

      

      

     接下来

    绘制网络端口

    网口绘制在中部面板,排列方式固定位置的办法,把所有可用的网口位置都标识出来,实际上占用多少就填充多少个,同样用不同的颜色表示已连通和未连通两种状态: 

    	initNetworkPorts: function() {
    		var self = this;
    		var cx0 = this._panelData.center.x0;
    		var cy0 = this._panelData.center.y0;
    		var cw0 = this._panelData.center.w0;
    		var ch0 = this._panelData.center.h0;
    		var xCount = this._networkPortRows;
    		var xPh = 3;
    		var xGap = (cw0 - xPh * xCount) / (xCount + 1);
    		var xStart = xGap + xPh / 2;
    		var xOffset = (cw0 - xGap) / xCount;
    		var yCount = this._element._uCount;
    		var yPh = 7;
    		var yGap = (ch0 - yPh * yCount) / (yCount + 1);
    		var yStart = yGap + yPh / 2;
    		var yOffset = (ch0 - yGap) / yCount;
    		for(j = 0; j < yCount; j++) {
    			for(i = 0; i < xCount; i++) {
    				var number1 = (xCount * j + i) * 2 + 1;
    				initNetworkPort(number1, i, j, -2);
    				var number2 = (xCount * j + i) * 2 + 2;
    				initNetworkPort(number2, i, j, 2);
    			}
    		}
    		function initNetworkPort(number, i, j, offset) {
    			var port = 'n' + number;
    			var data = {
    				x0: cx0 + xStart + xOffset * i,
    				y0: cy0 + yStart + yOffset * j + offset,
    				number: number,
    				connected: self._element._connectedNetworkPorts.indexOf(port) >= 0,
    				usable: number <= self._element._networkPortAmount
    			}
    			self._portsData[port] = data;
    			self.refreshPortLoc(port);
    		}
    	},
    

      

    这样一个设备面板就基本完成了 

       

    互动上似乎还可以再干点什么……那就

    突出显示当前端口 

    	onMouseMove: function(e) {
    		var eLoc = this._network.zoomManager._getLogicalPoint(e);
    		this._UI.setFocusPort(eLoc);
    	},
    ……
    	getFocusPortByLoc: function(eLoc) {
    		for(var port in this._portsData) {
    			var data = this._portsData[port];
    			var xDistance = Math.abs(data.x - eLoc.x);
    			var yDistance = Math.abs(data.y - eLoc.y);
    			if(port.charAt(0) == 'p' && xDistance < 3 && yDistance < 2) {
    				return port;
    			}
    			if(port.charAt(0) == 'n' && xDistance < 1.5 && yDistance < 1.5) {
    				return port;
    			}
    		}
    		return null;
    	},
    

      

    如果大家对设计和配色有槽要吐,那也是可以理解的,毕竟我只是个普通的程序猿。

    这个虚拟设备面板的可取之处,在于它的U高和端口数量都可以定制,有着极大的灵活性和实用性。

    	var rackDatas = [{
    		id: 'rackbin1',
    		name: '机柜1',
    		uAmount: 30,
    		children: [{
    			id: 'device11',
    			name: '设备1',
    			uStart: 2,
    			uCount: 2,
    			powerPortAmount: 3,
    			networkPortAmount: 7,
    			connectedPowerPorts: ['p1'],
    			connectedNetworkPorts: ['n2', 'n4', 'n6']
    		}, {
    			id: 'device12',
    			name: '设备2',
    			uStart: 10,
    			uCount: 3,
    			powerPortAmount: 4,
    			networkPortAmount: 51,
    			connectedPowerPorts: ['p2','p3'],
    			connectedNetworkPorts: ['n10', 'n11', 'n12', 'n13', 'n14']
    		}, {
    			id: 'device13',
    			name: '设备3',
    			uStart: 20,
    			uCount: 4,
    			powerPortAmount: 5,
    			networkPortAmount: 51,
    			connectedPowerPorts: ['p2','p3','p4'],
    			connectedNetworkPorts: []
    		}]
    	}];
    

    最后再看看连排设备的效果:

  • 相关阅读:
    WM_PAINT消息详解,使用InvalidateRect或InvalidateRgn函数刻意产生WM_PAINT消息(WIN7里有变化,“调整视觉效果”,将“启用桌面组合”去掉)
    delphi 大文件的读写 使用 MapviewOffile
    Delphi的子类化控件消息, 消息子类化
    wParam与lParam的区别
    为什么使用DLL
    大数据分包算法
    JSON如何序列图片
    AngularJs学习
    设计模式解读
    js模块化编程总结
  • 原文地址:https://www.cnblogs.com/xiaor2/p/7368139.html
Copyright © 2020-2023  润新知