单击按钮时访问根阶段实例

时间:2016-01-18 11:53:12

标签: html5 flash html5-canvas createjs

我在舞台上有一个名为myBtn的按钮实例,以及一个名为myContainer的方形影片剪辑的实例 - 所有这些都是从flash发布的。
myContainer中我有一个名为mySquare的movieclip实例,它通过传统补间动画从舞台的一个点到另一个点。
加载阶段后,我使用this.myBtn.on("click", startBtnOnClick)向按钮添加事件监听器,确实成功调用了函数startBtnOnClick(evt)。 我想要实现的是告诉myContainer在点击按钮时开始播放,并且这样做我当前需要使用:
evt.target.parent.parent.myContainer.gotoAndPlay(0)有效,但似乎不是最佳做法。
什么是更合适的方法?

使用HTML5文档类型从Adobe Flash发布时生成代码。我的补充是startBtnOnClick()函数定义,并将事件处理程序分配给myBtn实例

编辑:

我发布时会创建两个文件。要播放电影,请打开html文件。

SquareTrial.html:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SquareTrial</title>

<script src="http://code.createjs.com/easeljs-0.8.1.min.js"></script>
<script src="http://code.createjs.com/tweenjs-0.6.1.min.js"></script>
<script src="http://code.createjs.com/movieclip-0.8.1.min.js"></script>
<script src="SquareTrial.js"></script>

<script>
var canvas, stage, exportRoot;

function init() {
    canvas = document.getElementById("canvas");
    exportRoot = new lib.SquareTrial();

    stage = new createjs.Stage(canvas);
    stage.addChild(exportRoot);
    stage.update();

    createjs.Ticker.setFPS(lib.properties.fps);
    createjs.Ticker.addEventListener("tick", stage);
}
</script>
</head>

<body onload="init();" style="background-color:#D4D4D4">
    <canvas id="canvas" width="550" height="400" style="background-color:#FFFFFF"></canvas>
</body>
</html>

和SquareTrial.js:

(function (lib, img, cjs, ss) {

var p; // shortcut to reference prototypes

// library properties:
lib.properties = {
    width: 550,
    height: 400,
    fps: 24,
    color: "#FFFFFF",
    manifest: []
};


// functions:

function startBtnOnClick(evt)
{
    console.log("startBtnOnClick called.");

    console.log("stage:");
    console.log(stage);

    console.log("stage.myContainer:");
    console.log(stage.myContainer);

    console.log("this.myContainer:");
    console.log(this.myContainer);
}


// symbols:


(lib.MySquare = function() {
    this.initialize();

    // Layer 1
    this.shape = new cjs.Shape();
    this.shape.graphics.f().s("#000000").ss(1,1,1).p("AoWoWIQtAAIAAQtIwtAAg");
    this.shape.setTransform(53.5,53.5);

    this.shape_1 = new cjs.Shape();
    this.shape_1.graphics.f("#6633FF").s().p("AoWIXIAAwtIQtAAIAAQtg");
    this.shape_1.setTransform(53.5,53.5);

    this.addChild(this.shape_1,this.shape);
}).prototype = p = new cjs.Container();
p.nominalBounds = new cjs.Rectangle(-1,-1,109,109);


(lib.MyBtn = function() {
    this.initialize();

    // Layer 1
    this.shape = new cjs.Shape();
    this.shape.graphics.f().s("#000000").ss(1,1,1).p("AprjWITXAAIAAGtIzXAAg");
    this.shape.setTransform(62,21.5);

    this.shape_1 = new cjs.Shape();
    this.shape_1.graphics.f("#0099FF").s().p("AprDXIAAmtITXAAIAAGtg");
    this.shape_1.setTransform(62,21.5);

    this.addChild(this.shape_1,this.shape);
}).prototype = p = new cjs.Container();
p.nominalBounds = new cjs.Rectangle(-1,-1,126,45);


(lib.MyContainer = function(mode,startPosition,loop) {
    this.initialize(mode,startPosition,loop,{});

    // Layer 1
    this.mySquare = new lib.MySquare();
    this.mySquare.setTransform(53.5,53.5,1,1,0,0,0,53.5,53.5);

    this.timeline.addTween(cjs.Tween.get(this.mySquare).to({x:397.5},47).wait(1));

}).prototype = p = new cjs.MovieClip();
p.nominalBounds = new cjs.Rectangle(-0.5,-0.5,108,108);


// stage content:
(lib.SquareTrial = function() {
    this.initialize();

    // button
    this.myContainer = new lib.MyContainer();
    this.myContainer.setTransform(102.5,99.5,1,1,0,0,0,53.5,53.5);

    this.myBtn = new lib.MyBtn();
    this.myBtn.setTransform(111,337.5,1,1,0,0,0,62,21.5);

    //this.myBtn.on("click", startBtnOnClick); //<< does not work
    this.myBtn.on("click", startBtnOnClick, this);


    this.addChild(this.myBtn,this.myContainer);
}).prototype = p = new cjs.Container();
p.nominalBounds = new cjs.Rectangle(323.5,245.5,125,314);

})(lib = lib||{}, images = images||{}, createjs = createjs||{}, ss = ss||{});
var lib, images, createjs, ss;

1 个答案:

答案 0 :(得分:1)

如果您只是在寻找舞台,可以在任何显示对象上使用stage属性(getter),该对象返回实例所在的舞台。如果无法到达舞台,它将返回null。

var stage = evt.target.stage;

否则,您可能希望查看您的应用程序架构。例如,您可以通过将this作为on()方法的第3个参数传递,将事件处理程序绑定到当前范围。这会使您的startBtnOnClick方法在您的应用范围内触发,而不是让您查看相对于点击按钮的范围。

this.myBtn.on("click", startBtnOnClick, this);

[根据发布的内容进行编辑]

您的更新显示myContainer是您的Flash阶段的子项,它实际上是作为库JS中的SquareTrial函数导出的(以您的FLA命名)。此类在HTML中实例化为exportRoot

在库中定义函数的方式有点不正统。它基本上是一个匿名函数,但更大的问题是,如果从Flash重新导出库,它将被覆盖。我建议将其移动到您包含的另一个脚本,或者实际将其包含在您的帧脚本中。

无论如何,关于实际功能。由于您使用on()方法在范围内调用它,因此this变量将引用SquareTrial实例(也称为exportRoot)。您应该可以在this.myContainer方法中引用startBtnOnClick

我建议的stage getter并不理想,因为EaselJS阶段只包含exportRoot。它还需要以this.stage的形式访问。您使用stage引用存在,但它是在index.html中创建的全局变量。

因此,使用新方法,您应该能够这样做:

// In your frame script:
this.myBtn.on("click", startBtnOnClick, this); 

// In your function callback
console.log(this); // Should be the instance, and NOT window.
this.myContainer.gotoAndPlay(0);

如果您决定坚持使用无范围的匿名函数,那么您可以通过全局exportRoot变量引用您的内容:

exportRoot.myContainer.gotoAndPlay(0);

希望能够解决任何困惑。