Skip to content

Commit 9d06b7b

Browse files
committed
scaling from bottom right corner
1 parent e860d45 commit 9d06b7b

File tree

9 files changed

+132
-31
lines changed

9 files changed

+132
-31
lines changed

example/game.js

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
const game = new Phaser.Game({
22
width: 1920,
3-
height: 1080,
3+
height: 1920,
44
renderer: Phaser.CANVAS,
55
parent: 'game',
66
scaleMode: Phaser.ScaleManager.USER_SCALE,
@@ -44,8 +44,21 @@ function create() {
4444
const DIST = 400;
4545

4646
const parent = new Phaser.Group(game, game.world);
47-
parent.position.set(100, 300)
48-
47+
parent.position.set(100, 300);
48+
49+
// parent.top = 0;
50+
// game.tweens.create(parent.scale)
51+
// .to({ x: 0.5, y: 0.5 }, 2000)
52+
// .to({ x: 1, y: 1 }, 2000)
53+
// .repeatAll(-1)
54+
// .start();
55+
56+
// game.tweens.create(parent)
57+
// .to({ top: 0 }, 2000)
58+
// .to({ top: 0 }, 2000)
59+
// .repeatAll(-1)
60+
// .start();
61+
4962
// 0 0
5063
let child = el(DIST * 0, DIST * 0, SIZE, SIZE, parent, 'child-a0-p0 child-a0-p0 child-a0-p0 child-a0-p0');
5164

@@ -86,16 +99,24 @@ function create() {
8699
child = el(DIST * 2, DIST * 2, SIZE, SIZE, parent, 'child-a1-p1');
87100
child.anchor.set(1, 1);
88101
child.pivot.set(SIZE, SIZE);
89-
90-
102+
103+
91104
child = el(DIST * 3, 100, SIZE * 2, SIZE * 2, parent, 'child');
105+
parent.setChildIndex(child, 0)
106+
child.anchor.set(1, 1);
92107
child.pivot.set(SIZE * 1.5, SIZE * 1.5);
108+
// game.tweens.create(child.scale)
109+
// .to({ x: 0.5, y: 0.5 }, 2000)
110+
// .to({ x: 1, y: 1 }, 2000)
111+
// .repeatAll(-1)
112+
// .start();
113+
93114

94115
child = el(DIST * 3, 500, SIZE, SIZE, parent, 'child');
95116
child.scale.set(-1, -1);
96117

97118

98-
child = game.add.sprite(1180, 925, 'phaser');
119+
child = game.add.sprite(900, 600, 'phaser');
99120
child.name = 'sprite';
100121
child.scale.set(2, 2);
101122

src/editor-view/selectors/gizmos/scale-gizmo.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,28 @@
11
import { Gizmo, GIZMO_SCALE } from './gizmo';
22
import './scale-gizmo.scss';
33

4+
export enum Corner {
5+
TopLeft,
6+
TopRight,
7+
BottomLeft,
8+
BottomRight,
9+
}
10+
411
export class ScaleGizmo extends HTMLElement implements Gizmo {
512
public static readonly tagName = 'phred-scale-gizmo';
613
public readonly type = GIZMO_SCALE;
14+
public corner: Corner;
715

8-
public init(corner: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right') {
9-
this.classList.add(corner);
16+
public init(corner: Corner) {
17+
this.corner = corner ?? 0;
18+
let clazz = '';
19+
switch (corner) {
20+
case Corner.TopRight: clazz = 'top-right'; break;
21+
case Corner.BottomLeft: clazz = 'bottom-left'; break;
22+
case Corner.BottomRight: clazz = 'bottom-right'; break;
23+
default: clazz = 'top-left';
24+
}
25+
this.classList.add(clazz);
1026
this.appendChild(document.createElement('div')).classList.add('handle');
1127
}
1228
}

src/editor-view/selectors/gizmos/selection-gizmo.ts

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Rect } from 'plugin.model';
22
import { Selection, SelectionChangedEvent } from '../selection';
33
import { SelectionUtil } from '../selection.util';
44
import { Gizmo, GIZMO_MOVE } from './gizmo';
5-
import { ScaleGizmo } from './scale-gizmo';
5+
import { Corner, ScaleGizmo } from './scale-gizmo';
66
import './selection-gizmo.scss';
77

88
// interface PropertiesCache {
@@ -18,9 +18,12 @@ export class SelectionGizmo extends HTMLElement implements Gizmo {
1818
public static readonly tagName = 'phred-selection-gizmo';
1919
public readonly type = GIZMO_MOVE;
2020

21+
private _isOver = false;
2122
private _rect: Rect = { x: 0, y: 0, width: 0, height: 0 };
2223
private handlers: HTMLElement[] = [];
2324

25+
public get isOver() { return this._isOver; }
26+
2427
// private _selectionPropertiesCache: PropertiesCache = {
2528
// x: 0, y: 0, width: 0, height: 0, scaleX: 0, scaleY: 0
2629
// }
@@ -29,24 +32,27 @@ export class SelectionGizmo extends HTMLElement implements Gizmo {
2932
selection.addEventListener('changed', this.onSelectionChanged.bind(this));
3033
this.classList.add('selector');
3134

35+
this.addEventListener('mouseover', this.onMouseOver.bind(this));
36+
this.addEventListener('mouseout', this.onMouseOut.bind(this));
37+
3238
this.createResizeHandlers(this.handlers);
3339
}
3440

3541
private createResizeHandlers(handlers: HTMLElement[]) {
3642
const tl = this.appendChild(document.createElement(ScaleGizmo.tagName)) as ScaleGizmo;
37-
tl.init('top-left');
43+
tl.init(Corner.TopLeft);
3844
handlers.push(tl);
3945

4046
const tr = this.appendChild(document.createElement(ScaleGizmo.tagName)) as ScaleGizmo;
41-
tr.init('top-right');
47+
tr.init(Corner.TopRight);
4248
handlers.push(tr);
4349

4450
const bl = this.appendChild(document.createElement(ScaleGizmo.tagName)) as ScaleGizmo;
45-
bl.init('bottom-left');
51+
bl.init(Corner.BottomLeft);
4652
handlers.push(bl);
4753

4854
const br = this.appendChild(document.createElement(ScaleGizmo.tagName)) as ScaleGizmo;
49-
br.init('bottom-right');
55+
br.init(Corner.BottomRight);
5056
handlers.push(br);
5157
}
5258

@@ -75,16 +81,26 @@ export class SelectionGizmo extends HTMLElement implements Gizmo {
7581
}
7682

7783
public startMoving() {
84+
this.style.pointerEvents = 'none';
7885
this.handlers.forEach(h => h.style.pointerEvents = 'none');
7986
}
80-
87+
8188
public stopMoving() {
89+
this.style.pointerEvents = 'all';
8290
this.handlers.forEach(h => h.style.pointerEvents = 'all');
8391
}
8492

93+
94+
// #region Event Listeners
95+
8596
public onSelectionChanged(event: SelectionChangedEvent) {
8697
this.style.display = event.detail ? 'block' : 'none';
8798
}
99+
100+
public onMouseOver() { this._isOver = true; }
101+
public onMouseOut() { this._isOver = false; }
102+
103+
// #endregion
88104
}
89105

90106
customElements.define(SelectionGizmo.tagName, SelectionGizmo);
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export interface DraggingHandler {
2-
startHandling(e: MouseEvent): void;
2+
startHandling(e: MouseEvent, object: PIXI.DisplayObject): void;
33
handle(e: MouseEvent): void;
44
stopHandling(e: MouseEvent): void;
55
}
Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
import { Point } from 'plugin.model';
2-
import { Selection } from '../selection';
32
import { SelectionUtil } from '../selection.util';
43
import { DraggingHandler } from './dragging-handler';
54

65
export class MoveHandler implements DraggingHandler {
7-
private readonly selection: Selection;
86
private _point: Point = { x: 0, y: 0 };
7+
private _object: PIXI.DisplayObject;
98

10-
public constructor(selection: Selection) {
11-
this.selection = selection;
12-
}
13-
14-
public startHandling(e: MouseEvent) {
9+
public startHandling(e: MouseEvent, object: PIXI.DisplayObject) {
10+
this._object = object;
1511
SelectionUtil.mouseEventToGamePoint(e, this._point);
1612
}
1713

@@ -23,9 +19,8 @@ export class MoveHandler implements DraggingHandler {
2319
const dy = newPoint.y - lastPoint.y
2420
this._point = newPoint;
2521

26-
const object = this.selection.object;
27-
object.position.set(object.x + dx, object.y + dy);
22+
this._object.position.set(this._object.x + dx, this._object.y + dy);
2823
}
2924

30-
public stopHandling() { }
25+
public stopHandling() { this._object = null; }
3126
}
Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,55 @@
1+
import { Point } from 'plugin.model';
2+
import { ScaleGizmo } from '../gizmos/scale-gizmo';
3+
import { SelectionUtil } from '../selection.util';
14
import { DraggingHandler } from './dragging-handler';
25

36
export class ScaleHandler implements DraggingHandler {
4-
public startHandling(e: MouseEvent): void {
7+
private _point: Point;
8+
private _object: PIXI.DisplayObject;
9+
private _isGroup: boolean;
10+
private _top: number;
11+
private _left: number;
12+
13+
public startHandling(e: MouseEvent, object: PIXI.DisplayObject): void {
14+
const corner = (e.target as ScaleGizmo).corner;
15+
this._object = object;
16+
17+
object.position.set(object.x - object.pivot.x, object.y - object.pivot.y);
18+
object.pivot.set(0, 0);
19+
20+
this._isGroup = !object.anchor;
21+
if (this._isGroup) {
22+
this._top = object.top;
23+
this._left = object.left;
24+
}
525
}
626

727
public handle(e: MouseEvent): void {
28+
if (!this._point) {
29+
this._point = SelectionUtil.mouseEventToGamePoint(e, { x: 0, y: 0 });
30+
}
31+
32+
const lastPoint = this._point;
33+
const newPoint = SelectionUtil.mouseEventToGamePoint(e, { x: 0, y: 0 });
34+
35+
const dx = newPoint.x - lastPoint.x
36+
const dy = newPoint.y - lastPoint.y
37+
this._point = newPoint;
38+
39+
this._object.updateTransform();
40+
this._object.width = this._object.width + dx;
41+
this._object.height = this._object.height + dy;
42+
43+
if (this._isGroup) {
44+
this._object.top = this._top;
45+
this._object.left = this._left;
46+
}
47+
this._object.updateTransform();
848
}
949

1050
public stopHandling(e: MouseEvent): void {
51+
this._point = null;
52+
if (!this._object) return;
53+
// TODO reset object
1154
}
1255
}

src/editor-view/selectors/selection-area.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export class SelectionArea extends HTMLElement {
4747

4848
private createHandlers(selection: Selection) {
4949
this.selectionHandler = new SelectionHandler(selection);
50-
this.moveHandler = new MoveHandler(selection);
50+
this.moveHandler = new MoveHandler();
5151
this.scaleHandler = new ScaleHandler();
5252
}
5353

@@ -76,7 +76,7 @@ export class SelectionArea extends HTMLElement {
7676
if (e.button !== 0) return;
7777
this._mouseIsDown = true;
7878
this._isDragging = false;
79-
this._hasSelection = this.selectionHandler.isOverSelection(e);
79+
this._hasSelection = this.gizmo.isOver;
8080
this._handler = (e.target as Gizmo).type === GIZMO_SCALE
8181
? this.scaleHandler : this.moveHandler;
8282
}
@@ -86,6 +86,7 @@ export class SelectionArea extends HTMLElement {
8686
this._mouseIsDown = false;
8787
this._handler?.stopHandling(e);
8888
this._handler = null;
89+
this.gizmo.stopMoving();
8990
if (!(this._hasSelection && this._isDragging)) {
9091
this._hasSelection = this.selectionHandler.selectAt(e);
9192
}
@@ -99,9 +100,11 @@ export class SelectionArea extends HTMLElement {
99100
if (!this._hasSelection) {
100101
this._hasSelection = this.selectionHandler.selectAt(e);
101102
}
102-
console.log(this._handler);
103-
this._handler.startHandling(e);
104-
this.gizmo.startMoving();
103+
if (this._hasSelection) {
104+
this._handler.startHandling(e, this.selection.object);
105+
this.gizmo.startMoving();
106+
return;
107+
}
105108
}
106109
this._handler.handle(e);
107110
}

src/editor-view/selectors/selection.util.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class SelectionUtilClass {
1010
}
1111

1212
public mouseEventToGamePoint(e: MouseEvent, out: Point) {
13+
// TODO test if offsetLeft/offsetRight is different than 0
1314
return SelectionUtil.pointFromAreaToGame(
1415
(e.target as HTMLElement).offsetLeft + e.offsetX,
1516
(e.target as HTMLElement).offsetTop + e.offsetY,

src/global.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ declare namespace PIXI {
1111
inputEnabled?: boolean;
1212
getBounds?(): Rectangle;
1313
children?: DisplayObject[];
14+
top: number;
15+
left: number;
16+
bottom: number;
17+
right: number;
18+
width: number;
19+
height: number;
1420
}
1521
}
1622

0 commit comments

Comments
 (0)