♻️ switching to typescript
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
type PoolCanvas<T extends (OffscreenCanvas | HTMLCanvasElement)> = T & {
|
||||
export type PoolCanvas<T extends (OffscreenCanvas | HTMLCanvasElement)> = T & {
|
||||
acquire(): void
|
||||
release(): void
|
||||
}
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
export class Subject {
|
||||
type Listener<V> = ((val: V) => void);
|
||||
|
||||
export class Subject<V> {
|
||||
|
||||
__listeners: Listener<V>[]
|
||||
|
||||
constructor() {
|
||||
this.__listeners = [];
|
||||
}
|
||||
|
||||
next(val) {
|
||||
next(val:V) {
|
||||
for (let listener of this.__listeners) {
|
||||
listener(val);
|
||||
}
|
||||
}
|
||||
|
||||
once() {
|
||||
once():Promise<V> {
|
||||
return new Promise((resolve) => {
|
||||
const done = (val) => {
|
||||
resolve(val);
|
||||
@@ -20,11 +24,11 @@ export class Subject {
|
||||
})
|
||||
}
|
||||
|
||||
on(fn) {
|
||||
on(fn:Listener<V>) {
|
||||
this.__listeners.push(fn);
|
||||
}
|
||||
|
||||
off(fn) {
|
||||
off(fn:Listener<V>) {
|
||||
this.__listeners = this.__listeners.filter((listener) => listener !== fn);
|
||||
}
|
||||
|
||||
@@ -33,11 +37,12 @@ export class Subject {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
export class MultiSubject {
|
||||
__subjects: {
|
||||
[name: string]: Subject<any>
|
||||
}
|
||||
|
||||
constructor(types) {
|
||||
constructor(types: string[]) {
|
||||
this.__subjects = {};
|
||||
for (let type of types) {
|
||||
this.__subjects[type] = new Subject();
|
||||
@@ -5,13 +5,17 @@ import {
|
||||
Variables,
|
||||
ImageVar,
|
||||
BooleanVar,
|
||||
NumberVar
|
||||
NumberVar,
|
||||
VariableValueType
|
||||
} from '../io/AbstractIOSet';
|
||||
|
||||
const inputs = {
|
||||
image: {
|
||||
type: 'Image',
|
||||
} as ImageVar,
|
||||
width: {
|
||||
type: 'Number',
|
||||
} as NumberVar,
|
||||
};
|
||||
|
||||
const outputs = {
|
||||
@@ -29,11 +33,10 @@ const outputs = {
|
||||
|
||||
|
||||
export default class Canvas2d<I extends Variables, O extends Variables> extends Node<I & (typeof inputs), O & (typeof outputs)> {
|
||||
constructor(name, inputDefinition: I, outputDefiniton: O, options) {
|
||||
constructor(name, inputDefinition: I, outputDefiniton: O) {
|
||||
super(name,
|
||||
merge(inputs, inputDefinition),
|
||||
merge(outputs, outputDefiniton),
|
||||
options
|
||||
);
|
||||
}
|
||||
|
||||
@@ -42,7 +45,11 @@ export default class Canvas2d<I extends Variables, O extends Variables> extends
|
||||
}
|
||||
|
||||
async _update() {
|
||||
const values = {};
|
||||
type valuesType = {
|
||||
[K in keyof I]: VariableValueType<I[K]['type']>;
|
||||
}
|
||||
const values:valuesType = <valuesType>{};
|
||||
|
||||
for (let name of Object.keys(this.in.variables)) {
|
||||
values[name] = await waitForMedia(this.in[name].value);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import Canvas2d from './Canvas2d';
|
||||
import {PoolCanvas} from '../../canvas/CanvasPool';
|
||||
import {createCanvas, mediaSize, paintToCanvas} from '../canvas';
|
||||
import {
|
||||
ImageVar,
|
||||
@@ -89,7 +90,7 @@ const outputs = {
|
||||
export default class Compose extends Canvas2d<typeof inputs, typeof outputs> {
|
||||
|
||||
constructor(options={}) {
|
||||
super('Compose', inputs, outputs, options);
|
||||
super('Compose', inputs, outputs);
|
||||
}
|
||||
|
||||
get width() {
|
||||
@@ -149,13 +150,13 @@ export default class Compose extends Canvas2d<typeof inputs, typeof outputs> {
|
||||
ctx.globalCompositeOperation = 'source-over';
|
||||
|
||||
if (this.bg) {
|
||||
paintToCanvas(canvas, this.bg.image, this.bg);
|
||||
paintToCanvas(canvas, <PoolCanvas<any>>this.bg.image, this.bg);
|
||||
}
|
||||
|
||||
ctx.globalCompositeOperation = mode;
|
||||
|
||||
if (this.fg) {
|
||||
paintToCanvas(canvas, this.fg.image, this.fg);
|
||||
paintToCanvas(canvas, <PoolCanvas<any>>this.fg.image, this.fg);
|
||||
}
|
||||
|
||||
return canvas;
|
||||
|
||||
@@ -29,7 +29,7 @@ const outputs = {
|
||||
export default class EmptySpace extends Canvas2d<typeof inputs, typeof outputs> {
|
||||
|
||||
constructor() {
|
||||
super('EmptySpace', inputs, outputs, {});
|
||||
super('EmptySpace', inputs, outputs);
|
||||
this._update();
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ const outputs = {};
|
||||
export default class Flip extends Canvas2d<typeof inputs, typeof outputs> {
|
||||
|
||||
constructor() {
|
||||
super('Flip', inputs, outputs, {});
|
||||
super('Flip', inputs, outputs);
|
||||
this._update();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import Node from './Canvas2d';
|
||||
import {waitForMedia} from '../../utils';
|
||||
import {createCanvas, mediaSize, paintToCanvas} from '../canvas';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Canvas2d from './Canvas2d';
|
||||
import {waitForMedia} from '../../utils';
|
||||
import {createCanvas, mediaSize, paintToCanvas} from '../canvas';
|
||||
import {createCanvas, mediaSize, paintToCanvas, Bounds} from '../canvas';
|
||||
import {
|
||||
ImageVar,
|
||||
StringVar,
|
||||
@@ -27,7 +27,7 @@ const outputs = {};
|
||||
export default class Resize extends Canvas2d<typeof inputs, typeof outputs> {
|
||||
|
||||
constructor() {
|
||||
super('Resize', inputs, outputs, {});
|
||||
super('Resize', inputs, outputs);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,7 +52,7 @@ export default class Resize extends Canvas2d<typeof inputs, typeof outputs> {
|
||||
const {width: destWidth, height: destHeight} = mediaSize(canvas);
|
||||
const srcAspectRatio = (srcWidth / srcHeight);
|
||||
const destAspectRatio = (destWidth / destHeight);
|
||||
const newImage = {};
|
||||
const newImage:Partial<Bounds> = {};
|
||||
if (srcAspectRatio > destAspectRatio) {
|
||||
newImage.width = destHeight * srcAspectRatio;
|
||||
newImage.height = destHeight;
|
||||
@@ -64,7 +64,7 @@ export default class Resize extends Canvas2d<typeof inputs, typeof outputs> {
|
||||
newImage.top = (destHeight - newImage.height) / 2;
|
||||
newImage.left = (destWidth - newImage.width) / 2;
|
||||
|
||||
paintToCanvas(canvas, media, newImage);
|
||||
paintToCanvas(canvas, media, <Bounds>newImage);
|
||||
return canvas;
|
||||
}
|
||||
}
|
||||
@@ -65,7 +65,7 @@ const outputs = {};
|
||||
export default class Resize extends Canvas2d<typeof inputs, typeof outputs> {
|
||||
|
||||
constructor() {
|
||||
super('Text', inputs, outputs, {});
|
||||
super('Text', inputs, outputs);
|
||||
this._update();
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ const outputs = {
|
||||
|
||||
export default class Disable extends Node<typeof inputs, typeof outputs> {
|
||||
constructor() {
|
||||
super('Disable', inputs, outputs, {});
|
||||
super('Disable', inputs, outputs);
|
||||
}
|
||||
|
||||
async _update() {
|
||||
|
||||
@@ -36,7 +36,7 @@ const outputs = {
|
||||
|
||||
export default class Font extends Node<typeof inputs, typeof outputs> {
|
||||
constructor() {
|
||||
super('Font', inputs, outputs, {});
|
||||
super('Font', inputs, outputs);
|
||||
}
|
||||
|
||||
async _update() {
|
||||
|
||||
@@ -36,7 +36,7 @@ const outputs = {
|
||||
|
||||
export default class NumberBinaryOperation extends Node<typeof inputs, typeof outputs> {
|
||||
constructor() {
|
||||
super('NumberBinaryOperation', inputs, outputs, {});
|
||||
super('NumberBinaryOperation', inputs, outputs);
|
||||
}
|
||||
|
||||
async _update() {
|
||||
|
||||
@@ -37,7 +37,7 @@ const outputs = {
|
||||
|
||||
export default class Numbers extends Node<typeof inputs, typeof outputs> {
|
||||
constructor() {
|
||||
super('Numbers', inputs, outputs, {});
|
||||
super('Numbers', inputs, outputs);
|
||||
}
|
||||
|
||||
async _update() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {Inputs, Outputs} from './io/index';
|
||||
import uuidv4 from 'uuid/v4';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import {Variables, InputProperties, OutputProperties} from './io/AbstractIOSet';
|
||||
import {MultiSubject} from '../helpers/listener';
|
||||
|
||||
@@ -16,10 +16,10 @@ export default class Node<I extends Variables, O extends Variables> {
|
||||
_stopped: boolean
|
||||
subject: MultiSubject
|
||||
|
||||
constructor(name: string, inputDefinition: I, outputDefiniton: O, options) {
|
||||
constructor(name: string, inputDefinition: I, outputDefiniton: O) {
|
||||
this.name = name;
|
||||
this.uid = uuidv4();
|
||||
this.id = uuidv4();
|
||||
this.uid = uuid();
|
||||
this.id = uuid();
|
||||
this.__in = new Inputs(inputDefinition, this) as Inputs<I> & InputProperties<I>;
|
||||
this.__out = new Outputs(outputDefiniton, this) as Outputs<O> & OutputProperties<O>;
|
||||
this.__in.update = (name) => this.__update([name]);
|
||||
@@ -95,7 +95,7 @@ export default class Node<I extends Variables, O extends Variables> {
|
||||
}
|
||||
|
||||
async deserialize({id, options}) {
|
||||
this.id = id || uuidv4();
|
||||
this.id = id || uuid();
|
||||
}
|
||||
|
||||
async reconnect({options}, outputs) {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import Node from './Node';
|
||||
|
||||
export default class Numbers extends Node {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import Node from './Node';
|
||||
import {createCanvas} from './canvas';
|
||||
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import WebGL from './WebGl';
|
||||
import {
|
||||
NumberVar
|
||||
} from '../io/AbstractIOSet';
|
||||
|
||||
const inputs = {
|
||||
amount: {
|
||||
type: 'Number',
|
||||
default: 0,
|
||||
} as NumberVar,
|
||||
}
|
||||
|
||||
export default class Sepia extends WebGL {
|
||||
export default class Sepia extends WebGL<typeof inputs> {
|
||||
|
||||
constructor() {
|
||||
super('Tint', {
|
||||
amount: {
|
||||
type: 'Number',
|
||||
default: 0,
|
||||
},
|
||||
amount: {
|
||||
type: 'Color',
|
||||
default: '',
|
||||
},
|
||||
})
|
||||
super('Tint', inputs)
|
||||
}
|
||||
|
||||
get frag() {
|
||||
@@ -1,7 +1,7 @@
|
||||
import Node from '../Node';
|
||||
import {createCanvas, mediaSize, paintToCanvas} from '../canvas';
|
||||
import {merge} from '../../utils';
|
||||
import {canvasPool2D} from '../../canvas/CanvasPool';
|
||||
import {canvasPool2D, PoolCanvas} from '../../canvas/CanvasPool';
|
||||
import {
|
||||
Variables,
|
||||
ImageVar,
|
||||
@@ -36,7 +36,6 @@ export default class WebGL<I extends Variables> extends Node<I & (typeof inputs)
|
||||
name,
|
||||
merge(inputs, inputDefinition),
|
||||
outputs,
|
||||
{}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -166,7 +165,11 @@ export default class WebGL<I extends Variables> extends Node<I & (typeof inputs)
|
||||
|
||||
_passes() {
|
||||
return [
|
||||
(gl: WebGLRenderingContext, program: WebGLProgram, image) => {
|
||||
(
|
||||
gl: WebGLRenderingContext,
|
||||
program: WebGLProgram,
|
||||
// image
|
||||
) => {
|
||||
this._setParams(gl, program);
|
||||
},
|
||||
]
|
||||
@@ -190,7 +193,7 @@ export default class WebGL<I extends Variables> extends Node<I & (typeof inputs)
|
||||
|
||||
async _update() {
|
||||
|
||||
const image = this.in.image.value;
|
||||
const image = <PoolCanvas<any>>this.in.image.value;
|
||||
if (!image) {
|
||||
return;
|
||||
}
|
||||
@@ -230,7 +233,7 @@ export default class WebGL<I extends Variables> extends Node<I & (typeof inputs)
|
||||
|
||||
if (this.image) {
|
||||
// Upload the image into the texture.
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, await createImageBitmap(this.image));
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, await createImageBitmap(<PoolCanvas<any>>this.image));
|
||||
}
|
||||
|
||||
const texcoordBuffer = gl.createBuffer();
|
||||
@@ -309,8 +312,8 @@ export default class WebGL<I extends Variables> extends Node<I & (typeof inputs)
|
||||
if (image.release) {
|
||||
image.release();
|
||||
}
|
||||
if (this.out.image.value && this.out.image.value.release) {
|
||||
this.out.image.value.release();
|
||||
if (this.out.image.value && (<PoolCanvas<any>>this.out.image.value).release) {
|
||||
(<PoolCanvas<any>>this.out.image.value).release();
|
||||
}
|
||||
this.out.image.value = resultCanvas;
|
||||
if (this.out.width.value !== this.out.image.value.width) {
|
||||
|
||||
@@ -32,6 +32,7 @@ export default class Webcam extends Node {
|
||||
/** @type {HTMLVideoElement} */
|
||||
|
||||
const video = document.createElement('video');
|
||||
// @ts-ignore
|
||||
video.playsinline = true;
|
||||
video.srcObject = stream;
|
||||
video.play();
|
||||
|
||||
@@ -8,7 +8,7 @@ import {serialize, deserialize} from './serializer';
|
||||
|
||||
export default class Input<V extends Variable> extends AbstractIO<V> {
|
||||
|
||||
__output: Output<any>
|
||||
__output: Output<V>
|
||||
__onchangelistener: Function
|
||||
|
||||
constructor(name, definition, owner) {
|
||||
@@ -35,7 +35,7 @@ export default class Input<V extends Variable> extends AbstractIO<V> {
|
||||
return this.__output;
|
||||
}
|
||||
|
||||
connect(output: Output<any>) {
|
||||
connect(output: Output<V>) {
|
||||
if (output && output.type === this.type) {
|
||||
this.disconnect();
|
||||
this.__output = output
|
||||
|
||||
@@ -24,6 +24,7 @@ describe('Inputs', () => {
|
||||
type: 'String',
|
||||
default: 'foo'
|
||||
},
|
||||
// @ts-ignore
|
||||
}, owner)
|
||||
|
||||
expect(inputs.x.type).toBe('Number');
|
||||
@@ -21,6 +21,7 @@ describe('Outputs', () => {
|
||||
type: 'String',
|
||||
default: 'foo'
|
||||
},
|
||||
// @ts-ignore
|
||||
}, owner)
|
||||
|
||||
expect(inputs.x.type).toBe('Number');
|
||||
Reference in New Issue
Block a user