現象
EgretEngineで半径5・直径10の円のSpriteを作成後にwidthが13になる
参考:
https://twitter.com/squmari/status/1083523634738515969
再現するコード
class Main extends egret.UILayer {
:
const s = new egret.Shape();
s.graphics.beginFill(0xff0000);
s.graphics.drawCircle(0,0,10);
s.graphics.endFill();
this.addChild(s);
:
console.log(s.width); // 13と出力される
:
}
原因
WebGLのパッキングの問題でdrawCircleメソッドが下記のような実装になっているため
Graphics.ts#drawCircle
//-1 +2 解决WebGL裁切问题
this.extendBoundsByPoint(x - radius - 1, y - radius - 1);
this.extendBoundsByPoint(x + radius + 2, y + radius + 2);
this.updatePosition(x + radius, y);
元コード
Graphics.ts
:
/**
* Draw a rectangle with rounded corners.
* @param x x position of the center, relative to the registration point of the parent display object (in pixels).
* @param y y position of the center, relative to the registration point of the parent display object (in pixels).
* @param width Width of the rectangle (in pixels).
* @param height Height of the rectangle (in pixels).
* @param ellipseWidth Width used to draw an ellipse with rounded corners (in pixels).
* @param ellipseHeight Height used to draw an ellipse with rounded corners (in pixels). (Optional) If no value is specified, the default value matches the value of the ellipseWidth parameter.
* @version Egret 2.4
* @platform Web,Native
* @language en_US
*/
/**
* 绘制一个圆角矩形。
* @param x 圆心相对于父显示对象注册点的 x 位置(以像素为单位)。
* @param y 相对于父显示对象注册点的圆心的 y 位置(以像素为单位)。
* @param width 矩形的宽度(以像素为单位)。
* @param height 矩形的高度(以像素为单位)。
* @param ellipseWidth 用于绘制圆角的椭圆的宽度(以像素为单位)。
* @param ellipseHeight 用于绘制圆角的椭圆的高度(以像素为单位)。 (可选)如果未指定值,则默认值与为 ellipseWidth 参数提供的值相匹配。
* @version Egret 2.4
* @platform Web,Native
* @language zh_CN
*/
public drawRoundRect(x: number, y: number, width: number, height: number, ellipseWidth: number, ellipseHeight?: number): void {
x = +x || 0;
y = +y || 0;
width = +width || 0;
height = +height || 0;
ellipseWidth = +ellipseWidth || 0;
ellipseHeight = +ellipseHeight || 0;
if (egret.nativeRender) {
this.$targetDisplay.$nativeDisplayObject.setDrawRoundRect(x, y, width, height, ellipseWidth, ellipseHeight);
}
let fillPath = this.fillPath;
let strokePath = this.strokePath;
fillPath && fillPath.drawRoundRect(x, y, width, height, ellipseWidth, ellipseHeight);
strokePath && strokePath.drawRoundRect(x, y, width, height, ellipseWidth, ellipseHeight);
let radiusX = (ellipseWidth * 0.5) | 0;
let radiusY = ellipseHeight ? (ellipseHeight * 0.5) | 0 : radiusX;
let right = x + width;
let bottom = y + height;
let ybw = bottom - radiusY;
this.extendBoundsByPoint(x, y);
this.extendBoundsByPoint(right, bottom);
this.updatePosition(right, ybw);
this.dirty();
}
/**
* Draw a circle.
* @param x x position of the center, relative to the registration point of the parent display object (in pixels).
* @param y y position of the center, relative to the registration point of the parent display object (in pixels).
* @param r Radius of the circle (in pixels).
* @version Egret 2.4
* @platform Web,Native
* @language en_US
*/
/**
* 绘制一个圆。
* @param x 圆心相对于父显示对象注册点的 x 位置(以像素为单位)。
* @param y 相对于父显示对象注册点的圆心的 y 位置(以像素为单位)。
* @param radius 圆的半径(以像素为单位)。
* @version Egret 2.4
* @platform Web,Native
* @language zh_CN
*/
public drawCircle(x: number, y: number, radius: number): void {
x = +x || 0;
y = +y || 0;
radius = +radius || 0;
if (egret.nativeRender) {
this.$targetDisplay.$nativeDisplayObject.setDrawCircle(x, y, radius);
}
let fillPath = this.fillPath;
let strokePath = this.strokePath;
fillPath && fillPath.drawCircle(x, y, radius);
strokePath && strokePath.drawCircle(x, y, radius);
//-1 +2 解决WebGL裁切问题
this.extendBoundsByPoint(x - radius - 1, y - radius - 1);
this.extendBoundsByPoint(x + radius + 2, y + radius + 2);
this.updatePosition(x + radius, y);
this.dirty();
}