如何在EaselJs中使用文本覆盖位图图像

时间:2015-07-27 15:21:54

标签: createjs

我希望将文本叠加在EaselJs画布内的位图之上。

在我的代码中,首先使用PreloadJS加载图像。然后在此之后添加了文本。它们都以x = 0开始,y = 0,宽度和高度不同。因此,为了显示文本,我需要将它放在图像的顶部。

我有一种基于参数显示文本或图像的方法,即DisplayObj。所以基本上,我必须调用DisplayObj(img),然后调用DisplayObj(text)。但是,这将导致文本显示在图像后面。如果我改变我的代码而不是做2个函数调用,我只是在显示图像之后放置显示文本的逻辑,只调用一次并且它工作。然而,这不是我想要的,因为有时候,文本和图像不需要相互叠加,因此这种方法似乎不太好。

有关如何使用Easel和jQuery执行此操作的任何建议吗?

以下是我在Typescript中编写的函数:

function DisplayContentObject(c_xml: any): JQueryPromise<any> {
//var deferred: JQueryDeferred<any> = $.Deferred();
//var promise: JQueryPromise<any> = deferred.promise();

if (c_xml.attributes.is_visible.value === "1") {
    if (c_xml.attributes.type.value.toLowerCase().indexOf("text") > -1) {
        let x: number = +c_xml.attributes.content_pos.value.split(",")[0];
        let y: number = +c_xml.attributes.content_pos.value.split(",")[1];
        let width: number = +c_xml.attributes.content_size.value.split(",")[0];
        let height: number = +c_xml.attributes.content_size.value.split(",")[1];
        var text = c_xml.attributes.data.value;
        var textElement = new createjs.Text(text, "16px Times New Roman", "#00F");
        textElement.x = x + 10;
        textElement.y = y + 10;

        textElement.lineWidth = width;
        textElement.maxWidth = width;
        textElement.lineHeight = 20;

        stage.addChild(textElement);
        stage.update();
        displayContentDeffered.resolve();
    }
    if (c_xml.attributes.type.value.toLowerCase().indexOf("audio") > -1) {
        var fe: string = c_xml.attributes.filename.value.split(".")[1].toLowerCase();
        if (fe === "swf") {
        } else if (fe === "mp3") {
            createjs.Sound.stop();
            createjs.Sound.addEventListener("fileload", SoundFileLoaded);
            createjs.Sound.alternateExtensions = ["mp3"];
            createjs.Sound.registerSound({ id: "audio", src: media_path + c_xml.attributes.filename.value });
        }
        displayContentDeffered.resolve();
    }
    if (c_xml.attributes.type.value.toLowerCase().indexOf("visual") > -1) {
        var file: string = c_xml.attributes.filename.value;
        if (file.indexOf("swf") === -1) {
            let _x: number = +c_xml.attributes.content_pos.value.split(",")[0];
            let _y: number = +c_xml.attributes.content_pos.value.split(",")[1];
            let _w: number = +c_xml.attributes.content_size.value.split(",")[0];
            let _h: number = +c_xml.attributes.content_size.value.split(",")[1];
            var manifest = [
                {
                    src: media_path + file,
                    id: "img", x: _x, y: _y, w: _w, h: _h
                }
            ];
            preload = new createjs.LoadQueue(true);
            preload.on("complete", ImageFileLoaded, this);
            preload.loadManifest(manifest);
        } else
            displayContentDeffered.resolve();
    }
} else {
    if (c_xml.attributes.type.value.toLowerCase().indexOf("audio") > -1) {
        var fe: string = c_xml.attributes.filename.value.split(".")[1].toLowerCase();
        if (fe === "swf") {
        } else if (fe === "mp3") {
            createjs.Sound.stop();
            createjs.Sound.addEventListener("fileload", SoundFileLoaded);
            createjs.Sound.alternateExtensions = ["mp3"];
            createjs.Sound.registerSound({ id: "audio", src: media_path + c_xml.attributes.filename.value });
        }
    }
    displayContentDeffered.resolve();
}   

return displayContentPromise;
}

该函数接受一个包含应显示的信息的XMLObject。此XMLObject可以包含文本信息或图像URL。在循环中调用此函数。

总的来说:

  • 我有一个要显示的对象列表。假设 contents = [a,b,c] a 是声音, b 是图片, c 是文字。
  • 在循环中,迭代内容对象并使用DisplayObj函数显示每个对象。

问题出现在b我正在使用PreloadJS加载图像并处理OnComplete事件中的加载逻辑。正如我所知,在完成 c 之前,OnComplete尚未完成。因此,在这种情况下,加载顺序将是 a - c - b ,因此文本位于图像下方。我仍在尝试使用jQuery Deffered但到目前为止没有成功。

1 个答案:

答案 0 :(得分:0)

看起来你已经确定了你的竞争条件。你可以做几件事。

  1. 创建占位符Container并立即将其添加到舞台。然后,当预加载器完成后,将图像添加到该容器而不是舞台,您将获得适当的分层。

  2. 在解析XML之前预先加载所有图像,以便它们已在内存中可用,以便添加。