Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
»ùÓÚ HTML5 WebGL µÄ 3D ²Ö´¢¹ÜÀíϵͳ
 
  4156  次浏览      28
 2017-12-13 
 
±à¼­ÍƼö:
±¾ÎÄÀ´Ô´segmentfault£¬±¾ÎIJִ¢¹ÜÀíϵͳ£¨WMS£©ÊÇÒ»¸öʵʱµÄ¼ÆËã»úÈí¼þϵͳ£¬ËüÄܹ»°´ÕÕÔË×÷µÄÒµÎñ¹æÔòºÍÔËËã·¨Ôò£¬¶ÔÐÅÏ¢¡¢×ÊÔ´¡¢ÐÐΪ¡¢´æ»õºÍ·ÖÏúÔË×÷½øÐиüÍêÃÀµØ¹ÜÀí¡£

²Ö´¢¹ÜÀíϵͳ£¨WMS£©ÊÇÒ»¸öʵʱµÄ¼ÆËã»úÈí¼þϵͳ£¬ËüÄܹ»°´ÕÕÔË×÷µÄÒµÎñ¹æÔòºÍÔËËã·¨Ôò£¬¶ÔÐÅÏ¢¡¢×ÊÔ´¡¢ÐÐΪ¡¢´æ»õºÍ·ÖÏúÔË×÷½øÐиüÍêÃÀµØ¹ÜÀí£¬Ê¹Æä×î´ó»¯Âú×ãÓÐЧ²ú³öºÍ¾«È·ÐÔµÄÒªÇó¡£´Ó²ÆÎñÈí¼þ¡¢½øÏú´æÈí¼þCIMS£¬´ÓMRP¡¢MRPIIµ½ERP£¬´ú±íÁËÖйúÆóÒµ´Ó´Ö·ÅÐ͹ÜÀí×ßÏò¼¯Ô¼¹ÜÀíµÄÒªÇ󣬾ºÕùµÄ¼¤ÁҺͶԳɱ¾µÄÒªÇóʹµÃ¹ÜÀí¶ÔÏó±íÏÖΪ£ºÕûºÍÉÏÓΡ¢ÆóÒµ±¾Éí¡¢ÏÂÓÎÒ»Ì廯¹©Ó¦Á´µÄÐÅÏ¢ºÍ×ÊÔ´¡£¶ø²Ö¿â£¬ÓÈÆäÊÇÖÆÔìÒµÖеIJֿ⣬×÷ΪÁ´ÉϵĽڵ㣬²»Í¬Á´½ÚÉÏµÄ¿â´æ¹Û²»Í¬£¬ÔÚÎïÁ÷¹©Ó¦Á´µÄ¹ÜÀíÖУ¬²»ÔÙ°Ñ¿â´æ×÷Ϊά³ÖÉú²úºÍÏúÊ۵ĴëÊ©£¬¶ø½«Æä×÷ΪһÖÖ¹©Ó¦Á´µÄƽºâ»úÖÆ£¬Æä×÷ÓÃÖ÷ÒªÊÇЭµ÷Õû¸ö¹©Ó¦Á´¡£µ«ÏÖ´úÆóҵͬʱÓÖÃæÁÙ×ÅÐí¶à²»È·¶¨ÒòËØ£¬ÎÞÂÛËûÃÇÀ´×Ô·Ö¹©·½»¹ÊÇÀ´×ÔÉú²ú»ò¿Í»§£¬¶ÔÆóÒµÀ´Ëµ´¦ÀíºÃ¿â´æ¹ÜÀíÓ벻ȷ¶¨ÐÔ¹ØÏµµÄΨһ°ì·¨ÊǼÓÇ¿ÆóÒµÖ®¼äÐÅÏ¢µÄ½»Á÷ºÍ¹²Ïí£¬Ôö¼Ó¿â´æ¾ö²ßÐÅÏ¢µÄ͸Ã÷ÐÔ¡¢¿É¿¿ÐÔºÍʵʱÐÔ¡£¶øÕ⣬ÕýÊÇWMSËùÒª°ïÖúÆóÒµ½â¾öµÄÎÊÌâ¡£

WMSÈí¼þºÍ½øÏú´æ¹ÜÀíÈí¼þµÄ×î´óÇø±ðÔÚÓÚ£º½øÏú´æÈí¼þµÄÄ¿±êÊÇÕë¶ÔÓÚÌØ¶¨¶ÔÏó£¨Èç²Ö¿â£©µÄÉÌÆ·¡¢µ¥¾ÝÁ÷¶¯£¬ÊǶÔÓÚ²Ö¿â×÷Òµ½á¹ûµÄ¼Ç¼¡¢ºË¶ÔºÍ¹ÜÀí¡ª¡ª±¨¾¯¡¢±¨±í¡¢½á¹û·ÖÎö£¬±ÈÈç¼Ç¼ÉÌÆ·³öÈë¿âµÄʱ¼ä¡¢¾­ÊÖÈ˵ȣ»¶øWMSÈí¼þÔò³ýÁ˹ÜÀí²Ö¿â×÷ÒµµÄ½á¹û¼Ç¼¡¢ºË¶ÔºÍ¹ÜÀíÍâ×î´óµÄ¹¦ÄÜÊǶԲֿâ×÷Òµ¹ý³ÌµÄÖ¸µ¼ºÍ¹æ·¶£º¼´²»µ«¶Ô½á¹û½øÐд¦Àí£¬¸üÊÇͨ¹ý¶Ô×÷Òµ¶¯×÷µÄÖ¸µ¼ºÍ¹æ·¶±£Ö¤×÷ÒµµÄ׼ȷÐÔ¡¢ËٶȺÍÏà¹Ø¼Ç¼Êý¾ÝµÄ×Ô¶¯µÇ¼Ç£¨Èë¼ÆËã»úϵͳ£©£¬Ôö¼Ó²Ö¿âµÄЧÂÊ¡¢¹ÜÀí͸Ã÷¶È¡¢ÕæÊµ¶È½µµÍ³É±¾±ÈÈçͨ¹ýÎÞÏßÖÕ¶ËÖ¸µ¼²Ù×÷Ô±¸øÄ³¶¨µ¥·¢»õ£ºµ±²Ù×÷Ô±Ìá³ö·¢»õÇëÇóʱ£¬ÖÕ¶ËÌáʾ²Ù×÷Ô±Ó¦µ½Äĸö¾ßÌåµÄ²Ö¿â»õλȡ³öÖ¸¶¨ÊýÁ¿µÄÄǼ¸ÖÖÉÌÆ·£¬É¨Ãè»õ¼ÜºÍÉÌÆ·ÌõÂëºË¶ÔÊÇ·ñÕýÈ·£¬È»ºóË͵½½Ó»õÇø£¬Â¼ÈëÔËÊ䵥λÐÅÏ¢£¬Íê³É³ö»õÈÎÎñ£¬ÖØÒªµÄÊǰüÀ¨³ö»õʱ¼ä¡¢²Ù×÷Ô±¡¢»õÎïÖÖÀà¡¢ÊýÁ¿¡¢²úÆ·ÐòÁкš¢³ÐÔ˵¥Î»µÈÐÅÏ¢ÔÚ»õÎï×°³µµÄͬʱÒѾ­Í¨¹ýÎÞÏß·½Ê½´«Êäµ½Á˼ÆËã»úÐÅÏ¢ÖÐÐÄÊý¾Ý¿â¡£

ÓÉÓÚÊг¡ÐèÇóÁ¿½Ï´ó£¬ÎÒÃÇÀ´ºÃºÃ½âÎö½ñÌìÕâ¸öÀý×Ó¡£

±¾ÀýµØÖ·£ºhttp://www.hightopo.com/demo/...

¶¯Í¼ÈçÏ£º

¿ÉÒÔÔÚ http://download.csdn.net/down... ÏÂÔØ´úÂë¡£¾ßÌåÔËÐдúÂëÇë²Î¿¼ readme.html¡£

Õâ¸öÀý×ÓÊDzÉÓà es6 µÄÄ£¿é»¯µÄ·½Ê½²¿ÊðµÄ¡£´ò¿ª index.html ½øÈë lib/index.js£¬Ô´ÂëÊÇÔÚ src Îļþ¼ÐÖУ¬ÎÒÃÇÖ±½Ó½ø src/view Ï嵀 index.js

ÔÚ¶¥²¿¼ÓÔØÆäËûÄ£¿éÖк¬ÓÐ export ½Ó¿ÚµÄÄ£¿é£º

import sidebar from './sidebar.js';
import header from './header.js';
import BorderLayout from './common/BorderLayout.js';
import shelfPane from './common/shelfPane.js';
import chartPane from './common/chartPane.js';
import graph3dView from './3d/index';

ÎÒÃǽ«Ò³ÃæÉϵÄÿ¸ö²¿·Ö·Ö¿ªÀ´·ÅÔÚ²»Í¬µÄ js ÎļþÖУ¬¾ÍÊÇÉÏÃæ¼ÓÔØµÄ js export µÄ²¿·Ö£¬¸ù²ãÈÝÆ÷ BorderLayout£¨ÕûÌå×îÍâ²ãµÄ div£©£¬ÕûÕÅͼÉϵIJ¿·Ö¶¼ÊÇ»ùÓÚ borderLayout µÄ¡£

×îÍâ²ãÈÝÆ÷ BorderLayout ÊÇÔÚ src/view/common Ï嵀 BorderLayout.js ÖÐ×Ô¶¨ÒåµÄÀ࣬ÆäÖÐ ht.Default.def(className, superClass, methods) ÊÇ HT Öзâ×°µÄ×Ô¶¨ÒåÀàµÄº¯Êý£¬ÆäÖÐ className Ϊ×Ô¶¨ÒåÀàÃû£¬ superClass ΪҪ¼Ì³ÐµÄ¸¸À࣬methods Ϊ·½·¨ºÍ±äÁ¿ÉùÃ÷£¬ÒªÊ¹ÓÃÕâ¸ö·½·¨ÒªÏÈÔÚÍⲿ¶¨ÒåÕâ¸öº¯Êý±äÁ¿£¬Í¨¹ý functionName.superClass.constructor.call(this) ·½·¨¼Ì³Ð¡£BorderLayout ×Ô¶¨ÒåÀà¼Ì³ÐÁË ht.ui.drawable.BorderLayout ²¼¾Ö×é¼þ£¬´Ë²¼¾ÖÆ÷½«×ÔÉí¿Õ¼ä»®·ÖΪÉÏ¡¢Ï¡¢×ó¡¢ÓÒ¡¢ÖмäÎå¸öÇøÓò£¬Ã¿¸öÇøÓò¿ÉÒÔ·ÅÖÃÒ»¸ö×Ó×é¼þ¡£ÎªÁËÄÜÕý³£½»»¥£¬ÖØÐ´ getSplitterAt º¯Êý½« splitterRect µÄ¿í¶ÈÐÞ¸ÄΪ 10£¬ÒÔ¼°ÎªÁ˵÷Õû×ó²à splitterCanvas µÄ³ß´ç£¬ÒԱ㵲ס×Ó×é¼þ¶øÖØÐ´µÄ layoutSplitterCanvas Á½¸ö·½·¨£º

let BorderLayout = function() {
BorderLayout.superClass.constructor.call(this);
this.setContinuous(true);
this.setSplitterSize(0);
};
ht.Default.def(BorderLayout, ht.ui.BorderLayout, {//×Ô¶¨ÒåÀà
/**
* splitter ¿í¶È¶¼Îª 0£¬ÎªÁËÄÜÕý³£½»»¥£¬ÖØÐ´´Ëº¯Êý½« splitterRect µÄ¿í¶ÈÐÞ¸ÄΪ 10
* @override
*/
getSplitterAt: function (event) {//»ñȡʼþ¶ÔÏóÏ·ָôÌõËùÔÚµÄÇøÓò
var leftRect = this._leftSplitterRect, lp;
if (leftRect) {
leftRect = ht.Default.clone(leftRect);
leftRect.width = 10;
leftRect.x -= 5;
if (event instanceof Event)
lp = this.lp(event);
else
lp = event;
if (ht.Default.containsPoint(leftRect, lp)) return 'left';
}
return BorderLayout.superClass.getSplitterAt.call(this, event);
},
/**
* µ÷Õû×ó²à splitterCanvas µÄ³ß´ç£¬ÒԱ㵲ס×Ó×é¼þ
* @override
*/
layoutSplitterCanvas: function(canvas, x, y, width, height, region) {
if (region === 'left') {
canvas.style.pointerEvents = '';
canvas.style.display = 'block';
ht.Default.setCanvas(canvas, 10, height);
canvas.style.left = this.getContentLeft() + this.tx() + x - 5 + 'px';
canvas.style.top = this.getContentTop() + this.ty() + y + 'px';
}
else {
BorderLayout.superClass.layoutSplitterCanvas.call(this, canvas, x, y, width, height, region);
}
}
});
export default BorderLayout;

×ó²àÀ¸ sidebar£¬·ÖΪ 8 ¸ö²¿·Ö£º¶¥²¿ logo¡¢»õλͳ¼Æ±í¸ñ¡¢½ø¶ÈÌõ¡¢·Ö¸îÏß¡¢»õÎï±í¸ñ¡¢Í¼±í¡¢¹ÜÀí×é¡¢ÎÊÌâ·´À¡°´Å¥µÈ¡£

¿ÉÒԲ鿴 src/view Ï嵀 sidebar.js Îļþ£¬Õâ¸ö js ÎļþÖÐͬÑù¼ÓÔØÁË src/view/common ϵÄTreeHoverBackgroundDrawable.js ºÍ ProgressBarSelectBarDrawable.js ÖÐµÄ TreeHoverBackgroundDrawable ºÍ ProgressBarSelectBarDrawable ±äÁ¿£¬ÒÔ¼° src/controller Ï嵀 sidebar.js ÖÐµÄ controller ±äÁ¿£º

import TreeHoverBackgroundDrawable from './common/TreeHoverBackgroundDrawable.js';
import ProgressBarSelectBarDrawable from './common/ProgressBarSelectBarDrawable.js';
import controller from '../controller/sidebar.js';

HT ·â×°ÁËÒ»¸ö ht.ui.VBoxLayout º¯Êý£¬ÓÃÀ´½«×Ó×é¼þ·ÅÖÃÔÚͬһ´¹Ö±ÁÐÖУ¬ÎÒÃÇ¿ÉÒÔ½«×ó²àÀ¸ÒªÏÔʾµÄ²¿·Ö¶¼·Åµ½Õâ¸ö×é¼þÖУ¬ÕâÑùËùÓеIJ¿·Ö¶¼ÊÇÒÔ´¹Ö±ÁÐÅŲ¼£º

let vBoxLayout = new ht.ui.VBoxLayout();//´Ë²¼¾ÖÆ÷½«×Ó×é¼þ·ÅÖÃÔÚͬһ´¹Ö±ÁÐÖУ»
vBoxLayout.setBackground('#17191a');
¶¥²¿ logo ÊǸù¾ÝÔÚ Label ±êÇ©ÉÏÌí¼Ó icon µÄ·½·¨À´ÊµÏֵ쬲¢½«Õâ¸ö topLabel Ìí¼Ó½ø´¹Ö±ÁÐ vBoxLayout ÖУº
let topLabel = new ht.ui.Label(); //±êÇ©×é¼þ
topLabel.setText('Demo-logo');//ÉèÖÃÎÄ×ÖÄÚÈÝ
topLabel.setIcon('imgs/logo.json');//ÉèÖÃͼ±ê£¬¿ÉÒÔÊÇÑÕÉ«»òÕßͼƬµÈ
topLabel.setIconWidth(41);
topLabel.setIconHeight(37);
topLabel.setTextFont('18px arial, sans-serif');
topLabel.setTextColor('#fff');
topLabel.setPreferredSize(1, 64);//×é¼þ×ÔÉí×îºÏÊʵijߴç
topLabel.setBackground('rgb(49,98,232)');
vBoxLayout.addView(topLabel, {//½«×Ó×é¼þ¼Óµ½ÈÝÆ÷ÖÐ
width: 'match_parent'//ÌîÂú¸¸ÈÝÆ÷
});

¶ÔÓÚ¡°»õλͳ¼Æ±í¸ñ¡±£¬ÎÒÃDzÉÓõÄÊÇ HT ·â×°µÄ TreeTableView ×é¼þ£¬ÒÔÊ÷ºÍ±í¸ñµÄ×éºÏ·½Ê½³ÊÏÖ DataModel ÖÐÊý¾ÝÔªËØÊôÐÔ¼°¸¸×Ó¹ØÏµ£¬²¢½«Õâ¸ö¡°Ê÷±í¡±Ìí¼Ó½ø´¹Ö±ÁÐ vBoxLayout ÖУº

let shelfTreeTable = new ht.ui.TreeTableView();//Ê÷±í×é¼þ£¬ÒÔÊ÷ºÍ±í¸ñµÄ×éºÏ·½Ê½³ÊÏÖ DataModel ÖÐÊý¾ÝÔªËØÊôÐÔ¼°¸¸×Ó¹ØÏµ
shelfTreeTable.setHoverBackgroundDrawable(new TreeHoverBackgroundDrawable('#1ceddf', 2));//ÉèÖà hover ״̬ÏÂÐÐÑ¡Öб³¾°µÄ Drawable ¶ÔÏó
shelfTreeTable.setSelectBackgroundDrawable(new TreeHoverBackgroundDrawable('#1ceddf', 2));//ÉèÖÃÐÐÑ¡Öб³¾°µÄ Drawable ¶ÔÏó ²ÎÊýΪ¡°±³¾°
shelfTreeTable.setBackground(null);
shelfTreeTable.setIndent(20);//ÉèÖò»Í¬²ã´ÎµÄËõ½øÖµ
shelfTreeTable.setColumnLineVisible(false);//ÉèÖÃÁÐÏßÊÇ·ñ¿É¼û
shelfTreeTable.setRowLineVisible(false);
shelfTreeTable.setExpandIcon('imgs/expand.json');//ÉèÖÃÕ¹¿ªÍ¼±êͼ±ê£¬¿ÉÒÔÊÇÑÕÉ«»òÕßͼƬµÈ
shelfTreeTable.setCollapseIcon('imgs/collapse.json');//ÉèÖúϲ¢Í¼±êͼ±ê£¬¿ÉÒÔÊÇÑÕÉ«»òÕßͼƬµÈ
shelfTreeTable.setPreferredSizeRowCountLimit();//ÉèÖüÆËã preferredSize ʱҪÏÞÖÆµÄÊý¾ÝÐÐÊý
shelfTreeTable.setId('shelfTreeTable');
vBoxLayout.addView(shelfTreeTable, {
width: 'match_parent',
height: 'wrap_content',//×é¼þ×ÔÉíÊ×Ñ¡¸ß¶È
marginTop: 24,
marginLeft: 4,
marginRight: 4
});

ÎÒÃÇÔÚÉèÖá°ÐÐÑ¡ÖС±Ê±±³¾°´«ÈëÁËÒ»¸ö TreeHoverBackgroundDrawable ¶ÔÏó£¬Õâ¸ö¶ÔÏóÊÇÔÚ srcviewcommon Ï嵀 TreeHoverBackgroundDrawable.js ÎļþÖж¨ÒåµÄ£¬ÆäÖÐ ht.Default.def(className, superClass, methods) ÊÇ HT Öзâ×°µÄ×Ô¶¨ÒåÀàµÄº¯Êý£¬ÆäÖÐ className Ϊ×Ô¶¨ÒåÀàÃû£¬ superClass ΪҪ¼Ì³ÐµÄ¸¸À࣬methods Ϊ·½·¨ºÍ±äÁ¿ÉùÃ÷£¬ÒªÊ¹ÓÃÕâ¸ö·½·¨ÒªÏÈÔÚÍⲿ¶¨ÒåÕâ¸öº¯Êý±äÁ¿£¬Í¨¹ý functionName.superClass.constructor.call(this) ·½·¨¼Ì³Ð¡£TreeHoverBackgroundDrawable ×Ô¶¨ÒåÀà¼Ì³ÐÁË ht.ui.drawable.Drawable ×é¼þÓÃÓÚ»æÖÆ×é¼þ±³¾°¡¢Í¼±êµÈ£¬Ö»ÖØÐ´ÁË draw ºÍ getSerializableProperties Á½¸ö·½·¨£¬ÎÒÃÇÔÚ draw ·½·¨ÖÐÖØ»æÁË shelfTreeTable µÄÐÐÑ¡Öб³¾°É«£¬²¢ÖØÔØÁË getSerializableProperties ÐòÁл¯×é¼þº¯Êý£¬²¢½« TreeHoverBackgroundDrawable ´«ÈëµÄ²ÎÊý×÷Ϊ map ÖÐÐÂÌí¼ÓµÄÊôÐÔ£º

let TreeHoverBackgroundDrawable = function(color, width) {
TreeHoverBackgroundDrawable. superClass. constructor.call(this);
this.setColor(color);
this.setWidth(width);
};
ht.Default.def(TreeHoverBackgroundDrawable, ht.ui.drawable.Drawable, {
ms_ac: ['color', 'width'],
draw: function(x, y, width, height, data, view, dom) {
var self = this,
g = view.getRootContext(dom),
color = self.getColor();

g.beginPath();
g.fillStyle = color;
g.rect(x, y, self.getWidth(), height);
g.fill();
},
getSerializableProperties: function() {
var parentProperties = TreeHoverBackgroundDrawable. superClass.getSerializableProperties. call(this);
return addMethod(parentProperties, {
color: 1, width: 1
});
}
});

¼ÇסҪµ¼³ö TreeHoverBackgroundDrawable £º

export default TreeHoverBackgroundDrawable;

HT »¹·â×°Á˷dz£ºÃÓÃµÄ ht.ui.ProgressBar ×é¼þ£¬¿ÉÖ±½Ó»æÖƽø¶ÈÌõ£º

let progressBar = new ht.ui.ProgressBar();
progressBar.setId('progressBar');
progressBar.setBackground('#3b2a00');//ÉèÖÃ×é¼þµÄ±³¾°£¬¿ÉÒÔÊÇÑÕÉ«»òÕßͼƬµÈ
progressBar.setBar('rgba(0,0,0,0)');//ÉèÖýø¶ÈÌõ±³¾°£¬¿ÉÒÔÊÇÑÕÉ«»òÕßͼƬµÈ
progressBar.setPadding(5);
progressBar.setSelectBarDrawable(new ProgressBarSelectBarDrawable('#c58348', '#ffa866')); //ÉèÖÃǰ¾°(¼´½ø¶È¸²¸ÇÇøÓò)µÄ Drawable ¶ÔÏ󣬿ÉÒÔÊÇÑÕÉ«»òÕßͼƬµÈ
progressBar.setValue(40);//ÉèÖõ±Ç°½ø¶ÈÖµ
progressBar.setBorderRadius(0);
vBoxLayout.addView(progressBar, {
marginTop: 24,
width: 'match_parent',
height: 28,
marginBottom: 24,
marginLeft: 14,
marginRight: 14
});

ÎÒÃÇÔÚ ÉèÖá°Ç°¾°¡±µÄʱºò´«ÈëÁËÒ»¸ö ProgressBarSelectBarDrawable ¶ÔÏó£¬Õâ¸ö¶ÔÏóÔÚ srcviewcommon Ï嵀 ProgressBarSelectBarDrawable.js Öж¨ÒåµÄ¡£¾ßÌ嶨Òå·½·¨¸úÉÏÃæµÄ TreeHoverBackgroundDrawable º¯Êý¶ÔÏóÀàËÆ£¬ÕâÀï²»ÔÙ׸Êö¡£

·Ö¸îÏßµÄÖÆ×÷×îΪ¼òµ¥£¬Ö»Òª½«Ò»¸ö¾ØÐεĸ߶ÈÉèÖÃΪ 1 ¼´¿É£¬ÎÒÃÇÓà ht.ui.View() ×é¼þÀ´ÖÆ×÷£º

let separator = new ht.ui.View();//ËùÓÐÊÓͼ×é¼þµÄ»ùÀ࣬ËùÓпÉÊÓ»¯×é¼þ¶¼±ØÐë´Ó´ËÀà¼Ì³Ð
separator.setBackground('#666');
vBoxLayout.addView(separator, {
width: 'match_parent',
height: 1,
marginLeft: 14,
marginRight: 14,
marginBottom: 24
});

»õÎï±í¸ñµÄ²Ù×÷¼¸ºõºÍ»õλͳ¼Æ±í¸ñÏàͬ£¬ÕâÀï²»ÔÙ׸Êö¡£

ÎÒÃǽ«Ò»¸ö json µÄͼ±íÎļþµ±×öͼƬ´«¸øÍ¼±íµÄ×é¼þÈÝÆ÷×÷Ϊ±³¾°£¬Ò²ÄܺÜÇáËɵزÙ×÷£º

let chartView = new ht.ui.View();
chartView.setBackground('imgs/chart.json');
vBoxLayout.addView(chartView, {
width: 173,
height: 179,
align: 'center',
marginBottom: 10
});

¹ÜÀí×éºÍ¶¥²¿ logo µÄ¶¨Ò巽ʽÀàËÆ£¬ÕâÀï²»ÔÙ׸Êö¡£

ÎÊÌâ·´À¡°´Å¥£¬ÎÒÃǽ«Õâ¸ö²¿·ÖÓà HT ·â×°µÄ ht.ui.Button ×é¼þÀ´ÖÆ×÷£¬²¢½«Õâ¸ö²¿·ÖÌí¼Ó½ø´¹Ö±ÁÐ vBoxLayout ÖУº

let feedbackButton = new ht.ui.Button();//°´Å¥Àà
feedbackButton.setId('feedbackButton');
feedbackButton.setText('ÎÊÌâ·´À¡£ºservice@hightopo.com');
feedbackButton.setIcon('imgs/em.json');
feedbackButton.setTextColor('#fff');
feedbackButton.setHoverTextColor( shelfTreeTable.getHoverLabelColor());//ÉèÖà hover ״̬ÏÂÎÄ×ÖÑÕÉ«
feedbackButton.setActiveTextColor( feedbackButton.getHoverTextColor());//ÉèÖà active ״̬ÏÂÎÄ×ÖÑÕÉ«
feedbackButton.setIconWidth(16);
feedbackButton.setIconHeight(16);
feedbackButton.setIconTextGap(10);
feedbackButton.setAlign('left');
feedbackButton.setBackground(null);
feedbackButton.setHoverBackground(null);
feedbackButton.setActiveBackground(null);
vBoxLayout.addView(feedbackButton, {
width: 'match_parent',
marginTop: 5,
marginBottom: 10,
marginLeft: 20
});

ÊÓͼ²¿·Ö×öºÃÁË£¬ÔÚÄ£¿é»¯¿ª·¢ÖУ¬controller ¾ÍÊÇ×ö½»»¥µÄ²¿·Ö£¬shelfTreeTable »õλͳ¼Æ±í¸ñ£¬ cargoTreeTable »õÎï±í¸ñ£¬ feedbackButton ÎÊÌâ·´À¡°´Å¥£¬ progressBar ½ø¶ÈÌõËĸö²¿·ÖµÄ½»»¥¶¼ÊÇÔÚÔÚ src/controller Ï嵀 sidebar.js Öж¨ÒåµÄ¡£Í¨¹ý findViewById(id, recursive) ¸ù¾Ýid²éÕÒ×Ó×é¼þ£¬recursive ±íʾÊÇ·ñµÝ¹é²éÕÒ¡£

shelfTreeTable »õλͳ¼Æ±í¸ñµÄÊý¾Ý°ó¶¨´«Ê䷽ʽÓë cargoTreeTable »õÎï±í¸ñÀàËÆ£¬ÕâÀïÎÒÃÇÖ»¶Ô shelfTreeTable »õλͳ¼Æ±í¸ñµÄÊý¾Ý°ó¶¨½øÐнâÎö¡£shelfTreeTable Ò»¹²ÓÐÈýÁУ¬ÆäÖв»Í¬µÄ²¿·ÖÖ»ÓС°ÒÑÓᱺ͡°Ê£ÓࡱÁ½¸ö²¿·Ö£¬ËùÒÔÎÒÃÇÖ»Òª½«ÕâÁ½¸ö²¿·Ö½øÐÐÊý¾Ý°ó¶¨¼´¿É£¬ÏÈ´´½¨Á½ÁУº

let column = new ht.ui.Column();//ÁÐÊý¾Ý£¬ÓÃÓÚ¶¨Òå±í¸ñ×é¼þµÄÁÐÐÅÏ¢
column.setName('used');//ÉèÖÃÊý¾ÝÔªËØÃû³Æ
column.setAccessType('attr');//ÔÚÕâÀï name Ϊ used£¬²ÉÓà getAttr('used') ºÍ setAttr('used', 98) µÄ·½Ê½´æÈ¡ set/getAttr ¼òдΪ a
column.setWidth(65);
column.setAlign('center');
columnModel.add(column);
column = new ht.ui.Column();
column.setName('remain');
column.setAccessType('attr');
column.setWidth(65);
column.setAlign('center');
columnModel.add(column);

½Ó×űéÀú json Îļþ£¬½« json ÎļþÖжÔÓ¦µÄ used¡¢remainÒÔ¼° labelColors ͨ¹ý set/getAttr »ò ¼òд a µÄ·½Ê½½øÐÐÊý¾Ý°ó¶¨£º

for (var i = 0; i < json.length; i++) {
var row = json[i];//»ñÈ¡ json ÖеÄÊôÐÔ
var data = new ht.Data();
data.setIcon(row.icon);//½« json ÖÐµÄ icon ´«¹ýÀ´
data.setName(row.name);
data.a('used', row.used);
data.a('remain', row.remain);
data.a('labelColors', row.colors);
data.setIcon(row.icon);
treeTable.dm().add(data);//ÔÚÊ÷±í×é¼þµÄÊý¾ÝÄ£ÐÍÖÐÌí¼ÓÕâ¸ödata½Úµã
var children = row.children;
if (children) {
for (var j = 0; j < children.length; j++) {
var child = children[j];
var childData = new ht.Data();
childData.setName(child.name);
childData.setIcon(child.icon);
childData.a('used', child.used);
childData.a('remain', child.remain);
childData.a('labelColors', child.colors);
childData.setParent(data);
treeTable.dm().add(childData);
}
}
}

×îºóÔÚ controller º¯Êý¶ÔÏóÖе÷Óà Õâ¸öº¯Êý£º

initTreeTableDatas(shelfTreeTable, json);//json Ϊ ../model/shelf.json´«Èë

progressBar ½ø¶ÈÌõµÄ±ä»¯ÊÇͨ¹ýÉèÖö¨Ê±Æ÷¸Ä±ä progressBar µÄ value ÖµÀ´¶¯Ì¬¸Ä±äµÄ£º

setInterval(() => {
if (progressBar.getValue() >= 100) {
progressBar.setValue(0);
}
progressBar.setValue(progressBar.getValue() + 1);
}, 50);

feedbackButton ÎÊÌâ·´À¡°´Å¥£¬Í¨¹ýÔö¼Ó View ʼþ¼àÌýÆ÷À´¼àÌý°´Å¥µÄµã»÷ʼþ£º

feedbackButton.addViewListener(e => {
if (e.kind === 'click') {//HT ×Ô¶¨ÒåµÄʼþÊôÐÔ£¬¾ßÌå²é¿´ http://hightopo.com/guide/guide/core/beginners/ht-beginners-guide.html
window.location.href = "mailto:service@www.hightopo.com";//µ±Ç°Ò³Ãæ´ò¿ªURLÒ³Ãæ
}
});

ÓÒ²à¸ùÈÝÆ÷ splitLayout

Ö±½ÓÓõķָî×é¼þ ht.ui.SplitLayout ½øÐзָ¾Ö£º

let splitLayout = new ht.ui.SplitLayout();//´Ë²¼¾ÖÆ÷½«×ÔÉí¿Õ¼ä»®·ÖΪÉÏ¡¢ÏÂÁ½¸öÇøÓò»ò×ó¡¢ÓÒÁ½¸öÇøÓò£¬Ã¿¸öÇøÓò¿ÉÒÔ·ÅÖÃÒ»¸ö×Ó×é¼þ
splitLayout.setSplitterVisible(false);
splitLayout.setPositionType('absoluteFirst');
splitLayout.setOrientation('v');

ÓÒ²àÍ·²¿ header

Õâ¸ö header ÊÇ´Ó src/view Ï嵀 header.js ÖлñÈ¡µÄ¶ÔÏó£¬Îª ht.ui.RelativeLayout Ïà¶Ô¶¨Î»²¼¾ÖÆ÷£¬·ÖΪ 5 ¸ö²¿·Ö£ºsearchField ËÑË÷¿ò¡¢titleLabel Ö÷±êÌâ¡¢temperatureLabel1 ζȡ¢humidityLabel1 ʪ¶ÈÒÔ¼° airpressureLabel1 ÆøÑ¹¡£

ÕâÀïÎÒÃÇûÓжԡ°ËÑË÷¿ò¡± searchField ½øÐÐÊý¾Ý°ó¶¨£¬ÒÔ¼°ËÑË÷µÄ¹¦ÄÜ£¬ÕâÖ»ÊÇÒ»¸öÑùÀý£¬²»Éæ¼°ÒµÎñ²¿·Ö£º

let searchField = new ht.ui.TextField();//Îı¾¿ò×é¼þ
searchField.setBorder(new ht.ui.border.LineBorder(1, '#d8d8d8'));//ÔÚ×é¼þµÄ»­²¼ÉÏ»æÖÆÖ±Ï߱߿ò
searchField.setBorderRadius(12);
searchField.setBackground(null);
searchField.setIcon('imgs/search.json');
searchField.setIconPosition('left');
searchField.setPadding([2, 16, 2, 16]);
searchField.setColor('rgb(138, 138, 138)');
searchField.setPlaceholder('Find everything...');
searchField.getView().className = 'search';
header.addView(searchField, {
width: 180,
marginLeft: 20,
vAlign: 'middle'
});

¶ÔÓÚ titleLabel Ö÷±êÌâ±È½Ï¼òµ¥£¬ºÍζȡ¢Êª¶ÈÒÔ¼°ÆøÑ¹ÀàËÆ£¬ÎÒ¾Íֻ˵Ã÷Ò»ÏÂÖ÷±êÌâ titleLabel µÄ¶¨Ò壺

let titleLabel = new ht.ui.Label();//±êÇ©×é¼þ
titleLabel.setId('title');
titleLabel.setIcon('imgs/expand.json');
titleLabel.setTextColor('rgb(138, 138, 138)');
titleLabel.setText('º¼Öݲֿâ');
titleLabel.setHTextPosition('left');//ÉèÖÃÎÄ×ÖÔÚˮƽ·½ÏòÏà¶ÔÓÚͼ±êµÄλÖã¬Ä¬ÈÏֵΪ 'right'
titleLabel.setIconTextGap(10);//ÉèÖÃͼ±êºÍÎÄ×ÖÖ®¼äµÄ¼ä¾à
titleLabel.setBorder(new ht.ui.border.IndividualLineBorder(0, 0, 3, 0, '#3162e8'))//ÔÚ×é¼þµÄ»­²¼ÉÏ»æÖÆÖ±Ï߱߿ò£»Óë LineBorder ²»Í¬µÄÊÇ£¬´Ë±ß¿ò¿ÉÒÔµ¥¶À»æÖÆÄ³Ò»¸ö»ò¼¸¸ö·½ÏòµÄ±ß¿ò
titleLabel.setTextFont('16px arial');
header.addView(titleLabel, {
height: 'match_parent',
width: 'wrap_content',
align: 'center'
});

È»ºó½»»¥²¿·ÖÔÚ src/controller Ï嵀 header.js ÖÐ×öÁËÓÒ¼üµã»÷³öÏֲ˵¥À¸ÒÔ¼°µ¥»÷ titleLabel µÄλÖóöÏÖÏÂÀ­²Ëµ¥Á½ÖÖ½»»¥£¬Í¨¹ý¿ØÖÆÊó±êµÄµã»÷ʼþÀ´¿ØÖÆÊ¼þµÄ½»»¥£º

let title, contextMenu;
export default function controller (view) {
title = view.findViewById('title');
contextMenu = new ht.ui.ContextMenu();//ÓÒ¼ü²Ëµ¥×é¼þ
contextMenu.setLabelColor('rgb(138, 138, 138)');
contextMenu.setHoverRowBackground('#3664e4');
contextMenu.setItems([
{
label: '±±¾©²Ö¿â'
},
{
label: 'ÉϺ£²Ö¿â'
},
{
label: 'ÏÃÃŲֿâ'
}
]);
contextMenu.addViewListener((e) => {
if (e.kind === 'action') {//HT ×Ô¶¨ÒåµÄʼþÀàÐÍ
title.setText(e.item.label);
}
});
title.getView().addEventListener('mousedown', e => {
if (contextMenu.isInDOM()) {//ÅжÏ×é¼þÊÇ·ñÔÚ DOM Ê÷ÖÐ
contextMenu.hide();//Òþ²Ø²Ëµ¥
document.removeEventListener('mousedown', handleWindowClick);//ÒÆ³ýmousedown¼àÌýʼþ
}
else {//ûÓÐÓÒ¼üµã»÷¹ý
var items = contextMenu.getItems();
for (var i = 0; i < items.length; i++) {
items[i].width = title.getWidth();
}
let windowInfo = ht.Default.getWindowInfo(),//»ñÈ¡µ±Ç°´°¿Úleft|top|width|heightµÄ²ÎÊýÐÅÏ¢
titleRect = title.getView().getBoundingClientRect();
contextMenu.show(windowInfo.left + titleRect.left, windowInfo.top + titleRect.top + titleRect.height);
document.addEventListener('mousedown', handleWindowClick);
}
});
}
function handleWindowClick(e) {
if (!contextMenu.getView().contains(e.target) && !title.getView().contains(e.target)) {//ÅжÏÔªËØÊÇ·ñÔÚÊý×éÖÐ
contextMenu.hide();
document.removeEventListener('mousedown', handleWindowClick);
}
}

ÓÒ²àϲ¿·Ö RelativeLayout Ïà¶Ô²¼¾ÖÆ÷£¨Ïà¶ÔÓÚÓÒ²àϲ¿·Ö×î¸ù²ã div£©£¬°üº¬ÖмäÏÔʾ 3d ²¿·Ö graph3dView¡¢Ë«»÷»õ¹ñ»ò»õÎï²Å»á³öÏÖµÄ shelfPane¡¢ÒÔ¼°³öÏÖÔÚÓÒϽǵÄͼ±í chartPane£¬½«ÕâÈý²¿·ÖÌí¼Ó½ø RelativeLayout Ïà¶Ô²¼¾ÖÈÝÆ÷£º

let relativeLayout = new ht.ui.RelativeLayout();//´´½¨Ïà¶Ô²¼¾ÖÆ÷
relativeLayout.setId('contentRelative');
relativeLayout.setBackground('#060811');
var htView = new ht.ui.HTView(graph3dView);
htView.setId('contentHTView');
relativeLayout.addView(htView, {//½« 3d ×é¼þÌí¼Ó½ørelativeLayout Ïà¶Ô²¼¾ÖÆ÷
width: 'match_parent',
height: 'match_parent'
});
relativeLayout.addView(shelfPane, {//½«Ë«»÷³öÏÖµÄÏêϸÐÅÏ¢ shelfPane ×é¼þÌí¼Ó½ørelativeLayout Ïà¶Ô²¼¾ÖÆ÷
width: 220,
height: 'wrap_content',
align: 'right',
marginRight: 30,
marginTop: 30
});
relativeLayout.addView(chartPane, {//½«Í¼±í chartPane ×é¼þÌí¼Ó½ørelativeLayout Ïà¶Ô²¼¾ÖÆ÷
width: 220,
height: 200,
align: 'right',
vAlign: 'bottom',
marginRight: 30,
marginBottom: 30
})

È»ºó½«ÓÒ²àÏà¶Ô²¼¾ÖÆ÷ relativeLayout ºÍÓÒ²àÍ·²¿ header Ìí¼Ó½øÓÒ²àµ×²¿ÈÝÆ÷ splitLayout£º

let splitLayout = new ht.ui.SplitLayout();
splitLayout.setSplitterVisible(false);
splitLayout.setPositionType('absoluteFirst');
splitLayout.setOrientation('v');
splitLayout.addView(header, {
region: 'first'//Ö¸¶¨×é¼þËùÔÚµÄÇøÓò£¬¿ÉѡֵΪ£º'first'|'second'
});
splitLayout.addView(relativeLayout, {
region: 'second'
});

ÔÙ½«×ó²à²¿·ÖµÄ sidebar ºÍÓҲಿ·ÖµÄËùÓÐÒ²¾ÍÊÇ splitLayout Ìí¼Ó½øÕû¸öµ×²¿ÈÝÆ÷ borderLayout£¬ÔÙ½«µ×²¿ÈÝÆ÷Ìí¼Ó½ø html body ÌåÖУº

let borderLayout = new BorderLayout();
borderLayout.setLeftWidth(250);
borderLayout.addView(sidebar, {
region: 'left',// Ö¸¶¨×é¼þËùÔÚµÄÇøÓò£¬¿ÉѡֵΪ£º'top'|'right'|'bottom'|'left'|'center'
width: 'match_parent'//×é¼þ×ÔÉíÊ×Ñ¡¿í¶È
});
borderLayout.addView(splitLayout, {
region: 'center'
});

borderLayout.addToDOM();//½« borderLayout Ìí¼Ó½ø body ÌåÖÐ

ÎÒÃǾßÌå˵˵Õâ¸öÏà¶Ô²¼¾ÖÆ÷ÄÚ²¿°üº¬µÄ 3d ²¿·Ö graph3dView¡¢Ë«»÷»õ¹ñ»ò»õÎï²Å»á³öÏÖµÄ shelfPane¡¢ÒÔ¼°³öÏÖÔÚÓÒϽǵÄͼ±í chartPane¡£

(1) graph3dView

´Ó srcview3d Îļþ¼ÐÖÐµÄ index.js ÖлñÈ¡ graph3dView µÄÍⲿ½Ó¿Ú±» src/view ÖÐµÄ index.js µ÷Óãº

import graph3dView from './3d/index';

´ÓÕâ¸ö 3d ³¡¾°ÖпÉÒÔ¿´µ½£¬ÎÒÃÇÐèÒª¡°µØ°å¡±¡¢¡°Ç½Ã桱¡¢¡°»õ¼Ü¡±¡¢¡°²æ³µ¡±¡¢¡°»õÎÒÔ¼° 3d ³¡¾°¡£

ÔÚ 3d Îļþ¼ÐÏ嵀 index.js ÖУ¬ÎÒÃÇ´ÓÎļþ¼ÐÖе¼ÈëËùÓÐÐèÒªµÄ½Ó¿Ú£º

import {//ÕâÀïµ¼ÈëµÄ¶¼ÊÇһЩ»ù´¡Êý¾Ý
sceneWidth, sceneHeight, sceneTall,
toShelfList, randomCargoType
} from './G.js';
// Ä£ÄâÊý¾Ý½Ó¿Ú
import {
stockinout,// ³öÈë¿â
initiate,// ³õʼ»¯
inoutShelf// ÉÏϼÜ
} from './interfaces';
import { Shelf } from './shelf';//»õ¼Ü
import { Floor } from './floor';//µØ°å
import { Wall } from './wall';//Ç½Ãæ
import { Car } from './car';//²æ³µ
import { g3d } from './g3d';//3d³¡¾°
import { getCargoById } from './cargo';//»õÎï

g3d.js ÎļþÖÐÖ»ÉèÖÃÁ˳¡¾°ÒÔ¼°¶Ô²¿·ÖʼþµÄ¼àÌý£º

g3d.mi((e) => {// ¼àÌýʼþ addInteractorListener
const kind = e.kind;
if (kind === 'doubleClickData') {//Ë«»÷ͼԪʼþ
let data = e.data;//ʼþÏà¹ØµÄÊý¾ÝÔªËØ
if (data instanceof Shelf) {//Èç¹ûÊÇ»õ¼Ü
data.setTransparent(false);
eventbus.fire({ type: 'cargoBlur' });//ÅÉ·¢Ê¼þ£¬ÒÀ´Îµ÷ÓÃËùÓеļàÌýÆ÷º¯Êý
}
else {
data = data.a('cargo');
if (!data) return;
data.transparent = false;
eventbus.fire({ type: 'cargoFocus', data: data });
}
for (let i = shelfList.length - 1; i >= 0; i--) {//³ýÁËË«»÷µÄͼԪ£¬ÆäËûµÄͼԪ¶¼ÉèÖÃ͸Ã÷
const shelf = shelfList[i];
shelf.setTransparent(true, data);
}
return;
}
if (kind === 'doubleClickBackground') {//Ë«»÷±³¾°Ê¼þ
for (let i = shelfList.length - 1; i >= 0; i--) {//Ë«»÷±³¾°£¬ËùÓеÄͼԪ¶¼²»Í¸Ã÷
const shelf = shelfList[i];
shelf.setTransparent(false);
}
eventbus.fire({ type: 'cargoBlur' });
return;
}
});

ÎÒÃÇÔÚ G.js Öж¨ÒåÁËһЩ»ù´¡Êý¾Ý£¬ÆäËûÒýÓÃµÄ js Öж¼»á·´¸´µ÷ÓÃÕâЩ±äÁ¿£¬ËùÒÔÎÒÃÇÏÈÀ´½âÎöÕâ¸öÎļþ£º

const sceneWidth = 1200;//³¡¾°¿í¶È
const sceneHeight = 800;//³¡¾°¸ß¶È
const sceneTall = 410;//³¡¾°µÄÉî¶È
const globalOpacity = 0.3;//͸Ã÷¶È
const cargoTypes = {//»õÎïÀàÐÍ£¬·ÖΪËÄÖÖ
'cask': {//ľͰ
'name': 'bucket'
},
'carton': {//Ö½Ïä
'name': 'carton'
},
'woodenBox1': {//ľÏä1
'name': 'woodenBox1'
},
'woodenBox2': {//ľÏä2
'name': 'woodenBox2'
}
};

ÀïÃæÓÐÈý¸öº¯Êý£¬·Ö±ðÊÇ¡°»õ¼ÜµÄ obj ·Ö½â¡±¡¢¡°¼ÓÔØÄ£ÐÍ¡±¡¢¡°Ëæ»ú·ÖÅä»õÎïµÄÀàÐÍ¡±£º

function toShelfList(list) {//½«»õ¼ÜµÄ obj ·Ö½â£¬
const obj = {};
list.forEach((o) => {//Õâ±ßµÄ²ÎÊýo¾ßÌåÄÚÈÝ¿ÉÒԲ鿴 view/3d/interface.js
const strs = o.cubeGeoId.split('-');
let rs = obj[o.rackId];
if (!rs) {
rs = obj[o.rackId] = [];
}
const ri = parseInt(strs[2].substr(1)) - 1;
let ps = rs[ri];
if (!ps) {
ps = rs[ri] = [];
}
let type = 'cask';
if (o.inventoryType === 'Import') {
while((type = randomCargoType()) === 'cask') {}
}
const pi = parseInt(strs[3].substr(1)) - 1;
ps[pi] = {
id: o.cubeGeoId,
type: type
};
});
return obj;
}
function loadObj(shape3d, fileName, cbFunc) {//¼ÓÔØÄ£ÐÍ
const path = './objs/' + fileName;
ht.Default.loadObj(path + '.obj', path + '.mtl', {
shape3d: shape3d,
center: true,
cube: true,
finishFunc: cbFunc
});
}
function randomCargoType() {//Ëæ»ú·ÖÅä¡°»õÎµÄÀàÐÍ
const keys = Object.keys(cargoTypes);
const i = Math.floor(Math.random() * keys.length);
return keys[i];
}

Õâ¸ö 3d ³¡¾°Öл¹Óв»¿ÉȱÉٵġ°»õÎºÍ¡°»õ¼Ü¡±ÒÔ¼°¡°²æ³µ¡±£¬ÈýÕߵ͍Ò巽ʽÀàËÆ£¬ÕâÀïÖ»¶Ô¡°»õ¼Ü¡±½øÐнâÊÍ¡£ÎÒÃÇÖ±½ÓÔÚ¡°»õÎµÄ js ÖÐÒýÈëµ×ϵġ°ÍÐÅÌ¡±µÄ js Îļþ£¬½«ËüÃÇ¿´×öÒ»¸öÕûÌ壺

import { Pallet } from './pallet';
import {
cargoTypes,
loadObj,
globalOpacity
} from './G';

ÔÚ srcview3dcargo.js ÎļþÖУ¬¶¨ÒåÁËÒ»¸ö¡°»õÎÀ࣬Õâ¸öÀàÖÐÉùÃ÷Á˺ܶ෽·¨£¬±È½Ï»ù´¡£¬ÓÐÐèÒªµÄ×Ô¼º¿ÉÒԲ鿴Õâ¸öÎļþ£¬ÕâÀïÎÒ²»¹ý¶à½âÊÍ¡£Ö÷Òª½²Ò»ÏÂÈçºÎ¼ÓÔØÕâ¸ö¡°»õÎµÄ obj£¬ÎÒÃÇÔÚ G.js ÎļþÖÐÓж¨ÒåÒ»¸ö loadObj º¯Êý£¬ÎÒÃÇÔÚ´úÂë¶¥²¿Ò²ÓÐÒýÈ룬µ¼Èë obj ÎļþÖ®ºó¾ÍÔÚ¡°»õÎµÄ¿â´æÔö¼ÓÕâ¸ö¡°»õÎ£º

for (let type in cargoTypes) {//±éÀú cargoTypes Êý×飬 G.js Öж¨ÒåµÄ
const cargo = cargoTypes[type];
loadObj(type, cargo.name, (map, array, s3) => {//loadObj(shape3d, fileName, cbFunc) cbFunc ÖеIJÎÊý¿ÉÒԲο¼ [obj ÊÖ²á][9]
cargo.s3 = s3;//½« cargo µÄ s3 ÉèÖÃԭʼ´óС
updateCargoSize();
});
}
function updateCargoSize() {
let c, obj;
for (let i = cargoList.length - 1; i >= 0; i--) {
c = cargoList[i];
obj = cargoTypes[c.type];
if (!obj.s3) continue;
c.boxS3 = obj.s3;
}
}

»¹ÓоÍÊǽçÃæÉÏ¡°»õÎµÄ½ø³ö¿âµÄ¶¯»­£¬Ö÷ÒªÓõķ½·¨ÊÇ HT ·â×°µÄ ht.Default.startAnim º¯Êý£¨HT for Web ¶¯»­Êֲᣩ£¬³öµÄ¶¯»­Óë½øµÄ¶¯»­ÀàËÆ£¬ÕâÀﲻ׸Êö£º

// »õÎï½ø
in() {
if (anim) {//Èç¹ûÓÐÖµ£¬¾ÍÍ£Ö¹¶¯»­
anim.stop(true);
}
this.x = this.basicX + moveDistance;
this.opacity = 1;
anim = ht.Default.startAnim({
duration: 1500,
finishFunc: () => {//¶¯»­½áÊøÖ®ºóµ÷ÓÃÕâ¸öº¯Êý£¬½«animÉèÖÃΪ¿ÕÍ£Ö¹¶¯»­
anim = null;
},
action: (v, t) => {
this.x = this.basicX + (1 - v) * moveDistance;//¸Ä±äx×ø±ê£¬¿´ÆðÀ´ÏñÏòÇ°ÒÆ¶¯
}
});
}

ǽºÍµØ°åÒ²ÊDZȽϼòµ¥µÄ£¬¼òµ¥µØ¼Ì³Ð ht.Node ºÍ ht.Shape£¬ÕâÀïÒÔ¡°Ç½¡±½øÐнâÊÍ£¬¼Ì³ÐÖ®ºóÖ±½ÓÔÚ¹¹Ô캯ÊýÖнøÐÐÊôÐÔµÄÉèÖü´¿É£º

class Wall extends ht.Shape {//¼Ì³Ð ht.Shape Àà
constructor(points, segments, tall, thickness, elevation) {
super();
this.setPoints(points);//ÉèÖᰵ㡱
this.setSegments(segments);//ÉèÖá°µãÖ®¼äµÄÁ¬½Ó·½Ê½¡±
this.setTall(tall);//¿ØÖÆNodeͼԪÔÚyÖáµÄ³¤¶È
this.setThickness(thickness);//ÉèÖá°ºñ¶È¡±
this.setElevation(elevation);//¿ØÖÆNodeͼԪÖÐÐÄλÖÃËùÔÚ3D×ø±êϵµÄyÖáλÖÃ
this.s({
'all.transparent': true,//ÁùÃæÍ¸Ã÷
'all.opacity': 0.3,//͸Ã÷¶ÈΪ 0.3
'all.reverse.flip': true,//ÁùÃæµÄ·´ÃæÏÔʾÕýÃæµÄÄÚÈÝ
'bottom.visible': false//µ×Ãæ²»¿É¼û
});
}
}

floor¡¢wall¡¢shelf ÒÔ¼° car ÕâËĸöÀà¶¼×¼±¸Íê±Ï£¬Ö»ÐèÒªÔÚ srcview3dindex.js ÖÐ new Ò»¸öеĶÔÏó²¢¼ÓÈëµ½Êý¾ÝÄ£ÐÍ dataModel Öм´¿É£¬ÕâÀïֻչʾ car ¡°²æ³µ¡±µÄ³õʼ»¯´úÂ룺

// init Car
const car = new Car();
car.addToDataModel(dm);

ÖÁÓÚ¡°»õÎ£¬ÎÒÃÇÔÚÕâ¸ö js ÉÏÊDzÉÓö¨Ê±Æ÷µ÷Óà in ºÍ out ·½·¨£¬ÕâÀïÓÐÒ»¸öÄ£ÄâµÄÊý¾Ý¿â interfaces.js Îļþ£¬ÓÐÐèÇóµÄ¿ÉÒÔ¿´Ò»Ï£¬ÕâÀïÎÒÃÇÖ»µ±Êý¾ÝÀ´µ÷Ó㨽ø³ö¿âºÍÉÏϼÜÀàËÆ£¬ÕâÀïֻչʾ½ø³ö¿âµÄÉèÖ÷½·¨£©£º

// ÂÖѵµôÓóöÈë¿â½Ó¿Ú
setInterval(() => {
const obj = stockinout();//³öÈë¿â
let type = 'cask';
if (obj.inventoryType === 'Import') {
while((type = randomCargoType()) === 'cask') {}//Èç¹ûΪ¡°»õÎÀàÐÍΪ¡°Ä¾Í°¡±
}
car.cargoType = type;
if (obj.inOutStatus === 'I')//Èç¹ûֵΪ ¡°I¡±£¬Ôò½ø¿â
car.in();
else//·ñÔòΪ¡°o¡±£¬³ö¿â
car.out();
}, 30000);

(2) shelfPane

´Ó srcviewcommon Îļþ¼ÐÖÐµÄ shelfPane.js ÖлñÈ¡ graph3dView µÄÍⲿ½Ó¿Ú±» src/view ÖÐµÄ index.js µ÷Óãº

import shelfPane from './common/shelfPane.js';

shelfPane ÊÇ»ùÓÚ Pane ÀàµÄ£¬ÔÚ shelfPane.js ÎļþÖÐÒýÈëÕâ¸öÀàºÍʼþÅÉ·¢Æ÷£º

import Pane from './Pane.js';
import eventbus from '../../controller/eventbus';

Pane Àà¼Ì³ÐÓÚ HT ·â×°µÄ ht.ui.TabLayout À࣬ ²¢×öÁËÒ»Ð©ÌØ¶¨µÄÊôÐÔÉèÖãº

class Pane extends ht.ui.TabLayout {
constructor() {
super();
this.setBorder(new ht.ui.border.LineBorder(1, 'rgb(150,150,150)'));//ÉèÖÃ×é¼þµÄ±ß¿ò
this.setTabHeaderBackground(null);//ÉèÖñêÇ©Ðб³¾°£¬¿ÉÒÔÊÇÑÕÉ«»òÕßͼƬµÈ
this.setHoverTabBackground(null);//ÉèÖà Hover ״̬ϵıêÇ©±³¾°£¬¿ÉÒÔÊÇÑÕÉ«»òÕßͼƬµÈ
this.setActiveTabBackground(null);//ÉèÖà Active ״̬ϵıêÇ©±³¾°£¬¿ÉÒÔÊÇÑÕÉ«»òÕßͼƬµÈ
this.setTitleColor('rgb(184,184,184)');//ÉèÖÃÕý³£×´Ì¬Ï±êÇ©ÎÄ×ÖµÄÑÕÉ«
this.setActiveTitleColor('rgb(255,255,255)');//ÉèÖà Active ״̬ϱêÇ©ÎÄ×ÖµÄÑÕÉ«
this.setTabHeaderLineSize(0);//ÉèÖñêÇ©ÐзָîÏß¿í¶È
this.setMovable(false);//ÉèÖñêÇ©ÊÇ·ñ¿ÉÍÏ×§µ÷ÕûλÖã¬Ä¬ÈÏΪ true
this.setTabHeaderBackground('#1c258c');//ÉèÖñêÇ©Ðб³¾°£¬¿ÉÒÔÊÇÑÕÉ«»òÕßͼƬµÈ
this.setTabGap(0);//ÉèÖñêǩ֮¼äµÄ¾àÀë
}
getTabWidth(child) {//»ñȡָ¶¨×Ó×é¼þµÄ±êÇ©¿í¶È
const children = this.getChildren(),
size = children.size();
if (size === 0) {
return this.getContentWidth();//»ñÈ¡ÄÚÈÝ¿í¶È£¬¼´×é¼þ¿í¶È¼õÈ¥±ß¿ò¿í¶ÈºÍ×óÓÒÄڱ߾à¿í¶È
}
else {
return this.getContentWidth() / size;
}
}
drawTab(g, child, x, y, w, h) {//»æÖƱêÇ©
const children = this.getChildren(),//»ñÈ¡×Ó×é¼þÁбí
size = children.size(),
color = this.getCurrentTitleColor(child),//¸ù¾Ý²ÎÊý×Ó×é¼þµÄ״̬(normal¡¢hover¡¢active¡¢move)£¬»ñÈ¡±êÇ©ÎÄ×ÖÑÕÉ«
font = this.getTitleFont(child),//»ñÈ¡±êÇ©ÎÄ×Ö×ÖÌå
title = this.getTitle(child);//»ñȡָ¶¨×Ó×é¼þµÄ±êÇ©Îı¾
if (size === 1) {
ht.Default.drawText(g, title, font, color, x, y, w, h, 'left');//»æÖÆÎÄ×Ö
}
else {
ht.Default.drawText(g, title, font, color, x, y, w, h, 'center');
}
if (children.indexOf(child) < size - 1) {
g.beginPath();//¿ªÊ¼»æÖÆ
g.rect(x + w - 1, y + 4, 1, h - 8);
g.fillStyle = 'rgb(150,150,150)';
g.fill();
}
}
show() {
this.setVisible(true);//ÉèÖÃ×é¼þÊÇ·ñ¿É¼û
}
hide() {
this.setVisible(false);
}
}

ÎÒÃÇÕâ¸öÀý×ÓÖеġ°ÐÅÏ¢¡±ÁбíÊÇÒ»¸ö±í¸ñ×é¼þ£¬HT ͨ¹ý ht.ui.TableLayout º¯Êý¶¨ÒåÒ»¸ö±í¸ñ£¬È»ºóͨ¹ý ht.ui.TableRow Ïò±í¸ñÖÐÌí¼ÓÐУ¬Õâ¸öÀý×ÓÖеġ°±¸×¢¡±¡¢¡°±àºÅ¡±¡¢¡°À´Ô´¡±¡¢¡°Èë¿â¡±¡¢¡°·¢Íù¡±ÒÔ¼°¡°³ö¿â¡±¶¼ÊÇÎı¾¿ò£¬ÕâÀïÄá°±¸×¢¡±×÷Ϊ¾ÙÀý£º

let tableLayout = new ht.ui.TableLayout();//´Ë²¼¾ÖÆ÷½«×ÔÉí¿Õ¼ä°´ÕÕÐÐÁÐÊý»®·ÖΪ row * column ¸öµ¥Ôª¸ñ
tableLayout.setColumnPreferredWidth(0, 45);//ÉèÖÃÁÐÊ×Ñ¡¿í¶È
tableLayout.setColumnWeight(0, 0);//ÉèÖÃÁпí¶ÈÈ¨ÖØ£»Èç¹û²¼¾ÖÆ÷µÄ×Ü¿í¶È´óÓÚËùÓÐÁеÄÊ×Ñ¡¿í¶ÈÖ®ºÍ£¬ÄÇôʣÓàµÄ¿í¶È¾Í¸ù¾ÝÈ¨ÖØ·ÖÅä
tableLayout.setColumnPreferredWidth(1, 150);
tableLayout.setPadding(8);//ÉèÖÃ×é¼þÄڱ߾࣬²ÎÊýÈç¹ûÊÇÊý×Ö£¬ËµÃ÷ËıßʹÓÃÏàͬµÄÄڱ߾ࣻÈç¹ûÊÇÊý×飬Ôò¸ñʽΪ£º[Éϱ߾à, Óұ߾à, ϱ߾à, ×ó±ß¾à]
// ±¸×¢
var tableRow1 = new ht.ui.TableRow();//TableLayout ÖеÄÒ»ÐÐ×Ó×é¼þ£»
var label = new ht.ui.Label();//±êÇ©×é¼þ
label.setText('±¸×¢');//ÉèÖÃÎÄ×ÖÄÚÈÝ
label.setAlign('left');//ÉèÖÃÎÄ×ÖºÍͼ±êÔÚ°´Å¥Ë®Æ½·½ÏòµÄÕûÌå¶ÔÆë·½Ê½£¬Ä¬ÈÏΪ 'center'
label.setTextColor('rgb(255,255,255)');//ÉèÖÃÎÄ×ÖÑÕÉ«
var textField = new ht.ui.TextField();//Îı¾¿ò×é¼þ
textField.setFormDataName('remark');//ÉèÖÃ×é¼þÔÚ±íµ¥ÖеÄÃû³Æ
textField.setBackground(null);//ÉèÖÃ×é¼þµÄ±³¾°£¬¿ÉÒÔÊÇÑÕÉ«»òÕßͼƬµÈ£»´ËÖµ×îÖջᱻת»»Îª Drawable ¶ÔÏó
textField.setBorderRadius(0);//ÉèÖà CSS ±ß¿òÔ²½Ç
textField.setColor('rgb(138,138,138)');//ÉèÖÃÎÄ×ÖÑÕÉ«
textField.setPlaceholder('ÎÞ');//ÉèÖÃÊäÈëÌáʾ
textField.setBorder(new ht.ui.border.IndividualLineBorder(0, 0, 1, 0, 'rgb(138,138,138)'));//ÉèÖÃ×é¼þµÄ±ß¿ò
tableRow1.addView(label);//Ìí¼Ó×Ó×é¼þ
tableRow1.addView(textField);
tableLayout.addView(tableRow1);//½«×Ó×é¼þ¼Óµ½ÈÝÆ÷ÖÐ

¡°¹éÀࡱºÍ¡°Ä£ÐÍ¡±ÀàËÆ£¬¶¼ÊÇÏÂÀ­¿ò£¬ÎÒÃÇÓà HT ·â×°µÄ ht.ui.ComboBox ×éºÏ¿ò×é¼þ£¬¸ú ht.ui.TextField Ò²ÊÇÒìÇúͬ¹¤£¬Ö»ÊǾßÌå²Ù×÷²»Í¬¶øÒÑ£¬HT ÕâÑù×öʹÓÃÉϸü¼ò±ã¸üÈÝÒ×ÉÏÊÖ£¬ÕâÀïÎÒÃÇÒÔ¡°Ä£ÐÍ¡±½øÐнâÎö£¬ÔÚÉèÖá°ÏÂÀ­Êý¾Ý¡±µÄʱºòÎÒÃÇÀûÓÃÁË HT ÖеÄÊý¾Ý°ó¶¨£º

// Ä£ÐÍ
var tableRow4 = new ht.ui.TableRow();
label = new ht.ui.Label();
label.setText('Ä£ÐÍ');
label.setAlign('left');
label.setTextColor('rgb(255,255,255)');
var comboBox = new ht.ui.ComboBox();
comboBox.setFormDataName('model');
comboBox.setBackground(null);
comboBox.setColor('rgb(232,143,49)');
comboBox.setDatas([////ÉèÖÃÏÂÀ­Êý¾ÝÊý×é
{ label: 'Ö½Ïä', value: 'carton' },
{ label: 'ľÏä1', value: 'woodenBox1' },
{ label: 'ľÏä2', value: 'woodenBox2' },
{ label: 'ľͰ', value: 'cask' }
]);
comboBox.setIcon('imgs/combobox_icon.json');
comboBox.setHoverIcon('imgs/combobox_icon_hover.json');
comboBox.setActiveIcon('imgs/combobox_icon_hover.json');
comboBox.setBorderRadius(0);////ÉèÖà CSS ±ß¿òÔ²½Ç
comboBox.setBorder(new ht.ui.border.IndividualLineBorder(0, 0, 1, 0, 'rgb(138,138,138)'));
tableRow4.addView(label);
tableRow4.addView(comboBox);
tableLayout.addView(tableRow4);

×îºóÒ»¸ö¡°È¾É«¡±£¬HT ·â×°ÁË ht.ui.ColorPicker ÑÕɫѡÔñÆ÷×é¼þ£¬×é¼þ´Ó ht.ui.ComboBox ¼Ì³Ð²¢Ê¹Óà ht.ui.ColorDropDown ×÷ΪÏÂÀ­Ä£°å£¬¸úÉÏÃæµÄÏÂÀ­ÁбíºÜÀàËÆ£¬Ö»ÊÇÏÂÀ­µÄÄ£°å±äÁ˶øÒÑ£º

// Ⱦɫ
var tableRow9 = new ht.ui.TableRow();
label = new ht.ui.Label();
label.setText('Ⱦɫ');
label.setAlign('left');
label.setTextColor('rgb(255,255,255)');
var comboBox = new ht.ui.ColorPicker();//ÑÕɫѡÔñÆ÷×é¼þ
comboBox.setFormDataName('blend');//ÉèÖÃ×é¼þÔÚ±íµ¥ÖеÄÃû³Æ
comboBox.getView().className = 'content_colorpicker';
comboBox.setBackground(null);
comboBox.setPreviewBackground(null);//ÉèÖÃÔ¤ÀÀ±³¾°£»¿ÉÒÔÊÇÑÕÉ«»òÕßͼƬµÈ
comboBox.getInput().style.visibility = 'visible';//»ñÈ¡×é¼þÄÚ²¿µÄ input ¿òµÄ style Ñùʽ
comboBox.setReadOnly(true);//ÉèÖÃÖ»¶Á
comboBox.setColor('rgba(0,0,0,0)');
comboBox.setPlaceholder('Ð޸ĻõÏäÑÕÉ«');
comboBox.setIcon('imgs/combobox_icon.json');
comboBox.setHoverIcon('imgs/combobox_icon_hover.json');
comboBox.setActiveIcon('imgs/combobox_icon_hover.json');
comboBox.setBorderRadius(0);
comboBox.setBorder(new ht.ui.border.IndividualLineBorder(0, 0, 1, 0, 'rgb(138,138,138)'));
comboBox.setInstant(true);//ÉèÖü´Ê±Ä£Ê½£»ÔÚÕâÖÖģʽÏ£¬Ã¿ÊäÈëÒ»¸ö×Ö·û value ÊôÐԱ仯ʼþ¾Í»áÁ¢¼´±»ÅÉ·¢£¬·ñÔòÖ»ÓÐʧȥ½¹µã»òÇûسµÊ±²Å±»ÅÉ·¢
tableRow9.addView(label);
tableRow9.addView(comboBox);
tableLayout.addView(tableRow9);

×îºóͨ¹ý ht.ui.Form ×é¼þµÄ addChangeListener ʼþ¼àÌýº¯Êý¼àÌý JSON ÕûÌå±ä»¯Ê¼þºÍ JSON Öе¥ÌõÊý¾Ý±ä»¯Ê¼þ£¬ÕâÁ½ÖÖʼþµÄ½âÊÍÈçÏÂͼ£º

¾ßÌå¼àÌý·½·¨ÈçÏ£º

form.addChangeListener((e) => {
const cargo = form.__cargo__;
if (e.kind === 'formDataValueChange') {//JSON Öе¥ÌõÊý¾ÝÖµ±ä»¯Ê¼þ
const name = e.name;
let value = e.newValue;
if (name === 'blend') {
if (value && value.startsWith('rgba')) {
const li = value.lastIndexOf(',');
value = 'rgb' + value.substring(value.indexOf('('), li) + ')';
}
}
cargo.setValue(name, value);
}
});

È»ºóͨ¹ý HT ·â×°µÄʼþÅÉ·¢Æ÷ ht.Notifier ½«½çÃæÖв»Í¬ÇøÓòµÄ×é¼þÖ®¼äͨ¹ýʼþÅÉ·¢½øÐн»»¥£¬¸ù¾Ý²»Í¬µÄʼþÀàÐͽøÐв»Í¬µÄ¶¯×÷£º
eventbus.add((e) => {//Ôö¼Ó¼àÌýÆ÷ ʼþ×ÜÏߣ»½çÃæÖв»Í¬ÇøÓòµÄ×é¼þÖ®¼äͨ¹ýʼþÅÉ·¢½øÐн»»¥

if (e.type === 'cargoFocus') {
shelfPane.show();
const cargo = e.data;
form.__cargo__ = cargo;
const json = form.getJSON();//»ñÈ¡ÓÉ±íµ¥×é¼þµÄÃû³ÆºÍÖµ×é×°³ÉµÄ JSON Êý¾Ý
for (let k in json) {
form.setItem(k, cargo.getValue(k));
}
return;
}
if (e.type === 'cargoBlur') {
shelfPane.hide();
return;
}
});

(3) chartPane

´Ó srcviewcommon Îļþ¼ÐÖÐµÄ chartPane.js ÖлñÈ¡ graph3dView µÄÍⲿ½Ó¿Ú±» src/view ÖÐµÄ index.js µ÷Óãº

import chartPane from './common/chartPane.js';

chartPane ºÍ shelfPane ÀàËÆ£¬¶¼ÊÇ Pane ÀàµÄ¶ÔÏó£¬ÊôÐÔÒ²ÀàËÆ£¬²»Í¬µÄÊÇÄÚÈÝ¡£ÒòΪ½ñÌìչʾµÄÖ»ÊÇÒ»¸ö Demo£¬ÎÒÃDz¢Ã»ÓÐ×ö¹ý¶àµÄ¹ØÓÚͼ±í²å¼þµÄ´¦Àí£¬ËùÒÔÕâÀï¾ÍÓÃͼƬÀ´´úÌæ¶¯Ì¬Í¼±í£¬²»¹ý¾ÍËãÏë×öÒ²ÊǺÜÈÝÒ×µÄÊ£¬HT ÔËÓõÚÈý·½²å¼þÒ²ÊǺÜÈÝÒ×ÉÏÊֵģ¬¿ÉÒÔ¿´Õâ±ßµÄÀý×Ó http://hightopo.com/demo/larg...£¬HT ¹ÙÍøÉÏÓиü¶àÓÐȤµÄÀý×Ó£¡

»Øµ½ÕýÌ⣬chartPane ͼ±íÃæ°åµÄʵÏַdz£ÈÝÒ×£¬½«ÄÚ²¿µÄ×Ó×é¼þÉèÖñ³¾°Í¼Æ¬ÔÙÌí¼Ó½ø chartPane ͼ±íÃæ°åÖм´¿É£º

import Pane from './Pane.js';
var chartPane = new Pane();
var view1 = new ht.ui.View();
view1.setBackgroundDrawable(new ht.ui.drawable.ImageDrawable('imgs/chart.png', 'fill'));//ÉèÖÃ×é¼þµÄ±³¾° Drawable ¶ÔÏó£»×é¼þäÖȾʱÓÅÏÈʹÓÃ´Ë Drawable ¶ÔÏó£¬Èç¹ûΪ¿Õ£¬ÔÙÓà background ת»»
var view2 = new ht.ui.View();
view2.setBackgroundDrawable(new ht.ui.drawable.ImageDrawable('imgs/chart.png', 'fill'));
chartPane.getView().style.background = 'rgba(18,28,64,0.60)';//ÉèÖñ³¾°ÑÕÉ«
chartPane.addView(view1, {//½«×Ó×é¼þ¼Óµ½ÈÝÆ÷ÖÐ
title: 'ÆäËûͼ±í'
});
chartPane.addView(view2, {
title: '¿â´æ¸ºÔØ'
});

chartPane.setActiveView(view2);//ÉèÖÃÑ¡ÖеÄ×Ó×é¼þ

Õû¸öÀý×Ó½âÎöÍê±Ï£¬ÓÐÐËȤµÄС»ï°é¿ÉÒÔÈ¥ HT ¹ÙÍøÉÏ×Ôϰ²éÔÄ×ÊÁÏ£¬ºÃºÃƷ棬һ¶¨»á·¢ÏÖ¸ü´óµÄÊÀ½ç¡£

   
4156 ´Îä¯ÀÀ       28
Ïà¹ØÎÄÕÂ

Éî¶È½âÎö£ºÇåÀíÀôúÂë
ÈçºÎ±àд³öÓµ±§±ä»¯µÄ´úÂë
ÖØ¹¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
ÍŶÓÏîÄ¿¿ª·¢"±àÂë¹æ·¶"ϵÁÐÎÄÕÂ
Ïà¹ØÎĵµ

ÖØ¹¹-¸ÄÉÆ¼ÈÓдúÂëµÄÉè¼Æ
Èí¼þÖØ¹¹v2
´úÂëÕû½àÖ®µÀ
¸ßÖÊÁ¿±à³Ì¹æ·¶
Ïà¹Ø¿Î³Ì

»ùÓÚHTML5¿Í»§¶Ë¡¢Web¶ËµÄÓ¦Óÿª·¢
HTML 5+CSS ¿ª·¢
ǶÈëʽC¸ßÖÊÁ¿±à³Ì
C++¸ß¼¶±à³Ì