Jump to content

bug with setTextBounds with anchor and scale


Yehuda Katz
 Share

Recommended Posts

Hello,

I am trying to put text in the middle of the button and then apply scale (pulse scale). Since the pulsation should be done relative to text center, I am using anchor.setTo(0.5). Everything works fine until I apply setTextBounds.

// wrong
var label = new Phaser.Text(this.game, 0, 0, 'Cool Label', {boundsAlignH: 'center', boundsAlignV: 'middle'});
label.setTextBounds(0, 0, 200, 100);
label.anchor.setTo(0.5);
label.x += label.offsetX;
label.y += label.offsetY;
this.game.add.existing(label);
this.game.add.tween(label.scale).to({x: 0.5, y: 0.5}, 1000, Phaser.Easing.Sinusoidal.Out, true, null, null, true);

// correct
var label = new Phaser.Text(this.game, 30, 100, 'Cool Label', {boundsAlignH: 'center', boundsAlignV: 'middle'});
label.anchor.setTo(0.5);
label.x += label.offsetX;
label.y += label.offsetY;
this.game.add.existing(label);
this.game.add.tween(label.scale).to({x: 0.5, y: 0.5}, 1000, Phaser.Easing.Sinusoidal.Out, true, null, null, true);

Did anyone experience this issue and can tell me what is going on?

Thanks

wrong scale.gif

Link to comment
Share on other sites

p.s. To save your time, the issue is with label.pivot. I have not idea why Phaser needs to change it... I can simply replace setTextBounds with:

label.x = (200 - label.canvas.width) / 2;
label.y = (100 - label.canvas.height) / 2;

and everything works fine... why setTextBounds calculates x coordinate of text in complicated way?

x += this.textBounds.halfWidth - (this.canvas.width / this.resolution / 2);
this.pivot.x = -x;

Did I miss something important?

p.p.s. I had a doubt and that's right, pivot is used in combination with scale:

tx = this.position.x - this.pivot.x * a;
ty = this.position.y - this.pivot.y * d;

so basically scale changes also pivot proportionally which is wrong IMHO

Link to comment
Share on other sites

In case nobody will answer my question (as always happens on this forum), here is my solution:

_set_text_bounds(object, x, y, width, height) {
  if (object.style.boundsAlignH === 'right') {
    x += width - object.canvas.width;
  } else if (object.style.boundsAlignH === 'center') {
    x += (width - object.canvas.width) / 2;
  }
  if (object.style.boundsAlignV === 'bottom') {
    y += height - object.canvas.height;
  } else if (object.style.boundsAlignV === 'middle') {
    y += (height - object.canvas.height) / 2;
  }
  object.x += x;
  object.y += y;
}
Link to comment
Share on other sites

I think setTextBounds is intended to work without altering the object's position. Thus pivot. And the pivot is updated when the text content changes to keep it aligned within the bounds (see example below).

If you just need to position the text relative to a box, you're correct that it's much simpler. You can probably just use

label.alignIn({x: 0, y: 0, width: 200, height: 100}, Phaser.CENTER);

 

Link to comment
Share on other sites

@samme thanks a lot for your reply. What I want to say is that text bound should be scaled and its pivot TOO but if you imagine text bound as invisible container, it should be affected by parent's anchor values. Just imagine a text which has size of 100x60 pixels. If we scale it to 50% it means new text bounds will be 50x30... and if text anchor was set to 0.5, that text bound should be aligned withing 100x60 accordingly left: 25 and top 15. Tell me if I am wrong... That's exactly how sprite behaves, when you scale it, it moves in relevant to it's anchor but text always moves relative to anchor 0 if setTextBounds were used.

Thanks a lot for your solution samme, it works ideally for my situation: 

label.alignIn(new Phaser.Rectangle(0, 0, 200, 100), Phaser.CENTER);
Link to comment
Share on other sites

Just in case if someone will come across the same problem, here is the working method:

_text_align(object, width, height, halign, valign) {
  var align = Phaser.CENTER;
  switch (halign) {
    case 'left':
      switch (valign) {
        case 'top':
          align = Phaser.TOP_LEFT;
          break;
        case 'center':
          align = Phaser.LEFT_CENTER;
          break;
        case 'bottom':
          align = Phaser.BOTTOM_LEFT;
          break;
      }
      break;
    case 'center':
      switch (valign) {
        case 'top':
          align = Phaser.TOP_CENTER;
          break;
        case 'center':
          align = Phaser.CENTER;
          break;
        case 'bottom':
          align = Phaser.BOTTOM_CENTER;
          break;
      }
      break;
    case 'right':
      switch (valign) {
        case 'top':
          align = Phaser.TOP_RIGHT;
          break;
        case 'center':
          align = Phaser.RIGHT_CENTER;
          break;
        case 'bottom':
          align = Phaser.BOTTOM_RIGHT;
          break;
      }
      break;
  }
  var rect = new Phaser.Rectangle(object.x, object.y, width, height);
  object.alignIn(rect, align);
}
Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...