我觉得花太多篇幅讲数据封装有点跑题了。但是既然开始了,那就做完。
按上篇的约定,这篇说GroupHelper。
GroupHelper目的是管理一个较长的一维数组,具有data和array两个属性。data是数据本身,array是对应的ArrayHelper的数组。

function GroupHelper(count, model){ this.data = [];
this.array = [];
}
GroupHelper.prototype = { /* 根据参数判断attach或者add */
init : function(arg1, arg2){ if(arg1 instanceof Array){ this.attach(arg1);
} else{ this.add(arg1, arg2);
}
},
/* 以model数组作为模板,添加count个数据 */
add : function(count, model){ if(typeof count == 'number' && count > 0 && model instanceof Array){ if(typeof this.fix == 'function'){ model = this.fix(model);
}
var offset = this.data.length;
ArrayHelper.model(model, count, this.data);
if(typeof this.creator == 'function'){ for(var i = 0; i < count; i++){ this.array.push(this.creator(this.data, offset));
offset += model.length;
}
}
offset = null;
}
},
/* 将对象附加到一个现有大数组中。data重置,array清空并重新建立。 */
attach : function(arr){ if(!(arr instanceof Array)) return;
this.data = arr;
this.array = [];
if(typeof this.creator == 'function'){ var o = this.creator();
var step = Math.max(1, o.length || 1);
o = null;
for(var i = 0; i < this.data.length; i += step){ this.array.push(this.creator(this.data, i));
}
}
}
}
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
子类在继承之后,应建立相应fix和creator方法。
fix是在执行add方法时,对model数组模板的修复,比如颜色数组模板,每个值应取值在0~1内。
creator是在子类中必须创建的,它应返回一个ArrayHelper实例,用于构建array。
function ColorGroup(){ this.init(arguments[0], arguments[1]); } Inherit.inherit(ColorGroup, new GroupHelper(), { fix : function(model){ var oriLen = model.length;
for(var i = 0; i < 4; i++){ model[i] = ColorHelper.Fix(model[i]);
}
if(oriLen < 4){ model[3] = 1;
}
model = model.slice(0, 4);
oriLen = i = null;
return model;
},
creator : function(data, offset){ return new ColorHelper(data, offset);
},
rand : function(){ for(var i = 0; i < this.array.length; i++){ this.array[i].rand();
}
i = null;
}
});
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
以上代码为颜色总管。可以尝试以下代码:
var cg = new ColorHelper();
cg.add(4, [.5,.5,.5,1])
alert(cg.data);
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
然后我根据立方体着色需求,写个专用函数来产生和管理立方体色彩数组的对象,并定义几个便于管理的方法。
function CubeColors(){ var cs = new ColorGroup(24, [.5, .5, .5, 1]);
Inherit.extend(cs, { /* 每个面的 a b c d 分别对应4个顶点的颜色,按CSS颜色方式赋值。参数不够时将前一个参数传递给下一个 */
Front : function(a, b, c, d){ SET(cs, a, b, c, d, 0, 1, 2, 3); }, Back : function(a, b, c, d){ SET(cs, a, b, c, d, 4, 5, 6, 7); }, Top : function(a, b, c, d){ SET(cs, a, b, c, d, 8, 9, 10, 11); }, Bottom : function(a, b, c, d){ SET(cs, a, b, c, d, 12, 13, 14, 15); }, Right : function(a, b, c, d){ SET(cs, a, b, c, d, 16, 17, 18, 19); }, Left : function(a, b, c, d){ SET(cs, a, b, c, d, 20, 21, 22, 23); } });
return cs;
function set(cs, i, v){ typeof v == 'string' && cs.array[i].set(v);
}
function SET(cs, a, b, c, d, A, B, C, D){ var v = 0;
set(cs, A, v = a || v);
set(cs, B, v = b || v);
set(cs, C, v = c || v);
set(cs, D, v = d || v);
v = null
}
}
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
使用方法:
var cs = CubeColors();
cs.Front('fa0', 'fa0', 'f00', 'f00'); cs.Back('060', '060', '0e0', '0e0'); cs.Top('0af', '0af', '00f', '00f'); cs.Bottom('f09', 'f09', 'f0f', 'f0f'); cs.Right('fff', 'fff', '888', '888'); cs.Left('0f0', '0f0', '0a0', '0a0'); //cs.rand();
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

代码末尾那个rand(),可产生随机颜色,可以试试,略有些诡异。

附本篇与上篇的代码
ArrayHelper_beta_1.0.js
WebGL-Step-04pro.html
下篇讲灯光