From c8c9249eb0837fe0cd4f6f8a9986ba48b3419ce7 Mon Sep 17 00:00:00 2001 From: Kleber Silva Date: Sat, 2 Oct 2021 10:41:13 -0300 Subject: [PATCH] hit area --- example/game.js | 3 ++- src/core/editor.ts | 5 +++-- src/core/preferences.ts | 5 +++-- src/editor-view/actions/actions-toolbar.ts | 6 +++++- src/editor-view/actions/button/action-button.ts | 7 ++----- src/editor-view/editor-view.ts | 2 ++ src/scene-view/scene-view.ts | 17 ++++++----------- src/scene-view/scene-view.util.ts | 14 ++++++++++++++ src/scene-view/selection/selection.ts | 17 ++++++++--------- 9 files changed, 45 insertions(+), 31 deletions(-) create mode 100644 src/scene-view/scene-view.util.ts diff --git a/example/game.js b/example/game.js index 04bfb81..666da0a 100644 --- a/example/game.js +++ b/example/game.js @@ -56,7 +56,8 @@ function create() { // 0 1 child = el(DIST * 2, DIST * 0, SIZE, SIZE, parent, 'child-a0-p1'); child.pivot.set(SIZE, SIZE); - + child.inputEnabled = true; + child.hitArea = new Phaser.Circle(0, 0, 200); // .5 0 child = el(DIST * 0, DIST * 1, SIZE, SIZE, parent, 'child-a.5-p0'); diff --git a/src/core/editor.ts b/src/core/editor.ts index f7fda47..64971f9 100644 --- a/src/core/editor.ts +++ b/src/core/editor.ts @@ -65,7 +65,8 @@ class EditorClass { { name: 'frameName', label: 'frame', typeHint: 'string' }, { name: 'blendMode', typeHint: 'valueList', values: Phaser.blendModes }, { name: 'tint', typeHint: 'color' }, - { name: 'hitArea', typeHint: 'rect' }, + // TODO waiting for multiple type hint + // { name: 'hitArea', typeHint: 'rect' }, // Text { name: 'text', typeHint: 'text', data: { rows: 3 } }, @@ -88,7 +89,7 @@ class EditorClass { const basicProperties = { title: '', properties: [ '__type', 'name', 'position', 'scale', 'pivot', 'anchor', - 'alpha', 'visible', 'angle', 'hitArea', '_bounds' + 'alpha', 'visible', 'angle', '_bounds' ] }; diff --git a/src/core/preferences.ts b/src/core/preferences.ts index 35f7854..a6f98b5 100644 --- a/src/core/preferences.ts +++ b/src/core/preferences.ts @@ -64,7 +64,6 @@ export class Preferences { public set allHitAreasSnapshot(value: boolean) { this._allHitAreasSnapshot = value; this.notifyListeners('allHitAreasSnapshot', value); - this.save('allHitAreasSnapshot', value); } private _responsive = false; @@ -87,6 +86,8 @@ export class Preferences { this._snap = this.load('snap', true); this._gizmos = this.load('gizmos', true); this._guides = this.load('guides', false); + this._hitArea = this.load('hitArea', false); + this._responsive = this.load('responsive', false); this._refImage = this.load('refImage', false); } @@ -94,9 +95,9 @@ export class Preferences { public setupActions(actions: ActionHandler) { actions.setActionCommand(Actions.TOGGLE_SNAP, () => this.snap = !this._snap, () => this._snap); actions.setActionCommand(Actions.TOGGLE_GIZMOS, () => this.gizmos = !this._gizmos, () => this._gizmos); + actions.setActionCommand(Actions.TOGGLE_GUIDES, () => this.guides = !this._guides, () => this._guides); actions.setActionCommand(Actions.TOGGLE_HIT_AREA, () => this.hitArea = !this._hitArea, () => this._hitArea); actions.setActionCommand(Actions.TOGGLE_ALL_HIT_AREAS_SNAPSHOT, () => this.allHitAreasSnapshot = !this._allHitAreasSnapshot, () => this._allHitAreasSnapshot); - actions.setActionCommand(Actions.TOGGLE_GUIDES, () => this.guides = !this._guides, () => this._guides); actions.setActionCommand(Actions.TOGGLE_RESPONSIVE, () => this.responsive = !this._responsive, () => this._responsive); actions.setActionCommand(Actions.TOGGLE_REF_IMAGE, () => this.refImage = !this._refImage, () => this._refImage); } diff --git a/src/editor-view/actions/actions-toolbar.ts b/src/editor-view/actions/actions-toolbar.ts index 9a40e38..fbe4182 100644 --- a/src/editor-view/actions/actions-toolbar.ts +++ b/src/editor-view/actions/actions-toolbar.ts @@ -6,6 +6,8 @@ import './actions-toolbar.scss'; import { ActionButton } from './button/action-button'; export class ActionsToolbar extends Widget { + private readonly _buttons: ActionButton[] = []; + public setupActions(actions: ActionHandler) { this.createButton(actions.getAction(Actions.TOGGLE_ENABLED)); this.createSeparator(); @@ -26,7 +28,8 @@ export class ActionsToolbar extends Widget { this.createSpacer(); } - public enable() { } + public enable() { this._buttons.forEach(e => e.updateState()); } + public disable() { } private createButton(action: Action) { @@ -34,6 +37,7 @@ export class ActionsToolbar extends Widget { const btn = document.createElement(ComponentTags.ActionButton) as ActionButton; btn.setAction(action); this.appendChild(btn); + this._buttons.push(btn); } private createSeparator() { diff --git a/src/editor-view/actions/button/action-button.ts b/src/editor-view/actions/button/action-button.ts index 1ad54ef..7b4821b 100644 --- a/src/editor-view/actions/button/action-button.ts +++ b/src/editor-view/actions/button/action-button.ts @@ -25,9 +25,6 @@ export class ActionButton extends HTMLElement { } this.onclick = this.toggleSelected.bind(this); this.updateState(); - Editor.prefs.onPreferenceChanged.add((pref: PreferenceKey) => { - if (pref === 'gizmos') this.updateState(); - }); } private toggleSelected() { @@ -35,8 +32,8 @@ export class ActionButton extends HTMLElement { this.updateState(); } - private updateState() { - if (this.action.state()) this.classList.add('selected'); + public updateState() { + if (this.action.state?.()) this.classList.add('selected'); else this.classList.remove('selected'); } } diff --git a/src/editor-view/editor-view.ts b/src/editor-view/editor-view.ts index dc7e832..5fb5943 100644 --- a/src/editor-view/editor-view.ts +++ b/src/editor-view/editor-view.ts @@ -68,12 +68,14 @@ export class EditorView extends Widget { this.panels.forEach(panel => panel.enable()); this.gameContainer.addGame(this.game); + this.actions.enable(); document.body.appendChild(this); } public disable() { if (!this._enabled) return; this._enabled = false; + this.actions.disable(); this.gameContainer.returnGameToItsParent(); this.panels.forEach(panel => panel.enable()); this.parentElement.removeChild(this); diff --git a/src/scene-view/scene-view.ts b/src/scene-view/scene-view.ts index 7cdf493..aef0b95 100644 --- a/src/scene-view/scene-view.ts +++ b/src/scene-view/scene-view.ts @@ -1,10 +1,11 @@ import { ActionHandler } from 'core/action-handler'; import { Actions } from 'core/actions'; import { Editor } from 'core/editor'; +import { PreferenceKey } from 'core/preferences'; import { DataOrigin } from 'data/editor-data'; -import { HIT_AREA_COLOR, PreferenceKey } from 'index'; import { DragUtil } from '../util/drag.util'; import { SceneModel } from './scene-model'; +import { SceneViewUtil } from './scene-view.util'; import { Selection } from './selection/selection'; export class SceneView extends Phaser.Group { @@ -69,7 +70,6 @@ export class SceneView extends Phaser.Group { actions.setActionCommand(Actions.MOVE_RIGHT_10, () => this.moveSelectedObject(10, 0)); Editor.prefs.onPreferenceChanged.add(this.onPreferencesChanged, this); - this.onPreferencesChanged('responsive', Editor.prefs.responsive); } public enable(root: Container, parent: Phaser.Stage) { @@ -77,10 +77,12 @@ export class SceneView extends Phaser.Group { if (this.parent === parent) return; parent.addChild(this); this.touchArea.input.enabled = true; + // this.onPreferencesChanged('allHitAreasSnapshot', Editor.prefs.allHitAreasSnapshot); } public disable() { if (!this.parent) return; + Editor.prefs.allHitAreasSnapshot = false; this.parent.removeChild(this); this.touchArea.input.enabled = false; } @@ -204,18 +206,11 @@ export class SceneView extends Phaser.Group { } private showAllHitAreas(parent: PIXI.DisplayObjectContainer, view: Phaser.Graphics) { - if (parent.__isLeaf || !parent.visible) return; + if (!parent.visible || parent.__isLeaf) return; const children = parent.children; for (let i = 0, n = children.length; i < n; i++) { const child = children[i]; - console.log(child.name, child.inputEnabled); - if (child.visible && child.inputEnabled) { - const area = child.hitArea as PIXI.Rectangle ?? child.getBounds(); - view.lineStyle(1, HIT_AREA_COLOR, 1) - .beginFill(HIT_AREA_COLOR, 0.3) - .drawRect(area.x, area.y, area.width, area.height) - .endFill(); - } + if (child.visible && child.inputEnabled) SceneViewUtil.drawHitArea(child, child.getBounds(), view); if ('children' in child) this.showAllHitAreas(child as PIXI.DisplayObjectContainer, view); } } diff --git a/src/scene-view/scene-view.util.ts b/src/scene-view/scene-view.util.ts new file mode 100644 index 0000000..3172969 --- /dev/null +++ b/src/scene-view/scene-view.util.ts @@ -0,0 +1,14 @@ +import { HIT_AREA_COLOR } from './scene-colors'; + +export class SceneViewUtil { + public static drawHitArea(obj: PIXI.DisplayObject, bounds: PIXI.Rectangle, view: Phaser.Graphics) { + const area = obj.hitArea ?? bounds; + view.lineStyle(1, HIT_AREA_COLOR, 1).beginFill(HIT_AREA_COLOR, 0.5); + if (area instanceof Phaser.Rectangle) { + view.drawRect(area.x, area.y, area.width, area.height) + } else if (area instanceof Phaser.Circle) { + view.drawCircle(bounds.x + area.x, bounds.y + area.y, area.diameter) + } + view.endFill(); + } +} \ No newline at end of file diff --git a/src/scene-view/selection/selection.ts b/src/scene-view/selection/selection.ts index 76c66ea..21a2860 100644 --- a/src/scene-view/selection/selection.ts +++ b/src/scene-view/selection/selection.ts @@ -1,7 +1,7 @@ import { Editor } from 'core/editor'; import { PreferenceKey } from 'core/preferences'; import { DataOrigin } from 'data/editor-data'; -import { HIT_AREA_COLOR } from 'index'; +import { SceneViewUtil } from 'scene-view/scene-view.util'; import { PointUtil } from 'util/math.util'; import { ANCHOR_COLOR, ANCHOR_STROKE, BORDER_COLOR, BORDER_STROKE, PIVOT_COLOR, PIVOT_STROKE } from '../scene-colors'; import { ScaleHandler } from './scale/scale.handler'; @@ -69,7 +69,7 @@ export class Selection extends Phaser.Group { if (!this._selectedObject) return; const bounds = this._selectedObject.getBounds(); if (this._showGuides) this.drawGuides(bounds); - if (this._showHitArea) this.drawHitArea(this._selectedObject, bounds); + if (this._showHitArea) this.drawHitArea(bounds); this.drawBorder(bounds); this.drawPivot(this.scaleHandler.scaling ? this.scaleHandler.scaler.originalPivot @@ -133,13 +133,12 @@ export class Selection extends Phaser.Group { .drawCircle(bounds.width * anchor.x, bounds.height * anchor.y, 10); } - private drawHitArea(obj: PIXI.DisplayObject, bounds: PIXI.Rectangle) { - const rect = obj.hitArea as PIXI.Rectangle ?? bounds; - this.view - .lineStyle(0) - .beginFill(HIT_AREA_COLOR, 0.3) - .drawRect(0, 0, rect.width, rect.height) - .endFill(); + private drawHitArea(bounds: PIXI.Rectangle) { + if (!this._selectedObject.inputEnabled) return; + const b = new PIXI.Rectangle(); + b.width = bounds.width; + b.height = bounds.height; + SceneViewUtil.drawHitArea(this._selectedObject, b, this.view); } public move(deltaX: number, deltaY: number) {