CreateJS / EaselJS

The Easel Javascript library provides a full, hierarchical display list, a core interaction model, and helper classes to make working with the HTML5 Canvas element much easier.
http://createjs.com/
MIT License
8.13k stars 1.97k forks source link

Text bounds wrong after releasing the cache. #928

Closed JonnyCodes closed 6 years ago

JonnyCodes commented 6 years ago

Been working through some problems getting the bounds of Text objects and caching:

Text.js:253

p.getBounds = function() {
    var rect = this.DisplayObject_getBounds();
    if (rect) { return rect; }
    if (this.text == null || this.text === "") { return null; }
    var o = this._drawText(null, {});
    var w = (this.maxWidth && this.maxWidth < o.width) ? this.maxWidth : o.width;
    var x = w * Text.H_OFFSETS[this.textAlign||"left"];
    var lineHeight = this.lineHeight||this.getMeasuredLineHeight();
    var y = lineHeight * Text.V_OFFSETS[this.textBaseline||"top"];
    return this._rectangle.setValues(x, y, w, o.height);
};

DisplayObject.js:1145

p.getBounds = function() {
    if (this._bounds) { return this._rectangle.copy(this._bounds); }
        var cache = this.bitmapCache;
    if (cache) {
        return cache.getBounds();
        }
    return null;
};

First of all, I'm not sure what the _rectangle object is for, but it seems to be doing the job of the _bounds object in this case. Because the _bounds object isn't set at the end of Text.getBounds when I next calculate the bounds the DisplayObject.getBounds tries to use bitmapCache bounds, but if I've just released the cache the returned bounds are {x: 0, y: 0, width: 0, height: 0}. The bounds of Text objects shouldn't rely on the bitmapCache bounds. I think when the bitmapCache is released it should probably nullify this.bitmapCache on the display object.

The reason I'm releasing the cache is because when I update a Text object the width & height changes and I need to recalculate the size of the cacheCanvas. Is there another way to resize the cacheCanvas that I'm not aware of?

JonnyCodes commented 6 years ago

Whoops, I forgot to mention I'm using StageGL.

MannyC commented 6 years ago

Are you manually calling release on the bitmapCache or are you using the uncache method from DisplayObject? The uncache method should be setting the bitmapCache property to undefined.

_rectangle is just a reusable object that gets returned from getBounds. The idea is to avoid unnecessary object creation and the associated overhead.

JonnyCodes commented 6 years ago

I was calling bitmapCache.release, like a fool! Thanks.

Is the text supposed to get measured every time getBounds is called or should it be storing _bounds so when displayObject.getBounds is called it can return the _rectangle rather than remeasure the text?

MannyC commented 6 years ago

Not automatically. If you look at the description for getBounds it gives an example for how to stop it recalculating the bounds each time. You can also cache the text and it will use the bounds of the cache instead of measuring the text.

JonnyCodes commented 6 years ago

Awesome, thanks for replying so quickly!

On a side note, I'm also a big fan of Grim Fandango.