Use reactive GUI resizing
This commit is contained in:
parent
b159b58973
commit
bf696695ee
7 changed files with 97 additions and 36 deletions
|
@ -61,14 +61,6 @@ async function loop(fn) {
|
||||||
then = Date.now();
|
then = Date.now();
|
||||||
|
|
||||||
await new Promise(resolve => requestAnimationFrame(resolve));
|
await new Promise(resolve => requestAnimationFrame(resolve));
|
||||||
// await new Promise(resolve => requestAnimationFrame(resolve));
|
|
||||||
// await new Promise(resolve => requestAnimationFrame(resolve));
|
|
||||||
// await new Promise(resolve => requestAnimationFrame(resolve));
|
|
||||||
// await new Promise(resolve => requestAnimationFrame(resolve));
|
|
||||||
// await new Promise(resolve => requestAnimationFrame(resolve));
|
|
||||||
// await new Promise(resolve => requestAnimationFrame(resolve));
|
|
||||||
// await new Promise(resolve => requestAnimationFrame(resolve));
|
|
||||||
// await new Promise(resolve => requestAnimationFrame(resolve));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
import * as gui from './gui';
|
import * as gui from './gui';
|
||||||
import * as draw from './draw';
|
import * as draw from './draw';
|
||||||
import * as input from '../input';
|
import * as input from '../input';
|
||||||
import {render as renderWorld} from './world';
|
import { render as renderWorld } from './world';
|
||||||
import {render as renderBackground} from './background';
|
import { render as renderBackground } from './background';
|
||||||
import * as world from '../world/index';
|
import * as world from '../world/index';
|
||||||
import * as consts from '../consts';
|
import * as consts from '../consts';
|
||||||
|
|
||||||
const TAU = consts.TAU;
|
const TAU = consts.TAU;
|
||||||
|
|
||||||
export let canvas, context, tempCanvas, tempContext;
|
export let canvas: HTMLCanvasElement;
|
||||||
|
export let tempCanvas: HTMLCanvasElement;
|
||||||
|
export let context: CanvasRenderingContext2D;
|
||||||
|
export let tempContext: CanvasRenderingContext2D;
|
||||||
export let perspective: Perspective;
|
export let perspective: Perspective;
|
||||||
export let trace = true;
|
export let trace = true;
|
||||||
export let markers = true;
|
export let markers = true;
|
||||||
|
@ -19,11 +22,17 @@ export function init() {
|
||||||
tempCanvas = document.querySelector('#temp');
|
tempCanvas = document.querySelector('#temp');
|
||||||
tempContext = tempCanvas.getContext('2d');
|
tempContext = tempCanvas.getContext('2d');
|
||||||
|
|
||||||
canvas.width = window.innerWidth;
|
function resizeCanvas() {
|
||||||
canvas.height = window.innerHeight;
|
canvas.width = window.innerWidth;
|
||||||
|
canvas.height = window.innerHeight;
|
||||||
|
|
||||||
canvas.style.width = canvas.width + 'px';
|
canvas.style.width = window.innerWidth + 'px';
|
||||||
canvas.style.height = canvas.height + 'px';
|
canvas.style.height = window.innerHeight + 'px';
|
||||||
|
}
|
||||||
|
|
||||||
|
resizeCanvas();
|
||||||
|
|
||||||
|
window.addEventListener('resize', resizeCanvas);
|
||||||
|
|
||||||
perspective = new Perspective();
|
perspective = new Perspective();
|
||||||
|
|
||||||
|
@ -147,7 +156,7 @@ class Perspective {
|
||||||
get currentShift() {
|
get currentShift() {
|
||||||
let [ox, oy] = this.oldShift;
|
let [ox, oy] = this.oldShift;
|
||||||
return [this.interpolate(this.shiftX, ox),
|
return [this.interpolate(this.shiftX, ox),
|
||||||
this.interpolate(this.shiftY, oy)];
|
this.interpolate(this.shiftY, oy)];
|
||||||
}
|
}
|
||||||
|
|
||||||
get currentRotation() {
|
get currentRotation() {
|
||||||
|
@ -172,6 +181,8 @@ class Perspective {
|
||||||
}
|
}
|
||||||
|
|
||||||
tick(delta: number) {
|
tick(delta: number) {
|
||||||
|
this.bounds = [0, 0, canvas.width, canvas.height];
|
||||||
|
|
||||||
if (this.focus !== null)
|
if (this.focus !== null)
|
||||||
[this.x, this.y] = this.focus.com;
|
[this.x, this.y] = this.focus.com;
|
||||||
|
|
||||||
|
@ -219,7 +230,7 @@ class Perspective {
|
||||||
}
|
}
|
||||||
|
|
||||||
transformRotate() {
|
transformRotate() {
|
||||||
let [,,bw, bh] = this.bounds;
|
let [, , bw, bh] = this.bounds;
|
||||||
context.translate(bw / 2, bh / 2);
|
context.translate(bw / 2, bh / 2);
|
||||||
context.rotate(-this.rotation);
|
context.rotate(-this.rotation);
|
||||||
context.translate(-bw / 2, -bh / 2);
|
context.translate(-bw / 2, -bh / 2);
|
||||||
|
@ -227,11 +238,11 @@ class Perspective {
|
||||||
|
|
||||||
rotateVector(x, y, r = this.rotation) {
|
rotateVector(x, y, r = this.rotation) {
|
||||||
return [(x * Math.cos(r) - y * Math.sin(r)),
|
return [(x * Math.cos(r) - y * Math.sin(r)),
|
||||||
(y * Math.cos(r) - x * Math.sin(r))];
|
(y * Math.cos(r) - x * Math.sin(r))];
|
||||||
}
|
}
|
||||||
|
|
||||||
transformCanvas() {
|
transformCanvas() {
|
||||||
let [,,bw, bh] = this.bounds;
|
let [, , bw, bh] = this.bounds;
|
||||||
let [sx, sy] = this.rotateVector(...this.currentShift, this.rotation);
|
let [sx, sy] = this.rotateVector(...this.currentShift, this.rotation);
|
||||||
let tx = -(this.x + sx) * this.zoom;
|
let tx = -(this.x + sx) * this.zoom;
|
||||||
let ty = -(this.y + sy) * this.zoom;
|
let ty = -(this.y + sy) * this.zoom;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {Rect} from './misc';
|
import { Rect } from './misc';
|
||||||
|
|
||||||
const defaultOptions = {
|
const defaultOptions = {
|
||||||
draw: true, // Whether the element itself will be rendered.
|
draw: true, // Whether the element itself will be rendered.
|
||||||
|
@ -6,14 +6,17 @@ const defaultOptions = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class GuiElement extends Rect {
|
export default class GuiElement extends Rect {
|
||||||
constructor(x, y, w, h, options = {}) {
|
children: Set<GuiElement>;
|
||||||
super(x, y, w, h);
|
parent: GuiElement;
|
||||||
|
|
||||||
|
constructor(x, y, width, height, options = {}) {
|
||||||
|
super(x, y, width, height);
|
||||||
this.children = new Set();
|
this.children = new Set();
|
||||||
this.parent = null;
|
this.parent = null;
|
||||||
|
|
||||||
this.type = 'element';
|
this.type = 'element';
|
||||||
|
|
||||||
this.options = Object.assign({}, defaultOptions, options);
|
this.options = { ...defaultOptions, ...options };
|
||||||
}
|
}
|
||||||
|
|
||||||
tickElement() {
|
tickElement() {
|
||||||
|
@ -45,14 +48,14 @@ export default class GuiElement extends Rect {
|
||||||
// Code should be self-describing, comments are for fucking about.
|
// Code should be self-describing, comments are for fucking about.
|
||||||
// - Albert Einstein
|
// - Albert Einstein
|
||||||
|
|
||||||
posRelative({x = null, xc = 0, y = null, yc = 0, w = null, h = null}) {
|
posRelative({ x = null, xc = 0, y = null, yc = 0, w = null, h = null }) {
|
||||||
if (x !== null)
|
if (x !== null)
|
||||||
this.x = (this.parent.w * x) - (this.w * xc) + this.parent.x;
|
this.sourceX = () => (this.parent.w * x) - (this.w * xc) + this.parent.x;
|
||||||
if (y !== null)
|
if (y !== null)
|
||||||
this.y = (this.parent.h * y) - (this.h * yc) + this.parent.y;
|
this.sourceY = () => (this.parent.h * y) - (this.h * yc) + this.parent.y;
|
||||||
if (w !== null)
|
if (w !== null)
|
||||||
this.w = this.parent.w * w;
|
this.sourceWidth = () => this.parent.w * w;
|
||||||
if (h !== null)
|
if (h !== null)
|
||||||
this.h = this.parent.h * h;
|
this.sourceHeight = () => this.parent.h * h;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@ import * as gui from './index';
|
||||||
import GuiElement from './element';
|
import GuiElement from './element';
|
||||||
|
|
||||||
export default class GuiFrame extends GuiElement {
|
export default class GuiFrame extends GuiElement {
|
||||||
constructor(x, y, w, h, options) {
|
constructor(x, y, width, height, options) {
|
||||||
super(x, y, w, h, options);
|
super(x, y, width, height, options);
|
||||||
this.type = 'frame';
|
this.type = 'frame';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import {context} from '../graphics/index';
|
import {context} from '../graphics/index';
|
||||||
|
import GuiElement from './element';
|
||||||
import * as modules from './modules';
|
import * as modules from './modules';
|
||||||
|
|
||||||
export const elements = new Set();
|
export const elements = new Set();
|
||||||
export let root;
|
export let root: GuiElement;
|
||||||
|
|
||||||
export function init() {
|
export function init() {
|
||||||
elements.clear();
|
elements.clear();
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
import * as input from '../input';
|
import * as input from '../input';
|
||||||
|
|
||||||
export class Rect {
|
export class Rect {
|
||||||
constructor(x = 0, y = 0, w = 0, h = 0) {
|
sourceWidth: number | (() => number);
|
||||||
|
sourceHeight: number | (() => number);
|
||||||
|
sourceX: number | (() => number);
|
||||||
|
sourceY: number | (() => number);
|
||||||
|
|
||||||
|
constructor(x = 0, y = 0, width = 0, height = 0) {
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
this.w = w;
|
this.sourceWidth = width;
|
||||||
this.h = h;
|
this.sourceHeight = height;
|
||||||
|
|
||||||
this.onclick = null;
|
this.onclick = null;
|
||||||
this.mouseHeld = false;
|
this.mouseHeld = false;
|
||||||
|
@ -55,6 +60,54 @@ export class Rect {
|
||||||
return this.mouseOver() && input.mouse.pressed[0];
|
return this.mouseOver() && input.mouse.pressed[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get w() {
|
||||||
|
if (typeof this.sourceWidth == 'function') {
|
||||||
|
return this.sourceWidth();
|
||||||
|
} else {
|
||||||
|
return this.sourceWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get h() {
|
||||||
|
if (typeof this.sourceHeight == 'function') {
|
||||||
|
return this.sourceHeight();
|
||||||
|
} else {
|
||||||
|
return this.sourceHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set w(w) {
|
||||||
|
this.sourceWidth = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
set h(h) {
|
||||||
|
this.sourceHeight = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
get x() {
|
||||||
|
if (typeof this.sourceX == 'function') {
|
||||||
|
return this.sourceX();
|
||||||
|
} else {
|
||||||
|
return this.sourceX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get y() {
|
||||||
|
if (typeof this.sourceY == 'function') {
|
||||||
|
return this.sourceY();
|
||||||
|
} else {
|
||||||
|
return this.sourceY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set x(x) {
|
||||||
|
this.sourceX = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
set y(y) {
|
||||||
|
this.sourceY = y;
|
||||||
|
}
|
||||||
|
|
||||||
containsPoint(x, y) {
|
containsPoint(x, y) {
|
||||||
return x > this.x && x < this.x + this.w
|
return x > this.x && x < this.x + this.w
|
||||||
&& y > this.y && y < this.y + this.h;
|
&& y > this.y && y < this.y + this.h;
|
||||||
|
|
|
@ -14,8 +14,9 @@ import {state} from '../game/index';
|
||||||
import * as world from '../world/index';
|
import * as world from '../world/index';
|
||||||
|
|
||||||
export function root() {
|
export function root() {
|
||||||
return new GuiFrame(0, 0, canvas.width, canvas.height, {
|
return new GuiFrame(0, 0, () => canvas.width, () => canvas.height, {
|
||||||
draw: false
|
draw: false,
|
||||||
|
name: 'root',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue