Flash/Animate CC Tween 格式的数字

Flash/Animate CC Tween Formatted Number

我正在使用 Animate CC(erstwhile Flash CC) to do some ads that I'm exporting in HTML5 format (<canvas> and CreateJS 东西)。他们总体上工作得很好。

我在静态文本框中有一个格式化的数字,如下所示:5,000,000 我想在 30 帧的过程中将其补间为 20,000。我想在整个场景过程中将相同的文本补间到 5,0001,000,000 等等。

在我有限的 Animate CC 经验中,我设法避免使用任何 Javascript,但我想我现在需要这样做。那么,我的问题是:我该怎么做?


我对这样做的想法:

因为我使用的是 CreateJS,它有 TweenJS 库作为它的一部分,也许我可以只用它来补间?在我的时间轴的不同点做一些小动作?不确定这一切是如何工作的,很多在线参考资料都是针对 ActionScript 3 甚至 AS2 的。示例代码将不胜感激。

如果我进入 Javascript,我将如何进行数字格式化的问题。我可以将数字补间为 5000000 -> 20000 并在每个帧更新中插入逗号,这是一种方法。但让事情变得更复杂的是,这些广告将被翻译,并且不同的语言环境也会混合在一起。所以在英语中你会得到 5,000,000,在德语中你会得到 5.000.000,当然。

由于我们在浏览器中讨论 Javascript,我知道方法 Number.prototype.toLocaleString() 执行以下操作:

The toLocaleString() method returns a string with a language sensitive representation of this number.

这似乎可以解决问题,但我不得不担心浏览器的兼容性以及如果我不指定语言环境会发生什么。理想情况下,由于德语广告只会显示给在其 browser/OS 上具有德语区域设置的用户,我可以在不指定任何区域设置的情况下调用该方法,它会从用户的计算机上读取它。我想可能会出现德国人看到英文广告的情况,但我 不担心。

然而,在 MDN page for toLocaleString() 上,它有关于早期版本的 FF 默认为西方阿拉伯数字的警告,所以我完全怀疑该方法的使用。


最后,我有一个有趣的事实,即译者几乎肯定会将 5,000,000 转换为德语的 5.000.000。因此可以避免使用 toLocaleString(),因为我已经有了本地化的文本。因此,如果可以编写一个简单的 Javascript 函数来补间任意格式的数字,我认为就可以了。也许:

从 JS 的角度来看可能没那么难,但我被难住了的地方是我怎么会在 Animate/Flash and/or 和 CreateJS/TweenJS 中做到这一点?

就使用 TweenJS 补间格式化数字而言,您可以只补间非格式化数字,然后在 "change" 上创建一个格式化版本来执行您需要的操作:

createjs.Tween.get(obj, {loop:true})
    .to({val:10000}, 4000)
  .to({val:0}, 4000)
  .on("change", formatNumber);

function formatNumber(event) {
    // Round and format
    var formattedNumber = (obj.val|0).toLocaleString();
}

这是一个简单的fiddle:http://jsfiddle.net/m3req5g5/

尽管 Lanny 提供了一些很好的数据,但我还是想详细说明我最终做了什么来让这个工作正常进行。

首先,您需要以某种方式获得对要补间的对象的引用。当您在 Flash 中创建一个动作并写入 Javascript 时,this 将绑定到舞台,或者绑定到您正在编辑的 MovieClip 或 Graphic: http://createjs.com/html5ads/#Scope

您可以使用对象的 实例名称 访问对象,这些名称在 Flash 中定义在对象的属性上,一旦您将对象放置在舞台上。一些在线消息来源说它是基于 符号名称 或类似名称,但我还没有发现是这样。

// Get a reference to the object you want to tween
var obj = this.anInstanceName;

请注意,如果您想访问 inside MovieClip 中的内容,您需要在舞台上为您的 MovieClip 指定一个实例名称,然后进入 MovieClip 内部并为您的目标对象提供一个实例名称。然后你可以沿着层次结构走下去:

// Get a reference to the nested object you want to tween.
var obj = this.movieClipInstanceName.nestedInstanceName;

现在您可以对相关对象的任何数字 属性 进行补间。对我来说,因为我想对文本进行补间,所以我在对象上设置了一个额外的 属性 并对其进行补间,然后在进行过程中将其格式化并复制到文本 属性 中。

能够指定补间持续了多少帧而不是毫秒很有用,所以我传递了 useTicks 标志。

obj.counter = 0;
createjs.Tween.get(obj, {useTicks: true})
    .to({counter: 100}, 30) // <- 30 frames, this number is ms without useTicks
    .on("change", formatNumber);

function formatNumber(event) {
    obj.text = obj.counter.toLocaleString();
}

以上是普遍适用的。否则,这是我最终使用的工作代码。它应该能够被放入 HTML5 Canvas 项目中的 Flash Action 中并正常工作。

// Figures for tweening
var textStart = "2,000";
var textEnd = "6,000,000";

// Locate our target text box
var target = this.myTextBox; // replace "myTextBox" with your instance name

// Get our formatting data and so on
var data = this.getFormatData(textStart);

// Set up the text box
target.number = data.number;
target.text = textStart;

// Get the raw number we're tweening to
var endNumber = this.getFormatData(textEnd).number;

// Create the tween
createjs.Tween.get(target, {useTicks: true})
  .to({number:endNumber}, 30)
  .on("change", format);

//Formatting function, gets called repeatedly for each frame
function format(event) {
    var rounded = Math.round(target.number);
    var formatted = formatNumber(rounded, data.format);
    target.text = formatted;
}

// UTILITY FUNCTIONS:

// Takes "###,###,###" or somesuch
// Returns a raw number and a formatting object
function getFormatData(formattedNumber) {

    var toString = "" + formattedNumber; // in case it's not a string
    var reversed = toString.split('').reverse(); // get a reversed array

    // now walk (backwards) through the array and remove formatting
    var formatChars = {};
    for (var i = reversed.length-1; i >= 0; i--) {
        var c = reversed[i];
        var isnum = /^\d$/.test(c);
        if (!isnum) {
            formatChars[i] = c;
            reversed.splice(i, 1);
        }
    }

    // get the actual number
    var number = parseInt(reversed.reverse().join(''));

    // return the data
    var result = {number: number, format: formatChars};
    return result;
}

// Takes a raw number and a formatting object and produces a formatted number
formatNumber(number, format) {
    var toString = '' + number;
    var reversed = toString.split('').reverse();
    var index = 0;
    while (index < reversed.length) {
        if (format[index]) {
            reversed.splice(index, 0, format[index]);
        }
        index++;
    }

    var finished = reversed.reverse().join('');
    return finished;
}

这个 fiddle 演示了格式并在评论中有更多解释。

当然还有其他方法可以做到这一点,例如 toLocaleString(),但这完全符合我的要求。希望它能帮助其他人。