Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v8] Feat: add text and icon default anchor options #157

Merged
merged 10 commits into from
May 22, 2024
81 changes: 76 additions & 5 deletions src/FancyButton.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable max-len */
import { Container, isMobile, NineSliceSprite, ObservablePoint, Rectangle, Texture, Ticker } from 'pixi.js';
import { Group, Tween } from 'tweedle.js';
import { ButtonContainer } from './Button';
Expand Down Expand Up @@ -63,6 +64,8 @@ export type ButtonOptions = ViewsInput & {
iconOffset?: Offset;
defaultTextScale?: Pos | number;
defaultIconScale?: Pos | number;
defaultTextAnchor?: Pos | number;
defaultIconAnchor?: Pos | number;
animations?: StateAnimations;
nineSliceSprite?: [number, number, number, number];
ignoreRefitting?: boolean;
Expand Down Expand Up @@ -144,6 +147,12 @@ export class FancyButton extends ButtonContainer
/** Base icon scaling to take into account when fitting inside the button */
protected _defaultIconScale: Pos = { x: 1, y: 1 };

/** Base text anchor to take into account when fitting and placing inside the button */
protected _defaultTextAnchor: Pos = { x: 0.5, y: 0.5 };

/** Base icon anchor to take into account when fitting and placing inside the button */
protected _defaultIconAnchor: Pos = { x: 0.5, y: 0.5 };

/**
* Creates a button with a lot of tweaks.
* @param {object} options - Button options.
Expand All @@ -162,6 +171,8 @@ export class FancyButton extends ButtonContainer
* when all animations scales will be applied to the inner view.
* @param {number} options.defaultTextScale - Base text scaling to take into account when fitting inside the button.
* @param {number} options.defaultIconScale - Base icon scaling to take into account when fitting inside the button.
* @param {number} options.defaultTextAnchor - Base text anchor to take into account when fitting and placing inside the button.
* @param {number} options.defaultIconAnchor - Base icon anchor to take into account when fitting and placing inside the button.
* @param {number} options.anchor - Anchor point of the button.
* @param {number} options.anchorX - Horizontal anchor point of the button.
* @param {number} options.anchorY - Vertical anchor point of the button.
Expand All @@ -185,6 +196,8 @@ export class FancyButton extends ButtonContainer
iconOffset,
defaultTextScale: textScale,
defaultIconScale: iconScale,
defaultTextAnchor: textAnchor,
defaultIconAnchor: iconAnchor,
scale,
anchor,
anchorX,
Expand All @@ -206,6 +219,8 @@ export class FancyButton extends ButtonContainer
this.iconOffset = iconOffset;
this.defaultTextScale = textScale;
this.defaultIconScale = iconScale;
this.defaultTextAnchor = textAnchor;
this.defaultIconAnchor = iconAnchor;
this.scale.set(scale ?? 1);

if (animations)
Expand Down Expand Up @@ -323,7 +338,6 @@ export class FancyButton extends ButtonContainer
this._defaultTextScale = { x, y };
}

this._views.textView.anchor.set(0);
this.innerView.addChild(this._views.textView);

this.adjustTextView(this.state);
Expand Down Expand Up @@ -395,6 +409,7 @@ export class FancyButton extends ButtonContainer
if (!this.text) return;

const activeView = this.getStateView(this.state);
const { x: anchorX, y: anchorY } = this._defaultTextAnchor;

if (activeView)
{
Expand All @@ -409,7 +424,7 @@ export class FancyButton extends ButtonContainer
this._views.textView.y = activeView.y + (activeView.height / 2);
}

this._views.textView.anchor.set(0.5);
this._views.textView.anchor.set(anchorX, anchorY);

this.setOffset(this._views.textView, state, this.textOffset);
}
Expand Down Expand Up @@ -437,12 +452,24 @@ export class FancyButton extends ButtonContainer
this._views.iconView.scale.set(this._defaultIconScale.x, this._defaultIconScale.y);
}

const { x: anchorX, y: anchorY } = this._defaultIconAnchor;

fitToView(activeView, this._views.iconView, this.padding, false);

(this._views.iconView as Sprite).anchor?.set(0);
if ('anchor' in this._views.iconView)
{
(this._views.iconView.anchor as ObservablePoint).set(anchorX, anchorY);
}
else
{
this._views.iconView.pivot.set(
anchorX * (this._views.iconView.width / this._views.iconView.scale.x),
anchorY * (this._views.iconView.height / this._views.iconView.scale.y)
);
}

this._views.iconView.x = activeView.x + (activeView.width / 2) - (this._views.iconView.width / 2);
this._views.iconView.y = activeView.y + (activeView.height / 2) - (this._views.iconView.height / 2);
this._views.iconView.x = activeView.x + (activeView.width / 2);
this._views.iconView.y = activeView.y + (activeView.height / 2);

this.setOffset(this._views.iconView, state, this.iconOffset);
}
Expand Down Expand Up @@ -888,6 +915,50 @@ export class FancyButton extends ButtonContainer
return this.defaultIconScale;
}

/**
* Sets the base anchor for the text view to take into account when fitting and placing inside the button.
* @param {Pos | number} anchor - base anchor of the text view.
*/
set defaultTextAnchor(anchor: Pos | number)
{
if (anchor === undefined) return;
// Apply to the options so that the manual anchor is prioritized.
this.options.defaultTextAnchor = anchor;
const isNumber = typeof anchor === 'number';

this._defaultTextAnchor.x = isNumber ? anchor : anchor.x ?? 1;
this._defaultTextAnchor.y = isNumber ? anchor : anchor.y ?? 1;
this.adjustTextView(this.state);
}

/** Returns the text view base anchor. */
get defaultTextAnchor(): Pos
{
return this.defaultTextAnchor;
}

/**
* Sets the base anchor for the icon view to take into account when fitting and placing inside the button.
* @param {Pos | number} anchor - base anchor of the icon view.
*/
set defaultIconAnchor(anchor: Pos | number)
{
if (anchor === undefined) return;
// Apply to the options so that the manual anchor is prioritized.
this.options.defaultIconAnchor = anchor;
const isNumber = typeof anchor === 'number';

this._defaultIconAnchor.x = isNumber ? anchor : anchor.x ?? 1;
this._defaultIconAnchor.y = isNumber ? anchor : anchor.y ?? 1;
this.adjustIconView(this.state);
}

/** Returns the icon view base anchor. */
get defaultIconAnchor(): Pos
{
return this.defaultIconAnchor;
}

/**
* Sets width of a FancyButtons state views.
* If nineSliceSprite is set, then width will be set to nineSliceSprites of a views.
Expand Down
10 changes: 7 additions & 3 deletions src/stories/fancyButton/FancyButtonBitmapText.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const args = {
textOffsetX: 0,
textOffsetY: -7,
defaultTextScale: 0.99,
defaultTextAnchorX: 0.5,
defaultTextAnchorY: 0.5,
anchorX: 0.5,
anchorY: 0.5,
animationDuration: 100,
Expand All @@ -31,9 +33,11 @@ export const UsingSpriteAndBitmapText: StoryFn<typeof args> = (
textOffsetX,
textOffsetY,
defaultTextScale,
defaultTextAnchorX,
defaultTextAnchorY,
anchorX,
anchorY,
animationDuration
animationDuration,
},
context
) =>
Expand All @@ -54,14 +58,13 @@ export const UsingSpriteAndBitmapText: StoryFn<typeof args> = (
name: 'TitleFont',
style: {
...defaultTextStyle,

fill: textColor || defaultTextStyle.fill,
},
});

const title = new BitmapText({
text,
style: { fontFamily: 'TitleFont' },
style: { fontFamily: 'TitleFont', fontSize: defaultTextStyle.fontSize },
});

// Component usage !!!
Expand All @@ -74,6 +77,7 @@ export const UsingSpriteAndBitmapText: StoryFn<typeof args> = (
padding,
textOffset: { x: textOffsetX, y: textOffsetY },
defaultTextScale,
defaultTextAnchor: { x: defaultTextAnchorX, y: defaultTextAnchorY },
animations: {
hover: {
props: {
Expand Down
10 changes: 10 additions & 0 deletions src/stories/fancyButton/FancyButtonDynamicUpdate.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ const args = {
textColor: '#FFFFFF',
defaultTextScale: 0.99,
defaultIconScale: 0.2,
defaultTextAnchorX: 0.5,
defaultTextAnchorY: 0.5,
defaultIconAnchorX: 0.5,
defaultIconAnchorY: 0.5,
padding: 11,
anchorX: 0.5,
anchorY: 0.5,
Expand All @@ -25,6 +29,10 @@ export const DynamicUpdate: StoryFn<typeof args> = ({
textColor,
defaultTextScale,
defaultIconScale,
defaultTextAnchorX,
defaultTextAnchorY,
defaultIconAnchorX,
defaultIconAnchorY,
disabled,
onPress,
padding,
Expand All @@ -50,6 +58,7 @@ export const DynamicUpdate: StoryFn<typeof args> = ({

button.iconView = Sprite.from(icon);
button.defaultIconScale = defaultIconScale;
button.defaultIconAnchor = { x: defaultIconAnchorX, y: defaultIconAnchorY };
button.iconOffset = { x: -100, y: -7 };

button.textView = new Text({
Expand All @@ -59,6 +68,7 @@ export const DynamicUpdate: StoryFn<typeof args> = ({
}
});
button.defaultTextScale = defaultTextScale;
button.defaultTextAnchor = { x: defaultTextAnchorX, y: defaultTextAnchorY };
button.textOffset = { x: 30, y: -7 };

button.padding = padding;
Expand Down
10 changes: 10 additions & 0 deletions src/stories/fancyButton/FancyButtonGraphics.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ const args = {
textOffsetY: 140,
defaultTextScale: 0.99,
defaultIconScale: 0.99,
defaultTextAnchorX: 0.5,
defaultTextAnchorY: 0.5,
defaultIconAnchorX: 0.5,
defaultIconAnchorY: 0.5,
defaultOffsetY: 0,
hoverOffsetY: -1,
pressedOffsetY: 5,
Expand Down Expand Up @@ -57,6 +61,10 @@ export const UseGraphics: StoryFn<typeof args> = ({
textOffsetY,
defaultTextScale,
defaultIconScale,
defaultTextAnchorX,
defaultTextAnchorY,
defaultIconAnchorX,
defaultIconAnchorY,
defaultOffsetY,
hoverOffsetY,
pressedOffsetY,
Expand Down Expand Up @@ -113,6 +121,8 @@ export const UseGraphics: StoryFn<typeof args> = ({
},
defaultTextScale,
defaultIconScale,
defaultTextAnchor: { x: defaultTextAnchorX, y: defaultTextAnchorY },
defaultIconAnchor: { x: defaultIconAnchorX, y: defaultIconAnchorY },
animations: {
default: {
props: {
Expand Down
5 changes: 5 additions & 0 deletions src/stories/fancyButton/FancyButtonHTMLText.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const args = {
textOffsetX: 0,
textOffsetY: -7,
defaultTextScale: 0.99,
defaultTextAnchorX: 0.5,
defaultTextAnchorY: 0.5,
anchorX: 0.5,
anchorY: 0.5,
animationDuration: 100,
Expand All @@ -31,6 +33,8 @@ export const UsingSpriteAndHTMLText: StoryFn<typeof args> = (
textOffsetX,
textOffsetY,
defaultTextScale,
defaultTextAnchorX,
defaultTextAnchorY,
anchorX,
anchorY,
animationDuration
Expand Down Expand Up @@ -68,6 +72,7 @@ export const UsingSpriteAndHTMLText: StoryFn<typeof args> = (
padding,
textOffset: { x: textOffsetX, y: textOffsetY },
defaultTextScale,
defaultTextAnchor: { x: defaultTextAnchorX, y: defaultTextAnchorY },
animations: {
hover: {
props: {
Expand Down
5 changes: 5 additions & 0 deletions src/stories/fancyButton/FancyButtonIcon.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ const args = {
iconOffsetX: 0,
iconOffsetY: 0,
defaultIconScale: 0.99,
defaultIconAnchorX: 0.5,
defaultIconAnchorY: 0.5,
defaultOffset: 0,
hoverOffset: -1,
pressedOffset: 5,
Expand All @@ -43,6 +45,8 @@ export const UseIcon: StoryFn<typeof args> = ({
iconOffsetX,
iconOffsetY,
defaultIconScale,
defaultIconAnchorX,
defaultIconAnchorY,
defaultOffset,
hoverOffset,
pressedOffset,
Expand Down Expand Up @@ -86,6 +90,7 @@ export const UseIcon: StoryFn<typeof args> = ({
y: iconOffsetY
},
defaultIconScale,
defaultIconAnchor: { x: defaultIconAnchorX, y: defaultIconAnchorY },
animations: {
hover: {
props: {
Expand Down
14 changes: 12 additions & 2 deletions src/stories/fancyButton/FancyButtonNineSliceSprite.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ const args = {
height: 137,
defaultTextScale: 0.99,
defaultIconScale: 0.2,
defaultTextAnchorX: 0.5,
defaultTextAnchorY: 0.5,
defaultIconAnchorX: 0.5,
defaultIconAnchorY: 0.5,
anchorX: 0.5,
anchorY: 0.5,
animationDuration: 100,
Expand All @@ -36,6 +40,10 @@ export const UseNineSliceSprite: StoryFn<typeof args> = ({
height,
defaultTextScale,
defaultIconScale,
defaultTextAnchorX,
defaultTextAnchorY,
defaultIconAnchorX,
defaultIconAnchorY
}, context) =>
new PixiStory<typeof args>({
context,
Expand Down Expand Up @@ -69,7 +77,11 @@ export const UseNineSliceSprite: StoryFn<typeof args> = ({
}),
padding,
textOffset: { x: 30, y: -5 },
iconOffset: { x: -100, y: -7 },
defaultTextScale,
defaultIconScale,
defaultTextAnchor: { x: defaultTextAnchorX, y: defaultTextAnchorY },
defaultIconAnchor: { x: defaultIconAnchorX, y: defaultIconAnchorY },
animations: {
hover: {
props: {
Expand All @@ -94,8 +106,6 @@ export const UseNineSliceSprite: StoryFn<typeof args> = ({
borderWidth: 10,
borderColor: 0xFFFFFF
});
button.defaultIconScale = defaultIconScale;
button.iconOffset = { x: -100, y: -7 };

button.anchor.set(anchorX, anchorY);

Expand Down
5 changes: 5 additions & 0 deletions src/stories/fancyButton/FancyButtonSprite.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const args = {
textOffsetX: 0,
textOffsetY: -7,
defaultTextScale: 0.99,
defaultTextAnchorX: 0.5,
defaultTextAnchorY: 0.5,
anchorX: 0.5,
anchorY: 0.5,
animationDuration: 100,
Expand All @@ -30,6 +32,8 @@ export const UseSprite: StoryFn<typeof args> = ({
textOffsetX,
textOffsetY,
defaultTextScale,
defaultTextAnchorX,
defaultTextAnchorY,
anchorX,
anchorY,
animationDuration
Expand Down Expand Up @@ -57,6 +61,7 @@ export const UseSprite: StoryFn<typeof args> = ({
padding,
textOffset: { x: textOffsetX, y: textOffsetY },
defaultTextScale,
defaultTextAnchor: { x: defaultTextAnchorX, y: defaultTextAnchorY },
animations: {
hover: {
props: {
Expand Down
Loading