Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions src/assets/textures/rect.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@ import { Graphics } from 'pixi.js';
import { getColor } from '../../utils/get';
import { cacheKey, generateTexture } from './utils';

export const createRectTexture = (rectOpts) => {
export const createRectTexture = (renderer, theme, rectOpts) => {
const {
fill = null,
borderWidth = null,
borderColor = null,
radius = null,
} = rectOpts;
const rect = createRect({ fill, borderWidth, borderColor, radius });
const texture = generateTexture(rect);
const rect = createRect(theme, { fill, borderWidth, borderColor, radius });
const texture = generateTexture(rect, renderer);

texture.id = cacheKey(rectOpts);
texture.id = cacheKey(renderer, rectOpts);
texture.metadata = {
slice: {
topHeight: borderWidth + 4,
Expand All @@ -26,7 +26,7 @@ export const createRectTexture = (rectOpts) => {
return texture;
};

const createRect = ({ fill, borderWidth, borderColor, radius }) => {
const createRect = (theme, { fill, borderWidth, borderColor, radius }) => {
const graphics = new Graphics();
const size = 20 + borderWidth;

Expand All @@ -37,11 +37,11 @@ const createRect = ({ fill, borderWidth, borderColor, radius }) => {
graphics.rect(...xywh);
}

if (fill) graphics.fill(getColor(fill));
if (fill) graphics.fill(getColor(theme, fill));
if (borderWidth) {
graphics.stroke({
width: borderWidth,
color: getColor(borderColor),
color: getColor(theme, borderColor),
});
}
return graphics;
Expand Down
16 changes: 8 additions & 8 deletions src/assets/textures/texture.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
import { Assets, Cache } from 'pixi.js';
import { Assets } from 'pixi.js';
import { createRectTexture } from './rect';
import { cacheKey } from './utils';

export const getTexture = (config) => {
export const getTexture = (renderer, theme, config) => {
let texture = null;
if (typeof config === 'string') {
texture = Assets.get(config);
} else {
texture = Cache.has(cacheKey(config))
? Assets.get(cacheKey(config))
: createTexture(config);
texture = Assets.cache.has(cacheKey(renderer, config))
? Assets.cache.get(cacheKey(renderer, config))
: createTexture(renderer, theme, config);
}
return texture;
};

export const createTexture = (config) => {
export const createTexture = (renderer, theme, config) => {
let texture = null;
switch (config.type) {
case 'rect':
texture = createRectTexture(config);
texture = createRectTexture(renderer, theme, config);
break;
}
Cache.set(cacheKey(config), texture);
Assets.cache.set(cacheKey(renderer, config), texture);
return texture;
};
14 changes: 7 additions & 7 deletions src/assets/textures/utils.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import { TextureStyle } from '../../display/data-schema/component-schema';
import { deepMerge } from '../../utils/deepmerge/deepmerge';
import { renderer } from '../../utils/renderer';

const RESOLUTION = 5;

export const generateTexture = (target = null, opts = {}) => {
export const generateTexture = (target, renderer, opts = {}) => {
const options = deepMerge({ resolution: RESOLUTION }, opts);
if (!target) return;

const texture = renderer.get().generateTexture({
const texture = renderer.generateTexture({
target,
resolution: options.resolution,
});
return texture;
};

export const cacheKey = (config) => {
return TextureStyle.keyof()
.options.map((key) => config[key])
.join('-');
export const cacheKey = (renderer, config) => {
return [
renderer.uid,
...TextureStyle.keyof().options.map((key) => config[key]),
].join('-');
};
12 changes: 9 additions & 3 deletions src/command/commands/tint.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ export class TintCommand extends Command {
* Creates an instance of TintCommand.
* @param {Object} object - The Pixi.js display object whose tint will be changed.
* @param {Object} config - The new configuration for the object's tint.
* @param {object} options - Options for command execution.
*/
constructor(object, config) {
constructor(object, config, options) {
super('tint_object');
this.object = object;
this._config = parsePick(config, optionKeys);
this._prevConfig = parsePick(object.config, optionKeys);
this._options = options;
}

get config() {
Expand All @@ -33,17 +35,21 @@ export class TintCommand extends Command {
return this._prevConfig;
}

get options() {
return this._options;
}

/**
* Executes the command to change the object's tint.
*/
execute() {
changeTint(this.object, this.config);
changeTint(this.object, this.config, this.options);
}

/**
* Undoes the command, reverting the object's tint to its previous state.
*/
undo() {
changeTint(this.object, this.prevConfig);
changeTint(this.object, this.prevConfig, this.options);
}
}
2 changes: 0 additions & 2 deletions src/command/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import * as commands from './commands';
import { UndoRedoManager } from './undo-redo-manager';

export const Commands = commands;
export const undoRedoManager = new UndoRedoManager();
49 changes: 30 additions & 19 deletions src/command/undo-redo-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export class UndoRedoManager {
this._index = -1;
this._listeners = new Set();
this._maxCommands = maxCommands;
this._hotkeyListener = null;
}

/**
Expand Down Expand Up @@ -133,26 +134,36 @@ export class UndoRedoManager {
* @private
*/
_setHotkeys() {
document.addEventListener(
'keydown',
(e) => {
const key = (e.key || '').toLowerCase();
if (isInput(e.target)) return;

if (key === 'z' && (e.ctrlKey || e.metaKey)) {
if (e.shiftKey) {
this.redo();
} else {
this.undo();
}
e.preventDefault();
}
if (key === 'y' && (e.ctrlKey || e.metaKey)) {
this._hotkeyListener = (e) => {
const key = (e.key || '').toLowerCase();
if (isInput(e.target)) return;

if (key === 'z' && (e.ctrlKey || e.metaKey)) {
if (e.shiftKey) {
this.redo();
e.preventDefault();
} else {
this.undo();
}
},
false,
);
e.preventDefault();
}
if (key === 'y' && (e.ctrlKey || e.metaKey)) {
this.redo();
e.preventDefault();
}
};

document.addEventListener('keydown', this._hotkeyListener, false);
}

/**
* Removes event listeners and clears all internal states to prevent memory leaks.
*/
destroy() {
if (this._hotkeyListener) {
document.removeEventListener('keydown', this._hotkeyListener, false);
this._hotkeyListener = null;
}
this.clear();
this._listeners.clear();
}
}
6 changes: 4 additions & 2 deletions src/display/change/asset.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { getTexture } from '../../assets/textures/texture';
import { getViewport } from '../../utils/get';
import { isConfigMatch, updateConfig } from './utils';

export const changeAsset = (object, { asset: assetConfig }) => {
export const changeAsset = (object, { asset: assetConfig }, { theme }) => {
if (isConfigMatch(object, 'asset', assetConfig)) {
return;
}

const asset = getTexture(assetConfig);
const renderer = getViewport(object).app.renderer;
const asset = getTexture(renderer, theme, assetConfig);
if (!asset) {
console.warn(`Asset not found for config: ${JSON.stringify(assetConfig)}`);
}
Expand Down
23 changes: 15 additions & 8 deletions src/display/change/percent-size.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export const changePercentSize = (
margin = object.config.margin,
animationDuration = object.config.animationDuration,
},
{ animationContext },
) => {
if (
isConfigMatch(object, 'percentWidth', percentWidth) &&
Expand All @@ -21,8 +22,12 @@ export const changePercentSize = (
}

const marginObj = parseMargin(margin);
if (percentWidth) changeWidth(object, percentWidth, marginObj);
if (percentHeight) changeHeight(object, percentHeight, marginObj);
if (Number.isFinite(percentWidth)) {
changeWidth(object, percentWidth, marginObj);
}
if (Number.isFinite(percentHeight)) {
changeHeight(object, percentHeight, marginObj);
}
updateConfig(object, {
percentWidth,
percentHeight,
Expand All @@ -41,12 +46,14 @@ export const changePercentSize = (
component.parent.size.height - (marginObj.top + marginObj.bottom);

if (object.config.animation) {
killTweensOf(component);
gsap.to(component, {
pixi: { height: maxHeight * percentHeight },
duration: animationDuration / 1000,
ease: 'power2.inOut',
onUpdate: () => changePlacement(component, {}),
animationContext.add(() => {
killTweensOf(component);
gsap.to(component, {
pixi: { height: maxHeight * percentHeight },
duration: animationDuration / 1000,
ease: 'power2.inOut',
onUpdate: () => changePlacement(component, {}),
});
});
} else {
component.height = maxHeight * percentHeight;
Expand Down
2 changes: 1 addition & 1 deletion src/display/change/pipeline/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as change from '..';
import { Commands } from '../../../command';
import { createCommandHandler } from './utils';

export const pipeline = {
export const basePipeline = {
show: {
keys: ['show'],
handler: createCommandHandler(Commands.ShowCommand, change.changeShow),
Expand Down
20 changes: 10 additions & 10 deletions src/display/change/pipeline/component.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import * as change from '..';
import { Commands } from '../../../command';
import { pipeline } from './base';
import { basePipeline } from './base';
import { createCommandHandler } from './utils';

export const componentPipeline = {
...pipeline,
...basePipeline,
tint: {
keys: ['color', 'tint'],
handler: createCommandHandler(Commands.TintCommand, change.changeTint),
},
texture: {
keys: ['texture'],
handler: (component, config) => {
change.changeTexture(component, config);
handler: (component, config, options) => {
change.changeTexture(component, config, options);
},
},
asset: {
keys: ['asset'],
handler: (component, config) => {
change.changeAsset(component, config);
handler: (component, config, options) => {
change.changeAsset(component, config, options);
},
},
textureTransform: {
Expand All @@ -35,8 +35,8 @@ export const componentPipeline = {
},
percentSize: {
keys: ['percentWidth', 'percentHeight', 'margin'],
handler: (component, config) => {
change.changePercentSize(component, config);
handler: (component, config, options) => {
change.changePercentSize(component, config, options);
change.changePlacement(component, {});
},
},
Expand All @@ -60,8 +60,8 @@ export const componentPipeline = {
},
textStyle: {
keys: ['style', 'margin'],
handler: (component, config) => {
change.changeTextStyle(component, config);
handler: (component, config, options) => {
change.changeTextStyle(component, config, options);
change.changePlacement(component, config); // Ensure placement is updated after style change
},
},
Expand Down
4 changes: 2 additions & 2 deletions src/display/change/pipeline/element.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import * as change from '..';
import { Commands } from '../../../command';
import { updateComponents } from '../../update/update-components';
import { pipeline } from './base';
import { basePipeline } from './base';
import { createCommandHandler } from './utils';

export const elementPipeline = {
...pipeline,
...basePipeline,
position: {
keys: ['position'],
handler: createCommandHandler(
Expand Down
7 changes: 3 additions & 4 deletions src/display/change/pipeline/utils.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { undoRedoManager } from '../../../command';

export const createCommandHandler = (Command, changeFn) => {
return (object, config, options) => {
const { undoRedoManager } = options;
if (options?.historyId) {
undoRedoManager.execute(new Command(object, config), {
undoRedoManager.execute(new Command(object, config, options), {
historyId: options.historyId,
});
} else {
changeFn(object, config);
changeFn(object, config, options);
}
};
};
8 changes: 6 additions & 2 deletions src/display/change/stroke-style.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ import { getColor } from '../../utils/get';
import { selector } from '../../utils/selector/selector';
import { updateConfig } from './utils';

export const changeStrokeStyle = (object, { strokeStyle, links }) => {
export const changeStrokeStyle = (
object,
{ strokeStyle, links },
{ theme },
) => {
const path = selector(object, '$.children[?(@.type==="path")]')[0];
if (!path) return;

if ('color' in strokeStyle) {
strokeStyle.color = getColor(strokeStyle.color);
strokeStyle.color = getColor(theme, strokeStyle.color);
}

path.setStrokeStyle({ ...path.strokeStyle, ...strokeStyle });
Expand Down
Loading