Skip to content

Commit 09c7d49

Browse files
committed
Merged from dev-scripter
2 parents a31a39f + ca5522b commit 09c7d49

29 files changed

Lines changed: 1371 additions & 592 deletions

demo/scripting/ccl.htm

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,17 @@
1414
pre{margin:0;}
1515
pre.error{color:#f00;}
1616
pre.warning{color:#FFC500;}
17+
.s-button, .abp .button{
18+
display:block; border:1px solid #f88; padding:8px 6px 8px 6px;
19+
background:#000; color:#f88; float:left;
20+
-moz-user-select: none;
21+
-khtml-user-select: none;
22+
-webkit-user-select: none;
23+
-o-user-select: none;
24+
user-select: none;
25+
cursor:default;
26+
}
27+
.s-button:hover,.abp .button:hover{background:#f88; color:#000;}
1728
</style>
1829
<!-- Scripting Extensions -->
1930
<script src="../../src/scripting/build/Host.js"></script>
@@ -138,14 +149,28 @@ <h2>Tests</h2>
138149
}
139150
function stop(){
140151
cm.stopTimer();
152+
if(cm.scripting){
153+
cm.scripting.send("Update:TimeUpdate",{
154+
"state":"pause",
155+
"time":playhead
156+
});
157+
}
141158
clearTimeout(tmr);
142159
}
143160
function resume(){
144161
cm.startTimer();
145162
start = new Date().getTime() - playhead;
163+
var lasthead = playhead;
146164
tmr = setInterval(function(){
147165
playhead = new Date().getTime() - start;
148166
cm.time(playhead);
167+
if(cm.scripting && playhead - lasthead > 300 ){
168+
cm.scripting.send("Update:TimeUpdate",{
169+
"state":"pause",
170+
"time":playhead
171+
});
172+
lasthead = playhead;
173+
}
149174
},10);
150175
}
151176
</script>

docs/scripting/Display/Root.md

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Root Element 根(舞台)对象
1111

1212
事件监听的潜在问题(Listener Problems)
1313
----------------------------------
14-
Root元素由于和其他的元素在监听器构造上有截然不同的设计需求,因为弹幕舞台很可能会由多个播放器同时
14+
Root元素和其他的元素在监听器构造上有截然不同的设计需求,因为弹幕舞台很可能会由多个播放器同时
1515
占用。在其余的API中,我们都可以认为 KagerouEngine 显示端可以独占舞台,但是在 root 元素上我们
1616
不能这样认为。这一限制条件,加之 [影子对象](../Instances.md) 的设计,由控制外播放元件产生的
1717
对象,我们没有沙箱内绑定。在触发诸如 `Event.ADDED` 事件时,我们就没有办法有效的体现这些对象的
@@ -77,4 +77,21 @@ stage.dispatchEvent(new CustomEvent("deregisterKagerou",{
7777
`ThisObjectName` 那个字段里面发挥。
7878

7979
### 使用临时的DisplayObject
80-
使用的时候要小心,
80+
使用的时候要小心,不是所有的属性都被支持,不是所有的值都会返回正确。还有就是把Object实例导出后
81+
有可能会遇到Object消亡。举例如下:
82+
83+
```JavaScript
84+
var outside;
85+
function listener(e){
86+
var tempDO = e.target;
87+
outside = tempDO;
88+
}
89+
$.root.addEventListener("added",listener);
90+
```
91+
92+
随后,这个Object消亡了。如果有正确的 deregister ,那么沙箱内的 Runtime 下应该不会注册这个
93+
Object,但是其依然可以根据保存的既有 objectId 调用沙箱外的 Context。但是因为对象一进不存在,
94+
所以调用会失败。
95+
96+
一般来说我们认为在监听器函数内部的连贯操作下应该不会发生 target 消亡的情况。但是这也不是保证。
97+

src/scripting/build/Host.js

Lines changed: 199 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ var CCLScripting = function(workerUrl){
295295
this.addListener("Runtime:UpdateProperty", function(pl){
296296
self.getContext().updateProperty(pl.id, pl.name, pl.value);
297297
});
298+
self.getContext().registerObject("__root", {"class":"SpriteRoot"});
298299
};
299300
})();
300301
/** Define some Unpackers **/
@@ -336,6 +337,7 @@ var CCLScripting = function(workerUrl){
336337
this.DOM = _("div",{
337338
"style":{
338339
"position":"absolute",
340+
"opacity":data.alpha != null ? data.alpha : 1
339341
},
340342
"className":"cmt"
341343
});
@@ -419,19 +421,23 @@ var CCLScripting = function(workerUrl){
419421
this.setFilters([f]);
420422
});
421423
this.setFilters = function(params){
424+
var shadows = [];
422425
for(var i = 0; i < params[0].length; i++){
423426
var filter = params[0][i];
424427
if(filter.type === "blur"){
425-
this.DOM.style.color = "transparent";
426-
this.DOM.style.textShadow = [0,0, Math.max(
428+
//this.DOM.style.color = "transparent";
429+
shadows.push([0,0, Math.max(
427430
filter.params.blurX, filter.params.blurY) +
428-
"px"].join(" ");
431+
"px"].join(" "));
429432
}else if(filter.type === "glow"){
430-
this.DOM.style.textShadow = [0,0, Math.max(
431-
filter.params.blurX, filter.params.blurY) +
432-
"px", getColor(filter.params.color)].join(" ");
433+
for(var i = 0; i < Math.min(2, filter.params.strength); i++){
434+
shadows.push([0,0, Math.max(
435+
filter.params.blurX, filter.params.blurY) +
436+
"px", getColor(filter.params.color)].join(" "));
437+
}
433438
}
434439
};
440+
this.DOM.style.textShadow = shadows.join(",");
435441
};
436442

437443
/** Common **/
@@ -545,7 +551,10 @@ var CCLScripting = function(workerUrl){
545551
});
546552
};
547553

548-
var state = {lastPath : null};
554+
var state = {
555+
lastPath : null,
556+
scheduleClear: [],
557+
};
549558

550559
/** Public methods **/
551560
this.setX = function(x){
@@ -670,6 +679,7 @@ var CCLScripting = function(workerUrl){
670679
applyFill(path, this);
671680
applyStroke(path, this);
672681
defaultGroup.appendChild(path);
682+
this._clear();
673683
};
674684
this.beginFill = function(params){
675685
if(params.length === 0)
@@ -683,6 +693,16 @@ var CCLScripting = function(workerUrl){
683693
this.fill.fill = "none";
684694
};
685695
this.drawRect = function(params){
696+
if(state.drawing)
697+
console.log(state.drawing);
698+
if(params[2] < 0){
699+
params[0] -= params[2];
700+
params[2] = -params[2];
701+
}
702+
if(params[3] < 0){
703+
params[1] -= params[3];
704+
params[3] = -params[3];
705+
}
686706
var r = __("rect",{
687707
"x": params[0],
688708
"y": params[1],
@@ -733,24 +753,43 @@ var CCLScripting = function(workerUrl){
733753
if(params[1].length % 3 !== 0){
734754
throw new Error("Illegal drawTriangles index argument. Indices array size must be a multiple of 3.");
735755
}
756+
var commands = [], data = [];
736757
for(var i = 0; i < params[1].length / 3; i++){
737758
var a = params[1][3 * i],
738759
b = params[1][3 * i + 1],
739760
c = params[1][3 * i + 2];
740761
var ax = params[0][2 * a], ay = params[0][2 * a + 1];
741762
var bx = params[0][2 * b], by = params[0][2 * b + 1];
742763
var cx = params[0][2 * c], cy = params[0][2 * c + 1];
743-
this.moveTo([ax,ay]);
744-
this.lineTo([bx,by]);
745-
this.lineTo([cx,cy]);
746-
this.lineTo([ax,ay]);
764+
commands.push(1,2,2,2);
765+
data.push(ax,ay,bx,by,cx,cy,ax,ay);
766+
}
767+
this.drawPath([commands,data,"evenOdd"]);
768+
};
769+
770+
this._clear = function(){
771+
if(state.scheduleClear.length < 1)
772+
return;
773+
if(state.scheduleTimer > -1){
774+
clearTimeout(state.scheduleTimer);
775+
state.scheduleTimer = -1;
747776
}
777+
while (defaultGroup.lastChild && state.scheduleClear.length > 0) {
778+
defaultGroup.removeChild(state.scheduleClear.pop());
779+
}
780+
state.scheduleClear = [];
748781
};
749782

750783
this.clear = function(){
751-
while (defaultGroup.lastChild) {
752-
defaultGroup.removeChild(defaultGroup.lastChild);
784+
var children = defaultGroup.children ? defaultGroup.children : defaultGroup.childNodes;
785+
for (var i = 0; i < children.length; i++) {
786+
state.scheduleClear.push(children[i]);
753787
}
788+
var self = this;
789+
state.scheduleTimer = setTimeout(function(){
790+
self._clear();
791+
state.scheduleTimer = -1;
792+
}, 60);
754793
};
755794

756795
this.__defineGetter__("filters", function(f){
@@ -761,7 +800,6 @@ var CCLScripting = function(workerUrl){
761800
});
762801
this.setFilters = function(params){
763802
var filters = params[0];
764-
//Remove old filters
765803
this.DOM.removeChild(defaultEffects);
766804
defaultEffects = __("defs");
767805
for(var i = 0; i < filters.length; i++){
@@ -851,6 +889,153 @@ var CCLScripting = function(workerUrl){
851889
data.scaleX = 1;
852890
data.scaleY = 1;
853891

892+
this.__defineSetter__("scaleX", function(f){
893+
if(f > 50)
894+
return;
895+
data.scaleX = f;
896+
return;
897+
for(var i = 0; i < this.DOM.children.length; i++){
898+
this.DOM.children[i].style.transform = "scale(" + data.scaleX + "," + data.scaleY + ")";
899+
}
900+
});
901+
this.__defineSetter__("scaleY", function(f){
902+
if(f > 50)
903+
return;
904+
data.scaleY = f;
905+
return;
906+
for(var i = 0; i < this.DOM.children.length; i++){
907+
this.DOM.children[i].style.transform = "scale(" + data.scaleX + "," + data.scaleY + ")";
908+
}
909+
});
910+
this.__defineGetter__("scaleX", function(f){
911+
return data.scaleX;
912+
});
913+
this.__defineGetter__("scaleY", function(f){
914+
return data.scaleY;
915+
});
916+
917+
this.__defineSetter__("x", function(f){
918+
this.setX(f);
919+
});
920+
this.__defineSetter__("y", function(f){
921+
this.setY(f);
922+
});
923+
this.__defineGetter__("x", function(f){
924+
return this.DOM.offsetLeft;
925+
});
926+
this.__defineGetter__("y", function(f){
927+
return this.DOM.offsetTop;
928+
});
929+
930+
this.setX = function(x){
931+
this.DOM.style.left = x + "px";
932+
};
933+
934+
this.setY = function(y){
935+
this.DOM.style.top = y + "px";
936+
};
937+
938+
this.setWidth = function(width){
939+
this.DOM.style.width = width + "px";
940+
};
941+
942+
this.setHeight = function(height){
943+
this.DOM.style.height = height + "px";
944+
};
945+
946+
this.addChild = function(childitem){
947+
var child = ctx.getObject(childitem);
948+
if(!child)
949+
return;
950+
if(child.DOM){
951+
if(child.getClass() === "Shape"){
952+
child.DOM.style.left = -this.x + "px";
953+
child.DOM.style.top = -this.y + "px";
954+
child.setX(this.x);
955+
child.setY(this.y);
956+
}
957+
this.DOM.appendChild(child.DOM);
958+
}else{
959+
ctx.invokeError("Sprite.addChild failed. Attempted to add non object","err");
960+
}
961+
};
962+
963+
this.removeChild = function(childitem){
964+
var child = ctx.getObject(childitem);
965+
if(!child)
966+
return;
967+
try{
968+
this.DOM.removeChild(child.DOM);
969+
}catch(e){
970+
ctx.invokeError(e.stack, "err");
971+
}
972+
};
973+
974+
this.unload = function(){
975+
try{
976+
stage.removeChild(this.DOM);
977+
}catch(e){};
978+
};
979+
// Hook child
980+
stage.appendChild(this.DOM);
981+
}
982+
983+
ScriptingContext.prototype.Unpack.SpriteRoot = function(stage, data, ctx){
984+
this.DOM = stage;
985+
this.addChild = function(childitem){
986+
var child = ctx.getObject(childitem);
987+
if(!child)
988+
return;
989+
if(child.DOM){
990+
if(child.getClass() === "Shape"){
991+
child.DOM.style.left = -this.x + "px";
992+
child.DOM.style.top = -this.y + "px";
993+
child.setX(this.x);
994+
child.setY(this.y);
995+
}
996+
this.DOM.appendChild(child.DOM);
997+
}else{
998+
ctx.invokeError("Sprite.addChild failed. Attempted to add non object","err");
999+
}
1000+
};
1001+
1002+
this.removeChild = function(childitem){
1003+
var child = ctx.getObject(childitem);
1004+
if(!child)
1005+
return;
1006+
try{
1007+
this.DOM.removeChild(child.DOM);
1008+
}catch(e){
1009+
ctx.invokeError(e.stack, "err");
1010+
}
1011+
};
1012+
};
1013+
1014+
ScriptingContext.prototype.Unpack.Button = function(stage, data, ctx){
1015+
this.DOM = _("div",{
1016+
"className":"button",
1017+
"style":{
1018+
"position":"absolute",
1019+
"top": data.y ? data.y + "px" : "0px",
1020+
"left": data.x ? data.x + "px" : "0px"
1021+
}
1022+
},[_("text", data.text)]);
1023+
1024+
data.scaleX = 1;
1025+
data.scaleY = 1;
1026+
this.__defineSetter__("filters", function(f){
1027+
// Ignore now
1028+
});
1029+
this.__defineGetter__("filters", function(f){
1030+
return [];
1031+
});
1032+
this.__defineSetter__("alpha", function(f){
1033+
data.alpha = Math.min(Math.max(f,0),1);
1034+
this.DOM.style.opacity = data.alpha + "";
1035+
});
1036+
this.__defineGetter__("alpha", function(f){
1037+
return data.alpha !== undefined ? data.alpha : 1;
1038+
});
8541039
this.__defineSetter__("scaleX", function(f){
8551040
if(f > 50)
8561041
return;

0 commit comments

Comments
 (0)