feat: graphics stage

This commit is contained in:
cha0s 2019-03-30 05:08:33 -05:00
parent 9af970d641
commit 8b8216fe8f
2 changed files with 145 additions and 0 deletions

View File

@ -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
View 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;
}
}