♻️ better types system
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
:selectedOutput="selectedOutput"
|
||||
@outputSelected="selectedOutput = $event"
|
||||
@inputSelected="selectedInput = $event"
|
||||
@removeNode="removeNode"
|
||||
/>
|
||||
</Draggable>
|
||||
<ContextMenu
|
||||
@@ -140,6 +141,11 @@ export default {
|
||||
node: new node(),
|
||||
});
|
||||
this.contextMenuPosition = null;
|
||||
},
|
||||
removeNode(nodeToRemove) {
|
||||
const index = this.graph.findIndex(({node}) => node === nodeToRemove);
|
||||
console.log('nodeIndex', index);
|
||||
this.graph.splice(index, 1);
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
@@ -21,8 +21,9 @@
|
||||
>×</span>
|
||||
</div>
|
||||
<Value
|
||||
:type="type"
|
||||
:value="node.in[name]"
|
||||
:io="node.in[name]"
|
||||
direction="input"
|
||||
@change="(value) => node.in[name].value = value"
|
||||
class="node-var__value"
|
||||
/>
|
||||
</div>
|
||||
@@ -43,12 +44,18 @@
|
||||
@click="$emit('outputSelected', node.out[name])"
|
||||
>{{ name }} <!--<i>{{typeName(type)}}</i>--></div>
|
||||
<Value
|
||||
:type="type"
|
||||
:value="node.out[name]"
|
||||
:io="node.out[name]"
|
||||
direction="output"
|
||||
class="node-var__value"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="node__remove"
|
||||
@click="removeNode"
|
||||
>
|
||||
×
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
@@ -95,6 +102,9 @@ export default {
|
||||
}
|
||||
return ins;
|
||||
},
|
||||
removeNode() {
|
||||
this.$emit('removeNode', this.node);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -144,4 +154,18 @@ export default {
|
||||
.node__var {
|
||||
margin-bottom: 2px
|
||||
}
|
||||
|
||||
.node__remove {
|
||||
position: absolute;
|
||||
top: -20px;
|
||||
right: -20px;
|
||||
background-color: red;
|
||||
color: white;
|
||||
border-radius: 50%;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div
|
||||
class="image-value"
|
||||
@click="download"
|
||||
@click="onClick"
|
||||
>
|
||||
<canvas class="image-value__thumb" ref="thumb" />
|
||||
<canvas class="image-value__preview" ref="preview" />
|
||||
@@ -14,9 +14,17 @@ import {paintToCanvas, mediaSize} from '../../../src/nodes/canvas.js'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
io: {
|
||||
type: null,
|
||||
required: true,
|
||||
},
|
||||
value: {
|
||||
type: null,
|
||||
required: true,
|
||||
},
|
||||
direction: {
|
||||
type: String,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -34,7 +42,7 @@ export default {
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.redraw();
|
||||
this.value.onchange(this.redraw);
|
||||
this.io.onchange(this.redraw);
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
@@ -44,9 +52,12 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.isRunning = false;
|
||||
},
|
||||
methods: {
|
||||
redrawCanvas(canvas) {
|
||||
const value = this.value.value;
|
||||
const value = this.value;
|
||||
/** @type {HTMLCanvasElement} */
|
||||
const ctx = canvas.getContext('2d');
|
||||
if (!value) {
|
||||
@@ -70,6 +81,35 @@ export default {
|
||||
this.redrawCanvas(this.$refs.preview)
|
||||
}
|
||||
},
|
||||
onClick() {
|
||||
if (this.direction === 'output') {
|
||||
this.download();
|
||||
} else {
|
||||
this.selectFile();
|
||||
}
|
||||
},
|
||||
selectFile() {
|
||||
const input = document.createElement('input');
|
||||
window.$$input = input;
|
||||
input.type = 'file';
|
||||
input.accept = 'image/*';
|
||||
input.onchange = (event) => {
|
||||
const files = event.target.files;
|
||||
console.log(event);
|
||||
if (files.length) {
|
||||
const fr = new FileReader()
|
||||
fr.onload = (event) => {
|
||||
const image = new Image();
|
||||
image.onload = () => {
|
||||
this.$emit('change', image);
|
||||
}
|
||||
image.src = event.target.result;
|
||||
}
|
||||
fr.readAsDataURL(files[0]);
|
||||
}
|
||||
}
|
||||
input.click();
|
||||
},
|
||||
download() {
|
||||
const a = document.createElement('a');
|
||||
a.href = this.$refs.preview.toDataURL();
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<select v-model="value.value">
|
||||
<select v-model="io.value">
|
||||
<option
|
||||
v-for="t in type"
|
||||
:value="t"
|
||||
:key="t"
|
||||
>{{ t }}</option>
|
||||
v-for="value in io.definition.enum"
|
||||
:value="value"
|
||||
:key="value"
|
||||
>{{ value }}</option>
|
||||
</select>
|
||||
</template>
|
||||
<script>
|
||||
@@ -14,7 +14,7 @@ export default {
|
||||
type: null,
|
||||
required: true,
|
||||
},
|
||||
value: {
|
||||
io: {
|
||||
type: null,
|
||||
required: true,
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<input
|
||||
v-model="value.value"
|
||||
v-model="value"
|
||||
:type="
|
||||
type === 'Number' ? 'number' :
|
||||
type === 'Color' ? 'color' :
|
||||
@@ -11,7 +11,7 @@
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
io: {
|
||||
type: null,
|
||||
required: true,
|
||||
},
|
||||
@@ -19,6 +19,26 @@ export default {
|
||||
type: String,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
value: {
|
||||
get() {
|
||||
return this.io.value;
|
||||
},
|
||||
set(val) {
|
||||
if (this.type === 'Number') {
|
||||
this.io.value = parseFloat(val)
|
||||
} else {
|
||||
this.io.value = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onChange($event) {
|
||||
console.log('change', $event);
|
||||
this.value = $event.target.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -4,22 +4,34 @@ import SelectValue from './Select.vue';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
type: {
|
||||
io: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
direction: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
value: {
|
||||
type: null,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
render(h) {
|
||||
return h(
|
||||
this.type === 'Image' ? ImageValue :
|
||||
this.type === 'Number' ? StringValue :
|
||||
this.type === 'Color' ? StringValue :
|
||||
Array.isArray(this.type) ? SelectValue :
|
||||
this.io.type === 'Image' ? ImageValue :
|
||||
this.io.type === 'Number' ? StringValue :
|
||||
this.io.type === 'Color' ? StringValue :
|
||||
this.io.definition.enum ? SelectValue :
|
||||
null,
|
||||
{props: {value: this.value, type: this.type}})
|
||||
{
|
||||
props: {
|
||||
io: this.io,
|
||||
value: this.io.value,
|
||||
type: this.io.type,
|
||||
direction: this.direction
|
||||
},
|
||||
on: {
|
||||
change: (value) => {
|
||||
this.$emit('change', value);
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user