【问题标题】:Why does Flash use the entire height of a masked object instead of just the visible area?为什么 Flash 使用被遮罩对象的整个高度而不是只使用可见区域?
【发布时间】:2011-10-12 19:41:18
【问题描述】:

问题是如果我设置 Sprite 对象的 .mask 属性,当我调用 Sprite.height 时,Sprite 对象仍然返回它的全高。所以我想出了一个简单的方法来克服这个问题,那就是覆盖属性 getter。

现在.. 即使这样有效,如果我将此蒙面 Sprite 对象添加到另一个 Sprite 对象,新的 Sprite 对象将报告它的高度作为蒙版 Sprite 对象的高度,即使我已经覆盖了该属性由于蒙版,仅返回可见区域的高度。因此,Flash 似乎忽略了并非所有内容都可见但仍会自动增加新 Sprite 对象的高度这一事实,就好像蒙版 上没有蒙版一样精灵.

所以我想知道是否有解决方法,所以我可以将此蒙面对象添加到任何其他 DisplayObject 知道它将被调整为仅在蒙面中可见的内容对象。

感谢您的帮助。

编辑

这是一个代码示例..

var content:Bitmap = new Bitmap(new BitmapData(50, 100, false, 0x000000));
var container:Sprite = new Sprite();
var mask:Bitmap = new Bitmap(new BitmapData(50, 50, false, 0x000000));

container.mask = mask;

container.addChild(content);

trace(container.height) // this should return 50 instead of 100

【问题讨论】:

  • 我也尝试过类似的方法。没用。也尝试过覆盖 getBounds ,但也没有用。我有兴趣看到解决方案。
  • 以能够使用它的高度和宽度的方式设置遮罩是否有问题? if(sprite.mask)...
  • 我需要能够将蒙版对象添加到另一个 DisplayObject 而不会将其新父级调整为内容的完整高度,而只需调整到可见的内容。我已经为其他想知道的人尝试了 .scrollRect 并且仍然返回完整高度。
  • 我遇到了相反的情况(3天前!为我的公司整夜编码以参加比赛......)......滚动矩形不显示对象的实际大小......之后看到你的评论我做了一个快速测试(为了检查我当时是否在做梦)......这是奇怪的result
  • 是的,我已经知道那个奇怪的延迟错误。显然 scrollRect 直到延迟 1 帧后才会改变高度,这对我来说毫无用处,因为我需要它立即更新。不过还是谢谢。

标签: flash actionscript-3 mask


【解决方案1】:

如果您找不到直接的解决方案,您可以尝试以下方法:

  1. 将子项(您的 DisplayObject,包括掩码和掩码对象)绘制到 BitmapData 对象。
  2. 解析 BitmapData 对象的像素,并使用 BitmapData 的 getPixel32() 方法检查 Alpha 通道的值。
  3. 确定所有非零 Alpha 像素的边界框,并使用这些尺寸。

我会将所有这些都包含在 getMaskedDimensions(child:DisplayObject):Rectangle 方法中。如果您需要更多详细信息,请告诉我。否则,祝你好运!

【讨论】:

  • 谢谢伊恩,不幸的是,这与我的需要无关。我将这个蒙面对象添加到一个新的 Sprite 作为一个孩子,现在 Flash 的默认行为是根据内容 调整 Sprite 的大小(在这种情况下,蒙面对象)。不幸的是,Flash 没有根据蒙版对象的可见区域设置高度,而是使用蒙版对象的整个高度,包括看不到的位。所以我需要一种方法来欺骗或让它看起来被遮罩的对象被视为它的高度与它内部的可见内容的高度相同。
  • 我明白了。您可以扩展子对象以覆盖 get width()get height() 以向父对象提供调整后的宽度和高度并以这种方式欺骗它...
  • 正如我在原帖中提到的,我已经尝试过覆盖吸气剂,Flash 似乎以不同的方式获得高度。无论如何,感谢您的贡献。 ;)
  • 大声笑,对不起。我应该阅读更多内容:P 您是否尝试过覆盖get transform()?我想我以前在某处读过transform.pixelBounds 是父母在确定孩子布局等时可能使用的……无论如何,我希望你能找到它。我很想听听您想出什么解决方案。
  • 感谢 Ian 的提示,很遗憾我试过了,但没有成功。
【解决方案2】:

因此,对于那些感兴趣的人,我设法想出了一个解决方法。真正让我烦恼的是 DisplayObject.scrollRect 不会立即更新尺寸,所以在 Adob​​e 下手并修复它之前,这就是你需要做的。

正如我所提到的,.scrollRect 的问题在于它不会调整到新的宽度和高度,直到一帧过去或经过一定时间之后。无论哪种方式,我基本上都构建了我的类,以便一旦设置 .scrollRect,我创建一个每毫秒运行一次的计时器,检查是否 .width.height 已更新为新值。完成后,在将类添加到舞台之前,我会调度一个自定义 READY 事件,父对象会监听该事件。

现在,关于这个属性的混蛋,您需要了解的一件 非常 重要的事情是,您正在设置 .scrollRect的对象> 属性必须先添加到舞台,然后才能尝试将其宽度和高度值更新为 .scrollRect 属性中设置的值。所以为了尽可能干净,我将 Stage 对象从我的主类传递给我想要调整的 .scrollRect 对象,我们称之为 MyClass MyClass 将其 .visible 属性设置为 false,然后将 自身 添加到舞台。 只有完成此操作,我现在才能开始我的 1 毫秒计时器,以检查设置 .scrollRect 后尺寸是否正确更改。

因此,一旦计时器滴答处理函数看到尺寸已成功更改,MyClass 现在可以同时将 MyClass.READY 事件发送到主类,将其 .visible 属性设置为 true 并将其从舞台上移除。当主类的事件侦听器被触发时,它现在可以将 MyClass 添加到它想要的任何位置,因为它知道它将具有 MyClass.scrollRect 中设置的正确尺寸。

这对我自己和可能许多其他正在寻找解决方案的开发人员来说是一个巨大的痛苦,所以我希望这对您有所帮助,并且现在就足够了,直到 Adob​​e 对此采取行动。感谢之前发帖的所有尝试提供帮助的人,我真的很感激,谢谢!

【讨论】:

    【解决方案3】:

    宽度和高度可以被覆盖。一个对象将始终具有与其内部呈现的内容相对应的固有宽度和高度,不幸的是,固有宽度和高度永远不会考虑遮罩区域。 getRect 和 getBounds 对掩码也不敏感,因此它们本身也不够。

    您需要做的是编写一个名为“getMaskSensitiveRect”之类的递归方法,该方法对掩码敏感。不是在每个子对象上与 getRect 的结果相交,而是首先测试每个子对象的 mask 属性是否为 null,如果它不为 null,则在 mask 而不是对象上调用 getRect,并将其用作子对象的矩形相交与其余的子对象。而且您肯定必须将所有孩子、孙子等的整个层次结构深入到最深的层次才能获得准确的测量值,因为如果不考虑单个面具,它可能会炸毁尺寸。

    记住要覆盖宽度和高度的设置器,因为改变 DisplayObject 的宽度或高度实际上会改变它的比例,并且它是相对于该固有尺寸而不是您覆盖的宽度和高度进行的。您必须在 setter 中调用您的 getMaskSensitiveRect 方法,并使用该方法和您想要的宽度计算比例,然后将比例分配给 scaleX 和 scaleY 属性。

    【讨论】:

      【解决方案4】:

      正如 xLite 提到的,它会在下一帧渲染时更新宽度和高度。所以你可以做一些事情来强制它渲染。

       var content:Bitmap = new Bitmap(new BitmapData(50, 100, false, 0x000000));
       var container:Sprite = new Sprite();
       content.scrollRect = new Rectangle(0, 0, 50, 50);
      
       container.addChild(content);
      
       new BitmapData(1,1).draw(content);//this line would help
       trace(container.height);
      

      【讨论】:

      • 那条线总是保证强制渲染吗?
      • 我已经在我的工作中尝试过它并且它有效。在大多数情况下,您只需要调用一次。
      猜你喜欢
      • 1970-01-01
      • 2012-10-30
      • 1970-01-01
      • 1970-01-01
      • 2021-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多