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

Make Components responsive #118

Merged
merged 19 commits into from
Nov 5, 2023
9,269 changes: 8,064 additions & 1,205 deletions package-lock.json

Large diffs are not rendered by default.

13 changes: 7 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@pixi/ui",
"version": "0.9.1",
"version": "0.10.0",
"description": "It is a library that contains commonly used UI components, that are extensible to allow them to be used in any project",
"homepage": "https://github.com/pixijs/ui",
"bugs": "https://github.com/pixijs/ui/issues",
Expand Down Expand Up @@ -61,6 +61,7 @@
"docsKeyword": "PixiJS, UI, components"
},
"dependencies": {
"@pixi/mesh-extras": "^7.3.2",
"tweedle.js": "^2.1.0",
"typed-signals": "^2.5.0"
},
Expand All @@ -79,10 +80,10 @@
"@pixi/text": "^7.3.1",
"@pixi/text-bitmap": "^7.3.1",
"@pixi/text-html": "^7.3.1",
"@storybook/addon-essentials": "7.5.1",
"@storybook/addon-interactions": "7.5.1",
"@storybook/addon-links": "7.5.1",
"@storybook/addon-storysource": "^7.5.1",
"@storybook/addon-essentials": "7.5.2",
"@storybook/addon-interactions": "7.5.2",
"@storybook/addon-links": "7.5.2",
"@storybook/addon-storysource": "^7.5.2",
"@storybook/testing-library": "^0.2.2",
"@types/babel__core": "^7.1.20",
"@types/jest": "^29.2.4",
Expand All @@ -94,7 +95,7 @@
"jest": "^26.6.3",
"jest-raw-loader": "^1.0.1",
"lint-staged": "^13.1.0",
"storybook": "7.5.1",
"storybook": "7.5.2",
"typescript": "^5.2.0"
},
"peerDependencies": {
Expand Down
93 changes: 69 additions & 24 deletions src/DoubleSlider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { Container } from '@pixi/display';

export class DoubleSlider extends SliderBase
{
protected options: DoubleSliderOptions;
protected sliderOptions: DoubleSliderOptions;

protected activeValue: 'value1' | 'value2';

Expand All @@ -35,15 +35,15 @@ export class DoubleSlider extends SliderBase
{
super(options);

this.options = options;
this.sliderOptions = options;
this.setInitialState();
}

protected setInitialState()
{
this.validateValues();

const { value1, value2 } = this.options;
const { value1, value2 } = this.sliderOptions;

this.updateProgress(value1, value2);

Expand All @@ -59,34 +59,34 @@ export class DoubleSlider extends SliderBase

protected validateValues()
{
if (!this.options.value1)
if (!this.sliderOptions.value1)
{
this.options.value1 = this.min;
this.sliderOptions.value1 = this.min;
}

if (!this.options.value2)
if (!this.sliderOptions.value2)
{
this.options.value2 = this.options.max;
this.sliderOptions.value2 = this.sliderOptions.max;
}

if (this.options.value2 < this.options.value1)
if (this.sliderOptions.value2 < this.sliderOptions.value1)
{
this.options.value2 = this.options.value1;
this.sliderOptions.value2 = this.sliderOptions.value1;
}

if (this.options.value1 < this.options.min)
if (this.sliderOptions.value1 < this.sliderOptions.min)
{
this.options.value1 = this.options.min;
this.sliderOptions.value1 = this.sliderOptions.min;
}

if (this.options.value1 > this.options.max)
if (this.sliderOptions.value1 > this.sliderOptions.max)
{
this.options.value1 = this.options.max;
this.sliderOptions.value1 = this.sliderOptions.max;
}

if (this.options.value2 > this.options.max)
if (this.sliderOptions.value2 > this.sliderOptions.max)
{
this.options.value2 = this.options.max;
this.sliderOptions.value2 = this.sliderOptions.max;
}
}

Expand Down Expand Up @@ -134,6 +134,8 @@ export class DoubleSlider extends SliderBase

protected override update(event: FederatedPointerEvent)
{
super.update(event);

if (!this.dragging) return;

const obj = event.currentTarget as DragObject;
Expand All @@ -158,7 +160,7 @@ export class DoubleSlider extends SliderBase
}
}

const progress = this.validate((x / this.bg.width) * 100);
const progress = this.validate((x / this.bg?.width) * 100);

if (this.activeValue === 'value1')
{
Expand All @@ -170,6 +172,7 @@ export class DoubleSlider extends SliderBase
{
this.progress = progress;
this.value2 = this.min + (((this.max - this.min) / 100) * progress);
this.updateProgress(this.value1, this.value2);
}
}

Expand Down Expand Up @@ -219,43 +222,85 @@ export class DoubleSlider extends SliderBase

protected updateSlider1()
{
this._slider1.x = ((this.bg.width - this._slider1.width) / 100) * this.progressStart;
this._slider1.x = ((this.bg?.width - this._slider1.width) / 100) * this.progressStart;
this._slider1.y = this.bg?.height / 2;

if (this._slider2 && this._slider1.x > this._slider2.x)
{
this._slider1.x = this._slider2.x;
}

if (this.options?.showValue)
if (this.sliderOptions?.showValue)
{
this.value1Text.text = `${Math.round(this.value1)}`;

const sliderPosX = this._slider1.x + (this._slider1.width / 2);
const sliderPosY = this._slider1.y;

this.value1Text.x = sliderPosX + (this.options.valueTextOffset?.x ?? 0);
this.value1Text.y = sliderPosY + (this.options.valueTextOffset?.y ?? 0);
this.value1Text.x = sliderPosX + (this.sliderOptions.valueTextOffset?.x ?? 0);
this.value1Text.y = sliderPosY + (this.sliderOptions.valueTextOffset?.y ?? 0);
}
}

protected updateSlider2()
{
this._slider2.x = ((this.bg.width - this._slider2.width) / 100) * this.progress;
this._slider2.x = ((this.bg?.width - this._slider2.width) / 100) * this.progress;
this._slider2.y = this.bg?.height / 2;

if (this._slider2.x < this._slider1.x)
{
this._slider2.x = this._slider1.x;
}

if (this.options?.showValue)
if (this.sliderOptions?.showValue)
{
this.value2Text.text = `${Math.round(this.value2)}`;

const sliderPosX = this._slider2.x + (this._slider2.width / 2);
const sliderPosY = this._slider2.y;

this.value2Text.x = sliderPosX + (this.options.valueTextOffset?.x ?? 0);
this.value2Text.y = sliderPosY + (this.options.valueTextOffset?.y ?? 0);
this.value2Text.x = sliderPosX + (this.sliderOptions.valueTextOffset?.x ?? 0);
this.value2Text.y = sliderPosY + (this.sliderOptions.valueTextOffset?.y ?? 0);
}
}

/**
* Sets width of a Sliders background and fill.
* If nineSlicePlane is set, then width will be set to nineSlicePlane.
* If nineSlicePlane is not set, then width will control components width as Container.
* @param value - Width value.
*/
override set width(value: number)
{
super.width = value;

this.updateSlider1();
this.updateSlider2();
}

/** Gets width of a Slider. */
override get width(): number
{
return super.width;
}

/**
* Sets height of a Sliders background and fill.
* If nineSlicePlane is set, then height will be set to nineSlicePlane.
* If nineSlicePlane is not set, then height will control components height as Container.
* @param value - Height value.
*/
override set height(value: number)
{
super.height = value;

this.updateSlider1();
this.updateSlider2();
}

/** Gets height of a Slider. */
override get height(): number
{
return super.height;
}
}
116 changes: 112 additions & 4 deletions src/FancyButton.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { ObservablePoint, Ticker, Rectangle, utils } from '@pixi/core';
import { ObservablePoint, Ticker, Rectangle, utils, Texture } from '@pixi/core';
import { Container } from '@pixi/display';
import { Sprite } from '@pixi/sprite';
import type { Sprite } from '@pixi/sprite';
import { getView } from './utils/helpers/view';
import { AnyText, getTextView, PixiText } from './utils/helpers/text';
import { fitToView } from './utils/helpers/fit';
import { Tween, Group } from 'tweedle.js';
import { ButtonContainer } from './Button';
import { NineSlicePlane } from '@pixi/mesh-extras';

type State = 'default' | 'hover' | 'pressed' | 'disabled';
type Pos = { x?: number; y?: number };
Expand All @@ -18,7 +19,7 @@ type ButtonViewType = 'defaultView' | 'hoverView' | 'pressedView' | 'disabledVie
type ButtonView = string | Container;

type BasicButtonViews = {
[K in ButtonViewType]?: Container;
[K in ButtonViewType]?: Container | NineSlicePlane;
};

type ButtonViews = BasicButtonViews & {
Expand Down Expand Up @@ -62,6 +63,7 @@ export type ButtonOptions = ViewsInput & {
textOffset?: Offset;
iconOffset?: Offset;
animations?: StateAnimations;
nineSlicePlane?: [number, number, number, number];
};

/**
Expand Down Expand Up @@ -108,6 +110,9 @@ export class FancyButton extends ButtonContainer
protected originalInnerViewState: AnimationData;
protected defaultDuration = 100;

/** FancyButton options. */
protected readonly options?: ButtonOptions;

/** Padding of the button text view. If button text does not fit active view + padding it will scale down to fit. */
_padding: number;

Expand Down Expand Up @@ -156,6 +161,8 @@ export class FancyButton extends ButtonContainer
{
super();

this.options = options;

const {
defaultView,
hoverView,
Expand Down Expand Up @@ -522,7 +529,22 @@ export class FancyButton extends ButtonContainer
return;
}

this._views[viewType] = getView(view);
if (this.options?.nineSlicePlane)
{
if (typeof view === 'string')
{
this._views[viewType] = new NineSlicePlane(Texture.from(view), ...this.options.nineSlicePlane);
}
else
{
console.warn('NineSlicePlane can not be used with views set as Container.');
}
}

if (!this._views[viewType])
{
this._views[viewType] = getView(view);
}

this.setOffset(this._views[viewType], this.state, this.offset);

Expand Down Expand Up @@ -772,4 +794,90 @@ export class FancyButton extends ButtonContainer
{
return this._textOffset;
}

/**
* Sets width of a FancyButtons state views.
* If nineSlicePlane is set, then width will be set to nineSlicePlanes of a views.
* If nineSlicePlane is not set, then width will control components width as Container.
* @param width - Width value.
*/
override set width(width: number)
{
if (this.options?.nineSlicePlane)
{
if (this._views.defaultView)
{
this._views.defaultView.width = width;
}
if (this._views.hoverView)
{
this._views.hoverView.width = width;
}
if (this._views.pressedView)
{
this._views.pressedView.width = width;
}
if (this._views.disabledView)
{
this._views.disabledView.width = width;
}

this.adjustTextView(this.state);
this.adjustIconView(this.state);
this.updateAnchor();
}
else
{
super.width = width;
}
}

/** Gets width of a FancyButton. */
override get width(): number
{
return super.width;
}

/**
* Sets height of a FancyButtons state views.
* If nineSlicePlane is set, then height will be set to nineSlicePlanes of a views.
* If nineSlicePlane is not set, then height will control components height as Container.
* @param height - Height value.
*/
override set height(height: number)
{
if (this.options?.nineSlicePlane)
{
if (this._views.defaultView)
{
this._views.defaultView.height = height;
}
if (this._views.hoverView)
{
this._views.hoverView.height = height;
}
if (this._views.pressedView)
{
this._views.pressedView.height = height;
}
if (this._views.disabledView)
{
this._views.disabledView.height = height;
}

this.adjustTextView(this.state);
this.adjustIconView(this.state);
this.updateAnchor();
}
else
{
super.height = height;
}
}

/** Gets height of a FancyButton. */
override get height(): number
{
return super.height;
}
}
Loading
Loading