feat: graphics stage
This commit is contained in:
parent
9af970d641
commit
8b8216fe8f
|
@ -10,6 +10,7 @@ export {Primitives} from './primitives';
|
|||
export {Renderable} from './renderable';
|
||||
export {Renderer} from './renderer';
|
||||
export {Sprite} from './sprite';
|
||||
export {Stage} from './stage';
|
||||
|
||||
if (PIXI) {
|
||||
PIXI.settings.SCALE_MODE = PIXI.SCALE_MODES.NEAREST
|
||||
|
|
144
packages/graphics/stage.js
Normal file
144
packages/graphics/stage.js
Normal file
|
@ -0,0 +1,144 @@
|
|||
import {Vector} from '@avocado/math';
|
||||
|
||||
import {Container} from './container';
|
||||
import {Renderer} from './renderer';
|
||||
|
||||
export class Stage extends Container {
|
||||
|
||||
constructor(size) {
|
||||
super();
|
||||
this._canvasRatio = 1;
|
||||
this.parent = undefined;
|
||||
this.renderer = new Renderer(size);
|
||||
this.size = size;
|
||||
this.onWindowResize = this.onWindowResize.bind(this);
|
||||
window.addEventListener('resize', this.onWindowResize);
|
||||
const element = this.renderer.element;
|
||||
this.onPointerDown = this.onPointerDown.bind(this);
|
||||
for (const start of ['pointerdown', 'touchstart']) {
|
||||
element.addEventListener(start, this.onPointerDown);
|
||||
}
|
||||
this.onPointerMove = this.onPointerMove.bind(this);
|
||||
for (const move of ['pointermove', 'touchmove']) {
|
||||
element.addEventListener(move, this.onPointerMove);
|
||||
}
|
||||
this.onPointerUp = this.onPointerUp.bind(this);
|
||||
for (const end of ['pointerup', 'touchend']) {
|
||||
element.addEventListener(end, this.onPointerUp);
|
||||
}
|
||||
}
|
||||
|
||||
addToDom(parent) {
|
||||
if (this.parent) {
|
||||
this.parent.removeChild(this.renderer.element);
|
||||
}
|
||||
this.parent = parent;
|
||||
parent.appendChild(this.renderer.element);
|
||||
this.renderer.element.tabIndex = 0;
|
||||
this.renderer.element.focus();
|
||||
this.onWindowResize();
|
||||
}
|
||||
|
||||
get canvasRatio() {
|
||||
return this._canvasRatio;
|
||||
}
|
||||
|
||||
destroy() {
|
||||
window.removeEventListener('resize', this.onWindowResize);
|
||||
this.renderer.destroy();
|
||||
super.destroy();
|
||||
if (this.parent) {
|
||||
this.parent.removeChild(this.renderer.element);
|
||||
}
|
||||
for (const start of ['pointerdown', 'touchstart']) {
|
||||
element.removeEventListener(start, this.onPointerDown);
|
||||
}
|
||||
for (const move of ['pointermove', 'touchmove']) {
|
||||
element.removeEventListener(move, this.onPointerMove);
|
||||
}
|
||||
for (const end of ['pointerup', 'touchend']) {
|
||||
element.removeEventListener(end, this.onPointerUp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
get element() {
|
||||
return this.renderer.element;
|
||||
}
|
||||
|
||||
onPointerDown(event) {
|
||||
event = event || window.event;
|
||||
const position = this.translateEventPosition(event);
|
||||
const stageEvent = new StageEvent();
|
||||
stageEvent.position = position;
|
||||
this.emit('pointerDown', stageEvent);
|
||||
}
|
||||
|
||||
onPointerMove(event) {
|
||||
event = event || window.event;
|
||||
const position = this.translateEventPosition(event);
|
||||
const stageEvent = new StageEvent();
|
||||
stageEvent.position = position;
|
||||
this.emit('pointerMove', stageEvent);
|
||||
}
|
||||
|
||||
onPointerUp(event) {
|
||||
event = event || window.event;
|
||||
const position = this.translateEventPosition(event);
|
||||
const stageEvent = new StageEvent();
|
||||
stageEvent.position = position;
|
||||
this.emit('pointerUp', stageEvent);
|
||||
}
|
||||
|
||||
onWindowResize() {
|
||||
const element = this.renderer.element;
|
||||
if (this.parent) {
|
||||
const ratio = this.parent.clientWidth / this.parent.clientHeight;
|
||||
const axe = ratio > (16 / 9) ? 'height' : 'width';
|
||||
for (const key of ['height', 'width']) {
|
||||
element.style[key] = key === axe ? '100%' : 'auto';
|
||||
}
|
||||
}
|
||||
this._canvasRatio = this.size[0] / element.clientWidth;
|
||||
}
|
||||
|
||||
render() {
|
||||
this.renderer.render(this);
|
||||
}
|
||||
|
||||
translateEventPosition(event) {
|
||||
let position;
|
||||
if (event instanceof PointerEvent) {
|
||||
position = [event.clientX, event.clientY];
|
||||
}
|
||||
else if (event instanceof TouchEvent) {
|
||||
const touches = event.changedTouches;
|
||||
const touch = touches[0];
|
||||
position = [touch.clientX, touch.clientY];
|
||||
}
|
||||
return this.translateCanvasPosition(position);
|
||||
}
|
||||
|
||||
translateCanvasPosition(position) {
|
||||
const rect = this.renderer.element.getBoundingClientRect();
|
||||
const topLeft = [rect.x, rect.y];
|
||||
const offset = Vector.sub(position, topLeft);
|
||||
return Vector.div(
|
||||
Vector.scale(offset, this._canvasRatio),
|
||||
this.scale,
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class StageEvent {
|
||||
|
||||
get position() {
|
||||
return this._position;
|
||||
}
|
||||
|
||||
set position(position) {
|
||||
this._position = position;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user