diff --git a/src/components/input/SpectralPowerDistributionEntry.vue b/src/components/input/SpectralPowerDistributionEntry.vue index 9006895..2a951b3 100644 --- a/src/components/input/SpectralPowerDistributionEntry.vue +++ b/src/components/input/SpectralPowerDistributionEntry.vue @@ -7,6 +7,7 @@ import {settings} from '../store'; import {models} from "@/models/nodetypes"; import {Listen, clearTextSelection, lerp, clamp} from "@/util"; import * as cm from "@/models/colormanagement"; +import getString from "@/strings"; const props = defineProps({ node: { @@ -168,7 +169,7 @@ const beginInput = (downEvent: PointerEvent) => {
360
-
Wavelength (nm)
+
830
@@ -191,11 +192,17 @@ const beginInput = (downEvent: PointerEvent) => {
- +
@@ -257,10 +264,12 @@ const beginInput = (downEvent: PointerEvent) => { > .control-row { display: flex; justify-content: space-between; + align-items: center; > div { display: flex; flex-flow: row; + align-items: center; gap: 0.25em; } } diff --git a/src/components/node/NodeSocket.vue b/src/components/node/NodeSocket.vue index 2853926..df5e79c 100644 --- a/src/components/node/NodeSocket.vue +++ b/src/components/node/NodeSocket.vue @@ -117,6 +117,7 @@ const showTooltip = () => { const rect = socketContainer.value!.getBoundingClientRect(); const socketTypeName = socketTypeNames.get(props.socket.type); + const inOut = props.socket.isInput ? "in" : "out"; let tooltipString = `${getString(props.socket.socketDesc ?? NO_DESC)}`; @@ -124,7 +125,14 @@ const showTooltip = () => { tooltipString += `

${getString("general.socketDataTypeLabel")}${getString(`label.socketType.${socketTypeName}`)}
-${getString(`desc.socketType.${socketTypeName}.${props.socket.isInput ? "in" : "out"}`)}`; +${getString(`desc.socketType.${socketTypeName}.${inOut}`)}`; + } + + if (props.socket.constant) { + tooltipString += `
+
+${getString("label.socketAttr.constant")}
+${getString(`desc.socketAttr.constant.${inOut}`)}`; } if (props.socket.showSocket && props.socket.hasLinks) { @@ -189,9 +197,10 @@ Object.defineProperties(socketVue, { }" :style="{'--socket-color': socketColor} as any"> -
- {{socket.label}} -
+
; diff --git a/src/models/Node.ts b/src/models/Node.ts index b9e581b..c46c47e 100644 --- a/src/models/Node.ts +++ b/src/models/Node.ts @@ -432,7 +432,7 @@ type SocketData = St extends SocketType.Dropdown ? { options?: { value: string, - text: string, + text: StringKey, }[], } : St extends SocketType.Float ? { @@ -536,7 +536,7 @@ export abstract class Socket { readonly isInput: boolean, public type: St, - public label: string="", + public label: StringKey=NO_DESC, /** Object that specifies SocketType-independent options for this socket as well as SocketType-specific properties/data */ options=>{}, @@ -647,7 +647,7 @@ export class InSocket extends Socket { node: Node, type: St, - public label: string="", + label: StringKey, options=>{}, ) { @@ -795,7 +795,7 @@ export class OutSocket extends Socket { node: Node, type: St, - public label: string="", + label: StringKey, readonly outValue: (context: NodeEvalContext) => SocketValue, @@ -854,7 +854,7 @@ export class Field { value = 0; constructor( - public label: string="", + public label: StringKey=NO_DESC, ) {} } diff --git a/src/models/Overload.ts b/src/models/Overload.ts index 1cb3798..5f98aaa 100644 --- a/src/models/Overload.ts +++ b/src/models/Overload.ts @@ -1,10 +1,11 @@ import { WebglOutputs, WebglVariables } from "@/webgl-compute/WebglVariables"; import { InSocket, Node, NodeDisplay, NodeEvalContext, OutSocket, SocketType, SocketType as St, Tree } from "./Node"; +import { NO_DESC, StringKey } from "@/strings"; /** A collection of input/output sockets, as well as a function to compute outputs from the inputs' values */ export class Overload { constructor( - readonly label: string, + readonly label: StringKey, readonly buildInSockets: (node: NodeType) => [...InSockets], readonly buildOutSockets: (node: NodeType, ins: InSockets) => [...OutSockets], readonly nodeDisplay: (ins: InSockets, outs: OutSockets, context: NodeEvalContext, node: NodeType) => NodeDisplay=() => { throw new Error("not implemented") }, @@ -21,7 +22,7 @@ export class OverloadGroup { ) {} buildDropdown(node: NodeType, defaultMode: Mode, overloadManager: OverloadManager) { - return new InSocket(node, SocketType.Dropdown, "", { + return new InSocket(node, SocketType.Dropdown, NO_DESC, { showSocket: false, options: [...this.modes].map(([mode, overload]) => ( {value: mode, text: overload.label} diff --git a/src/models/nodetypes/externals.ts b/src/models/nodetypes/externals.ts index 9bb0f26..956279c 100644 --- a/src/models/nodetypes/externals.ts +++ b/src/models/nodetypes/externals.ts @@ -1,4 +1,4 @@ -import {Tree, Node, Socket, SocketType as St, Link, NodeEvalContext, OutputDisplayType, SocketFlag, InSocket, OutSocket} from "../Node"; +import {Tree, Node, Socket, SocketType, Link, NodeEvalContext, OutputDisplayType, SocketFlag, InSocket, OutSocket} from "../Node"; import * as cm from "../colormanagement"; export namespace externals { @@ -6,26 +6,26 @@ export namespace externals { static readonly TYPE = Symbol(this.name); static readonly LABEL = "Display buffer"; - readonly colorSockets: Socket[]; + readonly colorSockets: Socket[]; constructor() { super(); this.ins.push( ...(this.colorSockets = [ - new InSocket(this, Socket.Type.VectorOrColor, "Color"), + new InSocket(this, SocketType.VectorOrColor, "Color"), ]), ); this.outs.push( - new OutSocket(this, Socket.Type.Unknown, "Color data", context => {}), + new OutSocket(this, SocketType.Unknown, "Color data", context => {}), ); this.canMove = false; } output(context: NodeEvalContext): cm.Srgb { - const color = (context.socket! as Socket).inValue(context); + const color = (context.socket! as Socket).inValue(context); return color && cm.Srgb.from(color); // return this.colorSockets.filter(socket => socket.hasLinks) @@ -43,7 +43,7 @@ export namespace externals { if (!socket.isInput) return; - const newSocket = new InSocket(this, Socket.Type.VectorOrColor, "Color"); + const newSocket = new InSocket(this, SocketType.VectorOrColor, "Color"); this.ins.push(newSocket); this.colorSockets.push(newSocket); @@ -67,11 +67,11 @@ export namespace externals { super(); this.ins.push( - new InSocket(this, Socket.Type.Unknown, "Color data"), + new InSocket(this, SocketType.Unknown, "Color data"), ); this.outs.push( - new OutSocket(this, Socket.Type.Unknown, "Screen image", context => {}), + new OutSocket(this, SocketType.Unknown, "Screen image", context => {}), ); this.canMove = false; @@ -87,11 +87,11 @@ export namespace externals { super(); this.ins.push( - new InSocket(this, Socket.Type.Unknown, "Radiation"), + new InSocket(this, SocketType.Unknown, "Radiation"), ); this.outs.push( - new OutSocket(this, Socket.Type.Unknown, "Radiation"), + new OutSocket(this, SocketType.Unknown, "Radiation"), ); this.canMove = false; @@ -107,7 +107,7 @@ export namespace externals { super(); this.ins.push( - new InSocket(this, Socket.Type.Unknown, "Light"), + new InSocket(this, SocketType.Unknown, "Light"), ); this.canMove = false; diff --git a/src/models/nodetypes/images.ts b/src/models/nodetypes/images.ts index 1170210..080a77f 100644 --- a/src/models/nodetypes/images.ts +++ b/src/models/nodetypes/images.ts @@ -26,23 +26,23 @@ export namespace images { const {val} = GradientNode.outputSlots; this.ins.push( - (this.axisSocket = new InSocket(this, SocketType.Dropdown, "Axis", { + (this.axisSocket = new InSocket(this, SocketType.Dropdown, "label.socket.gradient.axis", { showSocket: false, options: [ - {text: "X", value: "0"}, - {text: "Y", value: "1"}, + {text: "label.socket.x", value: "0"}, + {text: "label.socket.y", value: "1"}, ], defaultValue: "0", valueChangeRequiresShaderReload: true, })), ...(this.boundsSockets = [ - new InSocket(this, SocketType.Float, "From", { + new InSocket(this, SocketType.Float, "label.socket.gradient.from", { sliderProps: { hasBounds: false, }, webglOutputMapping: {[webglOuts.val]: from}, }), - new InSocket(this, SocketType.Float, "To", { + new InSocket(this, SocketType.Float, "label.socket.gradient.to", { defaultValue: 1, sliderProps: { hasBounds: false, @@ -53,7 +53,7 @@ export namespace images { ); this.outs.push( - new OutSocket(this, SocketType.Float, "Values", context => { + new OutSocket(this, SocketType.Float, "label.socket.gradient.values", context => { const fac = context.coords?.[this.whichDimension] ?? 0; const value0 = this.boundsSockets[0].inValue(context); const value1 = this.boundsSockets[1].inValue(context); @@ -91,12 +91,14 @@ export namespace images { private static readonly outputSlots = WebglSlot.outs("val", "texture", "width", "height"); + width = 200; + constructor() { super(); this.ins.push( - (this.imageSocket = new InSocket(this, SocketType.Image, "File", {showSocket: false})), - (this.normalizeCoordinatesSocket = new InSocket(this, SocketType.Bool, "Normalize coordinates", { + (this.imageSocket = new InSocket(this, SocketType.Image, "label.socket.imageFile.file", {showSocket: false})), + (this.normalizeCoordinatesSocket = new InSocket(this, SocketType.Bool, "label.socket.normalizeCoordinates", { showSocket: false, defaultValue: true, })), @@ -105,7 +107,7 @@ export namespace images { const {val, width, height} = ImageFileNode.outputSlots; this.outs.push( - new OutSocket(this, SocketType.Vector, "RGB", context => { + new OutSocket(this, SocketType.Vector, "label.rgb", context => { const imageData = this.imageSocket.inValue(context); if (!imageData) return [0, 0, 0] as Vec3; @@ -121,8 +123,9 @@ export namespace images { webglOutputs: socket => () => ({ [webglOuts.val]: WebglTemplate.source`${val}.rgb`, }), + socketDesc: "desc.socket.imageFileRgb", }), - new OutSocket(this, SocketType.Float, "Alpha", context => { + new OutSocket(this, SocketType.Float, "label.socket.alpha", context => { const imageData = this.imageSocket.inValue(context); if (!imageData) return 0; @@ -135,18 +138,21 @@ export namespace images { webglOutputs: socket => () => ({ [webglOuts.val]: WebglTemplate.source`${val}.a`, }), + socketDesc: "desc.socket.imageFileRgb", }), - new OutSocket(this, SocketType.Float, "Width", context => this.imageSocket.inValue(context)?.width ?? 0, { + new OutSocket(this, SocketType.Float, "label.socket.width", context => this.imageSocket.inValue(context)?.width ?? 0, { constant: true, webglOutputs: socket => () => ({ [webglOuts.val]: WebglTemplate.slot(width), }), + socketDesc: "desc.socket.imageFileWidth", }), - new OutSocket(this, SocketType.Float, "Height", context => this.imageSocket.inValue(context)?.height ?? 0, { + new OutSocket(this, SocketType.Float, "label.socket.height", context => this.imageSocket.inValue(context)?.height ?? 0, { constant: true, webglOutputs: socket => () => ({ [webglOuts.val]: WebglTemplate.slot(height), }), + socketDesc: "desc.socket.imageFileHeight", }), ); } @@ -233,18 +239,18 @@ uniform float ${height};`, const {val, color} = SampleNode.outputSlots; this.ins.push( - new InSocket(this, SocketType.Any, "Source", { + new InSocket(this, SocketType.Any, "label.socket.sample.source", { ...dynamicTyping.inSocketOptions, constant: true, }), ...(this.coordsSockets = [ - new InSocket(this, SocketType.Float, "X", {webglOutputMapping: {[webglOuts.val]: x}}), - new InSocket(this, SocketType.Float, "Y", {webglOutputMapping: {[webglOuts.val]: y}}), + new InSocket(this, SocketType.Float, "label.socket.x", {webglOutputMapping: {[webglOuts.val]: x}}), + new InSocket(this, SocketType.Float, "label.socket.y", {webglOutputMapping: {[webglOuts.val]: y}}), ]) ); this.outs.push( - new OutSocket(this, SocketType.Any, "Output", context => { + new OutSocket(this, SocketType.Any, "label.socket.value", context => { return this.ins[0].inValue({ coords: this.coordsSockets.map(socket => socket.inValue(context)) as [number, number], }); diff --git a/src/models/nodetypes/math.ts b/src/models/nodetypes/math.ts index 15bab5a..a475fdc 100644 --- a/src/models/nodetypes/math.ts +++ b/src/models/nodetypes/math.ts @@ -6,6 +6,7 @@ import { Vec3, lerp } from "@/util"; import { Overload, OverloadGroup, NodeWithOverloads } from "../Overload"; import { WebglSlot, WebglTemplate, WebglVariables } from "@/webgl-compute/WebglVariables"; import { randFloat, randFloatVec3Seed } from "../colormanagement/random"; +import { NO_DESC, StringKey } from "@/strings"; export namespace math { const singleDisplayValueVec: ConstructorParameters[3] = @@ -44,14 +45,14 @@ export namespace math { ({ label, operandLabels, - outputLabel="Vector", + outputLabel="label.socket.vector", defaultBlendAmount=1, calculate, getTemplate, }: { - label: string, - operandLabels: [string, string], - outputLabel?: string, + label: StringKey, + operandLabels: [StringKey, StringKey], + outputLabel?: StringKey, defaultBlendAmount?: number, calculate: (fac: number, val0: Vec3, val1: Vec3) => Vec3, getTemplate: (inputSlots: typeof VectorArithmeticNode["inputSlots"]) => WebglTemplate, @@ -63,7 +64,7 @@ export namespace math { node => { const {fac, val0, val1} = this.inputSlots; return [ - new InSocket(node, SocketType.Float, "Blend amount", { + new InSocket(node, SocketType.Float, "label.socket.blendAmount", { defaultValue: defaultBlendAmount, webglOutputMapping: {[webglOuts.val]: fac}, }), @@ -84,49 +85,49 @@ export namespace math { static readonly overloadGroup = new OverloadGroup(new Map([ [VectorArithmeticMode.Lerp, this.threeValueOverload({ - label: "Lerp", - operandLabels: ["Start", "End"], + label: "label.overload.lerp", + operandLabels: ["label.socket.start", "label.socket.end"], defaultBlendAmount: 0.5, calculate: (fac, val0, val1) => val0.map((_, i) => lerp(val0[i], val1[i], fac)) as Vec3, getTemplate: ({fac, val0, val1}) => WebglTemplate.source`mix(${val0}, ${val1}, ${fac})`, })], [VectorArithmeticMode.Add, this.threeValueOverload({ - label: "Add", - operandLabels: ["Addend", "Addend"], - outputLabel: "Sum", + label: "label.overload.add", + operandLabels: ["label.socket.addOperand", "label.socket.addOperand"], + outputLabel: "label.socket.addOut", calculate: (fac, val0, val1) => val0.map((_, i) => val0[i] + val1[i] * fac) as Vec3, getTemplate: ({fac, val0, val1}) => WebglTemplate.source`${val0} + ${val1} * ${fac}`, })], [VectorArithmeticMode.Multiply, this.threeValueOverload({ - label: "Componentwise multiply", - operandLabels: ["Factor", "Factor"], - outputLabel: "Product", + label: "label.overload.vectorArithmetic.componentwiseMultiply", + operandLabels: ["label.socket.multiplyOperand", "label.socket.multiplyOperand"], + outputLabel: "label.socket.multiplyOut", calculate: (fac, val0, val1) => val0.map((_, i) => val0[i] * ((1 - fac) + val1[i] * fac)) as Vec3, getTemplate: ({fac, val0, val1}) => WebglTemplate.source`${val0} * ((1. - ${fac}) + ${val1} * ${fac})`, })], [VectorArithmeticMode.Subtract, this.threeValueOverload({ - label: "Subtract", - operandLabels: ["Minuend", "Subtrahend"], - outputLabel: "Difference", + label: "label.overload.subtract", + operandLabels: ["label.socket.subtractOperand1", "label.socket.subtractOperand2"], + outputLabel: "label.socket.subtractOut", calculate: (fac, val0, val1) => val0.map((_, i) => val0[i] - val1[i] * fac) as Vec3, getTemplate: ({fac, val0, val1}) => WebglTemplate.source`${val0} - ${val1} * ${fac}`, })], [VectorArithmeticMode.Divide, this.threeValueOverload({ - label: "Componentwise divide", - operandLabels: ["Dividend", "Divisor"], - outputLabel: "Quotient", + label: "label.overload.vectorArithmetic.componentwiseMultiply", + operandLabels: ["label.socket.divideOperand1", "label.socket.divideOperand2"], + outputLabel: "label.socket.divideOut", calculate: (fac, val0, val1) => val0.map((_, i) => val0[i] / ((1 - fac) + val1[i] * fac)) as Vec3, getTemplate: ({fac, val0, val1}) => WebglTemplate.source`${val0} / ((1. - ${fac}) + ${val1} * ${fac})`, })], [VectorArithmeticMode.Screen, this.threeValueOverload({ - label: "Screen", - operandLabels: ["Factor", "Factor"], - outputLabel: "Product", + label: "label.overload.screen", + operandLabels: ["label.socket.multiplyOperand", "label.socket.multiplyOperand"], + outputLabel: "label.socket.multiplyOut", calculate: (fac, val0, val1) => val0.map((_, i) => 1 - (1 - val0[i]) * (1 - val1[i] * fac)) as Vec3, getTemplate: ({fac, val0, val1}) => WebglTemplate.source`1. - (1. - ${val0}) * (1. - ${val1} * ${fac})`, })], @@ -136,15 +137,15 @@ export namespace math { const outputs = ({[webglOuts.val]: WebglTemplate.source`length(${val0} - ${val1})`}); return new Overload( - "Distance", + "label.overload.vectorArithmetic.distance", node => { return [ - new InSocket(node, SocketType.Vector, "Vector", {webglOutputMapping: {[webglOuts.val]: val0}}), - new InSocket(node, SocketType.Vector, "Vector", {webglOutputMapping: {[webglOuts.val]: val1}}), + new InSocket(node, SocketType.Vector, "label.socket.vector", {webglOutputMapping: {[webglOuts.val]: val0}}), + new InSocket(node, SocketType.Vector, "label.socket.vector", {webglOutputMapping: {[webglOuts.val]: val1}}), ]; }, (node, ins) => [ - new OutSocket(node, SocketType.Float, "Distance", context => { + new OutSocket(node, SocketType.Float, "label.socket.vectorArithmetic.distance", context => { const [val0, val1] = ins.map(socket => socket.inValue(context)) as [Vec3, Vec3]; return Math.hypot(...val0.map((_, i) => val0[i] - val1[i])); }, { @@ -162,15 +163,15 @@ export namespace math { const outputs = ({[webglOuts.val]: WebglTemplate.source`${vector} * ${scalar}`}); return new Overload( - "Scalar multiply", + "label.overload.vectorArithmetic.scalarMultiply", node => { return [ - new InSocket(node, SocketType.Vector, "Vector", {webglOutputMapping: {[webglOuts.val]: vector}}), - new InSocket(node, SocketType.Float, "Scalar", {webglOutputMapping: {[webglOuts.val]: scalar}}), + new InSocket(node, SocketType.Vector, "label.socket.vector", {webglOutputMapping: {[webglOuts.val]: vector}}), + new InSocket(node, SocketType.Float, "label.socket.scalar", {webglOutputMapping: {[webglOuts.val]: scalar}}), ]; }, (node, ins) => [ - new OutSocket(node, SocketType.Vector, "Vector", context => { + new OutSocket(node, SocketType.Vector, "label.socket.vector", context => { const [col, scalar] = ins.map(socket => socket.inValue(context)) as [Vec3, number]; return col.map((_, i) => col[i] * scalar) as Vec3; }, { @@ -225,13 +226,13 @@ export namespace math { private static readonly singleOutputOverload = ({ label, ins, - outputLabel="Value", + outputLabel="label.socket.value", calculate, getTemplate, }: { - label: string, + label: StringKey, ins: (...args: Parameters[1]>) => [...InSockets], - outputLabel?: string, + outputLabel?: StringKey, calculate: (...inputs: {[I in keyof InSockets]: ReturnType}) => number, getTemplate: (inputSlots: typeof ArithmeticNode["inputSlots"]) => WebglTemplate, }) => { @@ -255,7 +256,7 @@ export namespace math { const {val} = this.inputSlots; return [ - new InSocket(node, SocketType.Float, "Value", { + new InSocket(node, SocketType.Float, "label.socket.value", { sliderProps: {hasBounds: false}, webglOutputMapping: {[webglOuts.val]: val}, }), @@ -264,14 +265,14 @@ export namespace math { private static readonly singleOutputTwoInputsOverload = ({ label, - operandLabels, - outputLabel="Value", + operandLabels=["label.socket.value", "label.socket.value"], + outputLabel="label.socket.value", calculate, getTemplate, }: { - label: string, - operandLabels: [string, string], - outputLabel?: string, + label: StringKey, + operandLabels?: [StringKey, StringKey], + outputLabel?: StringKey, calculate: (val0: number, val1: number) => number, getTemplate: (inputSlots: typeof ArithmeticNode["inputSlots"]) => WebglTemplate, }) => this.singleOutputOverload({ @@ -299,7 +300,7 @@ export namespace math { calculate, getTemplate, }: { - label: string, + label: StringKey, calculate: (val: number) => number, getTemplate: (inputSlots: typeof ArithmeticNode["inputSlots"]) => WebglTemplate, }) => this.singleOutputOverload({ @@ -311,67 +312,67 @@ export namespace math { static readonly overloadGroup = new OverloadGroup(new Map([ [ArithmeticMode.Add, this.singleOutputTwoInputsOverload({ - label: "Add", - operandLabels: ["Addend", "Addend"], - outputLabel: "Sum", + label: "label.overload.add", + operandLabels: ["label.socket.addOperand", "label.socket.addOperand"], + outputLabel: "label.socket.addOut", calculate: (val0, val1) => val0 + val1, getTemplate: ({val0, val1}) => WebglTemplate.source`${val0} + ${val1}`, })], [ArithmeticMode.Multiply, this.singleOutputTwoInputsOverload({ - label: "Multiply", - operandLabels: ["Factor", "Factor"], - outputLabel: "Product", + label: "label.overload.arithmetic.multiply", + operandLabels: ["label.socket.multiplyOperand", "label.socket.multiplyOperand"], + outputLabel: "label.socket.multiplyOut", calculate: (val0, val1) => val0 * val1, getTemplate: ({val0, val1}) => WebglTemplate.source`${val0} * ${val1}`, })], [ArithmeticMode.Subtract, this.singleOutputTwoInputsOverload({ - label: "Subtract", - operandLabels: ["Minuend", "Subtrahend"], - outputLabel: "Difference", + label: "label.overload.subtract", + operandLabels: ["label.socket.subtractOperand1", "label.socket.subtractOperand2"], + outputLabel: "label.socket.subtractOut", calculate: (val0, val1) => val0 - val1, getTemplate: ({val0, val1}) => WebglTemplate.source`${val0} - ${val1}`, })], [ArithmeticMode.Divide, this.singleOutputTwoInputsOverload({ - label: "Divide", - operandLabels: ["Dividend", "Divisor"], - outputLabel: "Quotient", + label: "label.overload.arithmetic.divide", + operandLabels: ["label.socket.divideOperand1", "label.socket.divideOperand2"], + outputLabel: "label.socket.divideOut", calculate: (val0, val1) => val0 / val1, getTemplate: ({val0, val1}) => WebglTemplate.source`${val0} / ${val1}`, })], [ArithmeticMode.Pow, this.singleOutputTwoInputsOverload({ - label: "Power", - operandLabels: ["Base", "Exponent"], - outputLabel: "Power", + label: "label.overload.arithmetic.power", + operandLabels: ["label.socket.arithmetic.powerBase", "label.socket.arithmetic.powerExponent"], + outputLabel: "label.socket.arithmetic.powerOut", calculate: (val0, val1) => val0 ** val1, getTemplate: ({val0, val1}) => WebglTemplate.source`pow(${val0}, ${val1})`, })], [ArithmeticMode.Screen, this.singleOutputTwoInputsOverload({ - label: "Screen", - operandLabels: ["Factor", "Factor"], - outputLabel: "Product", + label: "label.overload.screen", + operandLabels: ["label.socket.multiplyOperand", "label.socket.multiplyOperand"], + outputLabel: "label.socket.multiplyOut", calculate: (val0, val1) => 1 - (1 - val0) * (1 - val1), getTemplate: ({val0, val1}) => WebglTemplate.source`1. - (1. - ${val0}) * (1. - ${val1})`, })], [ArithmeticMode.Lerp, this.singleOutputOverload({ - label: "Lerp", + label: "label.overload.lerp", ins: node => { const {min, max, fac} = this.inputSlots; return [ - new InSocket(node, SocketType.Float, "Min", { + new InSocket(node, SocketType.Float, "label.socket.min", { sliderProps: {hasBounds: false}, webglOutputMapping: {[webglOuts.val]: min}, }), - new InSocket(node, SocketType.Float, "Max", { + new InSocket(node, SocketType.Float, "label.socket.max", { sliderProps: {hasBounds: false}, webglOutputMapping: {[webglOuts.val]: max}, }), - new InSocket(node, SocketType.Float, "Amount", {webglOutputMapping: {[webglOuts.val]: fac}}), + new InSocket(node, SocketType.Float, "label.socket.blendAmount", {webglOutputMapping: {[webglOuts.val]: fac}}), ]; }, calculate: lerp, @@ -379,27 +380,27 @@ export namespace math { })], [ArithmeticMode.MapRange, this.singleOutputOverload({ - label: "Map range", + label: "label.overload.arithmetic.mapRange", ins: node => { const {source, sourceMin, sourceMax, targetMin, targetMax} = this.inputSlots; return [ - new InSocket(node, SocketType.Float, "Source value", { + new InSocket(node, SocketType.Float, "label.socket.arithmetic.mapRange.sourceValue", { sliderProps: {hasBounds: false}, webglOutputMapping: {[webglOuts.val]: source}, }), - new InSocket(node, SocketType.Float, "Source min", { + new InSocket(node, SocketType.Float, "label.socket.arithmetic.mapRange.sourceMin", { sliderProps: {hasBounds: false}, webglOutputMapping: {[webglOuts.val]: sourceMin}, }), - new InSocket(node, SocketType.Float, "Source max", { + new InSocket(node, SocketType.Float, "label.socket.arithmetic.mapRange.sourceMax", { sliderProps: {hasBounds: false}, webglOutputMapping: {[webglOuts.val]: sourceMax}, }), - new InSocket(node, SocketType.Float, "Target min", { + new InSocket(node, SocketType.Float, "label.socket.arithmetic.mapRange.targetMin", { sliderProps: {hasBounds: false}, webglOutputMapping: {[webglOuts.val]: targetMin}, }), - new InSocket(node, SocketType.Float, "Target max", { + new InSocket(node, SocketType.Float, "label.socket.arithmetic.mapRange.targetMax", { sliderProps: {hasBounds: false}, webglOutputMapping: {[webglOuts.val]: targetMax}, }), @@ -410,73 +411,71 @@ export namespace math { })], [ArithmeticMode.Floor, this.singleOutputSingleInputOverload({ - label: "Floor", + label: "label.overload.arithmetic.floor", calculate: Math.floor, getTemplate: ({val}) => WebglTemplate.source`floor(${val})`, })], [ArithmeticMode.Sine, this.singleOutputSingleInputOverload({ - label: "Sine", + label: "label.overload.arithmetic.sine", calculate: Math.sin, getTemplate: ({val}) => WebglTemplate.source`sin(${val})`, })], [ArithmeticMode.Cosine, this.singleOutputSingleInputOverload({ - label: "Cosine", + label: "label.overload.arithmetic.cosine", calculate: Math.cos, getTemplate: ({val}) => WebglTemplate.source`cos(${val})`, })], [ArithmeticMode.Cosine, this.singleOutputSingleInputOverload({ - label: "Tangent", + label: "label.overload.arithmetic.tangent", calculate: Math.tan, getTemplate: ({val}) => WebglTemplate.source`tan(${val})`, })], [ArithmeticMode.Arcsine, this.singleOutputSingleInputOverload({ - label: "Arcsine", + label: "label.overload.arithmetic.arcsine", calculate: Math.asin, getTemplate: ({val}) => WebglTemplate.source`asin(${val})`, })], [ArithmeticMode.Arccosine, this.singleOutputSingleInputOverload({ - label: "Arccosine", + label: "label.overload.arithmetic.arccosine", calculate: Math.acos, getTemplate: ({val}) => WebglTemplate.source`acos(${val})`, })], [ArithmeticMode.Arctangent, this.singleOutputSingleInputOverload({ - label: "Arctangent", + label: "label.overload.arithmetic.arctangent", calculate: Math.atan, getTemplate: ({val}) => WebglTemplate.source`atan(${val})`, })], [ArithmeticMode.Arctangent2, this.singleOutputTwoInputsOverload({ - label: "Two-argument arctangent", - operandLabels: ["Y", "X"], - outputLabel: "Value", + label: "label.overload.arithmetic.arctangent2", + operandLabels: ["label.socket.y", "label.socket.x"], calculate: Math.atan2, getTemplate: ({val0, val1}) => WebglTemplate.source`atan(${val1}, ${val0})`, })], [ArithmeticMode.Hypotenuse, this.singleOutputTwoInputsOverload({ - label: "Hypotenuse", - operandLabels: ["Value", "Value"], - outputLabel: "Hypotenuse", + label: "label.overload.arithmetic.hypotenuse", + outputLabel: "label.socket.arithmetic.hypotenuse", calculate: Math.hypot, getTemplate: ({val0, val1}) => WebglTemplate.source`sqrt(${val0} * ${val0} + ${val1} * ${val1})`, })], [ArithmeticMode.Quantize, this.singleOutputOverload({ - label: "Quantize", + label: "label.overload.arithmetic.quantize", ins: node => { const {val, nSegments} = this.inputSlots; return [ - new InSocket(node, SocketType.Float, "Value", { + new InSocket(node, SocketType.Float, "label.socket.value", { sliderProps: {hasBounds: false}, webglOutputMapping: {[webglOuts.val]: val}, }), - new InSocket(node, SocketType.Float, "# segments", { + new InSocket(node, SocketType.Float, "label.socket.arithmetic.quantize.nSegments", { sliderProps: {hasBounds: false, step: 1}, defaultValue: 4, webglOutputMapping: {[webglOuts.val]: nSegments}, @@ -505,19 +504,19 @@ export namespace math { const {x, y, z} = VectorNode.inputSlots; this.ins.push( - new InSocket(this, SocketType.Float, "", { + new InSocket(this, SocketType.Float, NO_DESC, { sliderProps: { hasBounds: false, }, webglOutputMapping: {[webglOuts.val]: x}, }), - new InSocket(this, SocketType.Float, "", { + new InSocket(this, SocketType.Float, NO_DESC, { sliderProps: { hasBounds: false, }, webglOutputMapping: {[webglOuts.val]: y}, }), - new InSocket(this, SocketType.Float, "", { + new InSocket(this, SocketType.Float, NO_DESC, { sliderProps: { hasBounds: false, }, @@ -526,7 +525,7 @@ export namespace math { ); this.outs.push( - new OutSocket(this, SocketType.Vector, "Vector", context => this.ins.map(socket => socket.inValue(context)) as Vec3, { + new OutSocket(this, SocketType.Vector, "label.socket.vector", context => this.ins.map(socket => socket.inValue(context)) as Vec3, { webglOutputs: socket => () => ({[webglOuts.val]: WebglTemplate.source`vec3(${x}, ${y}, ${z})`}), }), ); @@ -550,17 +549,17 @@ export namespace math { const {vec} = SplitVectorNode.inputSlots; this.ins.push( - (this.inSocket = new InSocket(this, SocketType.Vector, "Vector", {webglOutputMapping: {[webglOuts.val]: vec}})), + (this.inSocket = new InSocket(this, SocketType.Vector, "label.socket.vector", {webglOutputMapping: {[webglOuts.val]: vec}})), ); this.outs.push( - new OutSocket(this, SocketType.Float, "1", context => this.inSocket.inValue(context)[0], { + new OutSocket(this, SocketType.Float, "label.socket.1", context => this.inSocket.inValue(context)[0], { webglOutputs: socket => () => ({[webglOuts.val]: WebglTemplate.source`${vec}.x`}), }), - new OutSocket(this, SocketType.Float, "2", context => this.inSocket.inValue(context)[1], { + new OutSocket(this, SocketType.Float, "label.socket.2", context => this.inSocket.inValue(context)[1], { webglOutputs: socket => () => ({[webglOuts.val]: WebglTemplate.source`${vec}.y`}), }), - new OutSocket(this, SocketType.Float, "3", context => this.inSocket.inValue(context)[2], { + new OutSocket(this, SocketType.Float, "label.socket.3", context => this.inSocket.inValue(context)[2], { webglOutputs: socket => () => ({[webglOuts.val]: WebglTemplate.source`${vec}.z`}), }), ); @@ -599,21 +598,21 @@ export namespace math { const {difference} = this.outputSlots; return new Overload( - "ΔE* 1976", + "label.overload.colorDifference.deltaE1976", node => { return [ - new InSocket(node, SocketType.VectorOrColor, "L*a*b* or color", { + new InSocket(node, SocketType.VectorOrColor, "label.socket.labOrColor", { sliderProps: labSliderProps, webglGetOutputMapping: socket => () => ({[webglOuts.val]: col0}), }), - new InSocket(node, SocketType.VectorOrColor, "L*a*b* or color", { + new InSocket(node, SocketType.VectorOrColor, "label.socket.labOrColor", { sliderProps: labSliderProps, webglGetOutputMapping: socket => () => ({[webglOuts.val]: col1}), }), ]; }, (node, ins) => [ - new OutSocket(node, SocketType.Float, "Difference", context => { + new OutSocket(node, SocketType.Float, "label.socket.colorDifference.difference", context => { const val0 = ins[0].inValue(context); const val1 = ins[1].inValue(context); @@ -643,19 +642,19 @@ export namespace math { const {difference} = this.outputSlots; return new Overload( - "ΔE* 2000", + "label.overload.colorDifference.deltaE2000", node => [ - new InSocket(node, SocketType.VectorOrColor, "Sample L*a*b* or color", { + new InSocket(node, SocketType.VectorOrColor, "label.socket.colorDifference.sampleLabOrColor", { sliderProps: labSliderProps, webglGetOutputMapping: socket => () => ({[webglOuts.val]: col0}), }), - new InSocket(node, SocketType.VectorOrColor, "Target L*a*b* or color", { + new InSocket(node, SocketType.VectorOrColor, "label.socket.colorDifference.targetLabOrColor", { sliderProps: labSliderProps, webglGetOutputMapping: socket => () => ({[webglOuts.val]: col1}), }), ], (node, ins) => [ - new OutSocket(node, SocketType.Float, "Difference", context => { + new OutSocket(node, SocketType.Float, "label.socket.colorDifference.difference", context => { const val0 = ins[0].inValue(context); const val1 = ins[1].inValue(context); @@ -710,10 +709,10 @@ export namespace math { this.ins.push( ...(this.colorSockets = [ - new InSocket(this, SocketType.VectorOrColor, "XYZ or color", { + new InSocket(this, SocketType.VectorOrColor, "label.socket.xyzOrColor", { webglGetOutputMapping: socket => () => ({[webglOuts.val]: col0}), }), - new InSocket(this, SocketType.VectorOrColor, "XYZ or color", { + new InSocket(this, SocketType.VectorOrColor, "label.socket.xyzOrColor", { webglGetOutputMapping: socket => () => ({[webglOuts.val]: col1}), }), ]), @@ -729,22 +728,22 @@ export namespace math { const checkContrastRatioPassesThreshold = (threshold: number) => (context: NodeEvalContext) => calculateContrastRatio(context) >= threshold; this.outs.push( - new OutSocket(this, SocketType.Float, "Ratio", calculateContrastRatio, { + new OutSocket(this, SocketType.Float, "label.socket.contrastRatio.ratio", calculateContrastRatio, { webglOutputs: socket => () => ({[webglOuts.val]: WebglTemplate.slot(contrastRatio)}), }), - new OutSocket(this, SocketType.Bool, "Passes AAA body text?", checkContrastRatioPassesThreshold(7), { + new OutSocket(this, SocketType.Bool, "label.socket.contrastRatio.aaaBody?", checkContrastRatioPassesThreshold(7), { webglOutputs: socket => () => ({[webglOuts.val]: WebglTemplate.source`${contrastRatio} > 7.`}), }), - new OutSocket(this, SocketType.Bool, "Passes AAA large text?", checkContrastRatioPassesThreshold(4.5), { + new OutSocket(this, SocketType.Bool, "label.socket.contrastRatio.aaaLarge?", checkContrastRatioPassesThreshold(4.5), { webglOutputs: socket => () => ({[webglOuts.val]: WebglTemplate.source`${contrastRatio} > 4.5`}), }), - new OutSocket(this, SocketType.Bool, "Passes AA body text?", checkContrastRatioPassesThreshold(4.5), { + new OutSocket(this, SocketType.Bool, "label.socket.contrastRatio.aaBody?", checkContrastRatioPassesThreshold(4.5), { webglOutputs: socket => () => ({[webglOuts.val]: WebglTemplate.source`${contrastRatio} > 4.5`}), }), - new OutSocket(this, SocketType.Bool, "Passes AA large text?", checkContrastRatioPassesThreshold(3), { + new OutSocket(this, SocketType.Bool, "label.socket.contrastRatio.aaLarge?", checkContrastRatioPassesThreshold(3), { webglOutputs: socket => () => ({[webglOuts.val]: WebglTemplate.source`${contrastRatio} > 3.`}), }), - new OutSocket(this, SocketType.Bool, "Passes AA graphical elements?", checkContrastRatioPassesThreshold(3), { + new OutSocket(this, SocketType.Bool, "label.socket.contrastRatio.aaUi?", checkContrastRatioPassesThreshold(3), { webglOutputs: socket => () => ({[webglOuts.val]: WebglTemplate.source`${contrastRatio} > 3.`}), }), ); @@ -802,28 +801,28 @@ export namespace math { const {float, val} = this.outputSlots; return new Overload( - "Float seed", + "label.overload.randomFloat.floatSeed", node => [ - new InSocket(node, SocketType.Bool, "Integer", { + new InSocket(node, SocketType.Bool, "label.socket.randomFloat.integersOnly?", { showSocket: false, webglOutputMapping: {[webglOuts.val]: useFloor}, }), - new InSocket(node, SocketType.Float, "Seed", { + new InSocket(node, SocketType.Float, "label.socket.randomFloat.seed", { sliderProps: {hasBounds: false}, webglOutputMapping: {[webglOuts.val]: seed}, }), - new InSocket(node, SocketType.Float, "Min", { + new InSocket(node, SocketType.Float, "label.socket.min", { sliderProps: {hasBounds: false}, webglOutputMapping: {[webglOuts.val]: min}, }), - new InSocket(node, SocketType.Float, "Max", { + new InSocket(node, SocketType.Float, "label.socket.max", { sliderProps: {hasBounds: false}, defaultValue: 1, webglOutputMapping: {[webglOuts.val]: max}, }), ], (node, ins) => [ - new OutSocket(node, SocketType.Float, "Value", context => { + new OutSocket(node, SocketType.Float, "label.socket.value", context => { const useFloor = ins[0].inValue(context) const min = ins[2].inValue(context) as number; const max = ins[3].inValue(context) as number; @@ -855,13 +854,13 @@ float ${val} = ${useFloor} ? floor(${float}) : ${float};`({ const {float, val} = this.outputSlots; return new Overload( - "Vector seed", + "label.overload.randomFloat.vectorSeed", node => [ - new InSocket(node, SocketType.Bool, "Integer", { + new InSocket(node, SocketType.Bool, "label.socket.randomFloat.integersOnly?", { showSocket: false, webglOutputMapping: {[webglOuts.val]: useFloor}, }), - new InSocket(node, SocketType.Vector, "Seed", { + new InSocket(node, SocketType.Vector, "label.socket.randomFloat.seed", { sliderProps: [ {hasBounds: false}, {hasBounds: false}, @@ -869,18 +868,18 @@ float ${val} = ${useFloor} ? floor(${float}) : ${float};`({ ], webglOutputMapping: {[webglOuts.val]: seed}, }), - new InSocket(node, SocketType.Float, "Min", { + new InSocket(node, SocketType.Float, "label.socket.min", { sliderProps: {hasBounds: false}, webglOutputMapping: {[webglOuts.val]: min}, }), - new InSocket(node, SocketType.Float, "Max", { + new InSocket(node, SocketType.Float, "label.socket.max", { sliderProps: {hasBounds: false}, defaultValue: 1, webglOutputMapping: {[webglOuts.val]: max}, }), ], (node, ins) => [ - new OutSocket(node, SocketType.Float, "Value", context => { + new OutSocket(node, SocketType.Float, "label.socket.value", context => { const useFloor = ins[0].inValue(context) const min = ins[2].inValue(context) as number; const max = ins[3].inValue(context) as number; diff --git a/src/models/nodetypes/models.ts b/src/models/nodetypes/models.ts index 8fc3506..431ab50 100644 --- a/src/models/nodetypes/models.ts +++ b/src/models/nodetypes/models.ts @@ -6,6 +6,7 @@ import { Vec3 } from "@/util"; import { illuminantE } from "../colormanagement/spaces/col-xyz-xyy-illuminants"; import { getIlluminant, whitePointSocketOptions } from "./spaces"; import { WebglSlot, WebglTemplate, WebglVariables } from "@/webgl-compute/WebglVariables"; +import { StringKey } from "@/strings"; export namespace models { export class RgbNode extends Node { @@ -20,13 +21,13 @@ export namespace models { const {red, green, blue} = RgbNode.inputSlots; this.ins.push( - new InSocket(this, SocketType.Float, "Red", {webglOutputMapping: {[webglOuts.val]: red}}).flag(SocketFlag.Rgb), - new InSocket(this, SocketType.Float, "Green", {webglOutputMapping: {[webglOuts.val]: green}}).flag(SocketFlag.Rgb), - new InSocket(this, SocketType.Float, "Blue", {webglOutputMapping: {[webglOuts.val]: blue}}).flag(SocketFlag.Rgb), + new InSocket(this, SocketType.Float, "label.socket.red", {webglOutputMapping: {[webglOuts.val]: red}}).flag(SocketFlag.Rgb), + new InSocket(this, SocketType.Float, "label.socket.green", {webglOutputMapping: {[webglOuts.val]: green}}).flag(SocketFlag.Rgb), + new InSocket(this, SocketType.Float, "label.socket.blue", {webglOutputMapping: {[webglOuts.val]: blue}}).flag(SocketFlag.Rgb), ); this.outs.push( - new OutSocket(this, SocketType.Vector, "RGB", context => this.ins.map(socket => socket.inValue(context)) as Vec3, { + new OutSocket(this, SocketType.Vector, "label.socket.blue", context => this.ins.map(socket => socket.inValue(context)) as Vec3, { webglOutputs: socket => () => ({[webglOuts.val]: WebglTemplate.source`vec3(${red}, ${green}, ${blue})`}), }), ); @@ -66,7 +67,7 @@ export namespace models { id: string, outputDisplayType: OutputDisplayType, - socketLabels: string[], + socketLabels: StringKey[], nodeDisplayLabels: string[], socketFlags?: SocketFlag[], @@ -87,13 +88,13 @@ export namespace models { static readonly overloadGroup = new OverloadGroup(new Map([ [RgbOverloadMode.ToRgb, new Overload( - "To RGB", + "label.overload.toRgb", node => Object.values(inputSlots).map( (slot, i) => new InSocket(node, SocketType.Float, socketLabels[i], {webglOutputMapping: {[webglOuts.val]: slot}}).flag(socketFlags[i]), ), (node, ins) => [ - new OutSocket(node, SocketType.Vector, "RGB", context => toRgb.convert(ins.map(socket => socket.inValue(context)) as Vec3) as Vec3, { + new OutSocket(node, SocketType.Vector, "label.rgb", context => toRgb.convert(ins.map(socket => socket.inValue(context)) as Vec3) as Vec3, { webglOutputs: socket => () => toRgbOutputs, }), ], @@ -107,9 +108,9 @@ export namespace models { )], [RgbOverloadMode.FromRgb, new Overload( - "From RGB", + "label.overload.fromRgb", node => [ - new InSocket(node, SocketType.Vector, "RGB", {webglOutputMapping: {[webglOuts.val]: rgb}}), + new InSocket(node, SocketType.Vector, "label.rgb", {webglOutputMapping: {[webglOuts.val]: rgb}}), ], (node, ins) => Object.values(inputSlots).map( (slot, i) => @@ -140,7 +141,7 @@ export namespace models { id: "hsl", outputDisplayType: OutputDisplayType.Vec, - socketLabels: ["Hue", "Saturation", "Lightness"], + socketLabels: ["label.socket.hue", "label.socket.saturation", "label.socket.lightness"], nodeDisplayLabels: ["H", "S", "L"], socketFlags: [SocketFlag.Hue, SocketFlag.None, SocketFlag.None], toRgb: { @@ -158,7 +159,7 @@ export namespace models { id: "hsv", outputDisplayType: OutputDisplayType.Vec, - socketLabels: ["Hue", "Saturation", "Value"], + socketLabels: ["label.socket.hue", "label.socket.saturation", "label.socket.hsv.value"], nodeDisplayLabels: ["H", "S", "V"], socketFlags: [SocketFlag.Hue, SocketFlag.None, SocketFlag.None], toRgb: { @@ -176,7 +177,7 @@ export namespace models { id: "hwb", outputDisplayType: OutputDisplayType.Vec, - socketLabels: ["Hue", "Whiteness", "Blackness"], + socketLabels: ["label.socket.hue", "label.socket.whiteness", "label.socket.blackness"], nodeDisplayLabels: ["H", "W", "B"], socketFlags: [SocketFlag.Hue, SocketFlag.None, SocketFlag.None], toRgb: { @@ -194,7 +195,7 @@ export namespace models { id: "cmy", outputDisplayType: OutputDisplayType.Vec, - socketLabels: ["Cyan", "Magenta", "Yellow"], + socketLabels: ["label.socket.cyan", "label.socket.magenta", "label.socket.yellow"], nodeDisplayLabels: ["C", "M", "Y"], toRgb: { convert: cm.cmyToRgb, @@ -247,19 +248,19 @@ export namespace models { const {lightness, redGreen, yellowBlue} = LxyNode.inputSlots; this.ins.push( - new InSocket(this, SocketType.Float, "Lightness", { + new InSocket(this, SocketType.Float, "label.socket.lightness", { webglOutputMapping: {[webglOuts.val]: lightness}, sliderProps: { hasBounds: false, }, }), - new InSocket(this, SocketType.Float, "Red–green", { + new InSocket(this, SocketType.Float, "label.socket.redGreen", { webglOutputMapping: {[webglOuts.val]: redGreen}, sliderProps: { hasBounds: false, }, }), - new InSocket(this, SocketType.Float, "Yellow–blue", { + new InSocket(this, SocketType.Float, "label.socket.yellowBlue", { webglOutputMapping: {[webglOuts.val]: yellowBlue}, sliderProps: { hasBounds: false, @@ -268,7 +269,7 @@ export namespace models { ); this.outs.push( - new OutSocket(this, SocketType.Vector, "Lxy", context => this.ins.map(socket => socket.inValue(context)) as Vec3, { + new OutSocket(this, SocketType.Vector, "label.lxy", context => this.ins.map(socket => socket.inValue(context)) as Vec3, { webglOutputs: socket => () => ({[webglOuts.val]: WebglTemplate.source`vec3(${lightness}, ${redGreen}, ${yellowBlue})`}), }), ); @@ -284,7 +285,7 @@ export namespace models { } export const LchNode = (() => { - const socketLabels = ["Lightness", "Colorfulness", "Hue"]; + const socketLabels = ["label.socket.lightness", "label.socket.colorfulness", "label.socket.hue"] as StringKey[]; const inputSlots = WebglSlot.ins("lightness", "colorfulness", "hue"); const {lightness, colorfulness, hue} = inputSlots; @@ -300,7 +301,7 @@ export namespace models { static readonly overloadGroup = new OverloadGroup(new Map([ [LxyOverloadMode.ToLxy, new Overload( - "To Lxy", + "label.overload.toLxy", node => [ new InSocket(node, SocketType.Float, socketLabels[0], { webglOutputMapping: {[webglOuts.val]: lightness}, @@ -319,7 +320,7 @@ export namespace models { }).flag(SocketFlag.Hue), ], (node, ins) => [ - new OutSocket(node, SocketType.Vector, "Lxy", context => cm.lchToLxy(ins.map(socket => socket.inValue(context)) as Vec3) as Vec3, { + new OutSocket(node, SocketType.Vector, "label.lxy", context => cm.lchToLxy(ins.map(socket => socket.inValue(context)) as Vec3) as Vec3, { webglOutputs: socket => () => toLxyOutputs, }), ], @@ -333,9 +334,9 @@ export namespace models { )], [LxyOverloadMode.FromLxy, new Overload( - "From Lxy", + "label.overload.fromLxy", node => [ - new InSocket(node, SocketType.Vector, "Lxy", { + new InSocket(node, SocketType.Vector, "label.lxy", { webglOutputMapping: {[webglOuts.val]: lxy}, sliderProps: [ { @@ -394,10 +395,10 @@ export namespace models { const {unif} = SpectralPowerDistributionNode.outputSlots; this.outs.push( - new OutSocket(this, SocketType.Vector, "XYZ", context => this.computeXyz(), { + new OutSocket(this, SocketType.Vector, "label.xyz", context => this.computeXyz(), { webglOutputs: socket => () => ({[webglOuts.val]: WebglTemplate.slot(unif)}), }), - new OutSocket(this, SocketType.ColorComponents, "Color", context => new cm.Xyz(this.computeXyz(), illuminantE), { + new OutSocket(this, SocketType.ColorComponents, "label.socket.color", context => new cm.Xyz(this.computeXyz(), illuminantE), { webglOutputs: socket => () => ({[webglOuts.val]: WebglTemplate.source`Color(${unif}, illuminant2_E, ${unif})`}), }), ); @@ -451,7 +452,7 @@ export namespace models { const {xyz} = WavelengthNode.outputSlots; this.ins.push( - (this.inSocket = new InSocket(this, SocketType.Float, "Wavelength (nm)", { + (this.inSocket = new InSocket(this, SocketType.Float, "label.socket.wavelength", { sliderProps: { softMin: 360, softMax: 830, @@ -460,29 +461,29 @@ export namespace models { defaultValue: 510, webglOutputMapping: {[webglOuts.val]: wavelength}, })), - (this.powerSocket = new InSocket(this, SocketType.Float, "Relative power", { + (this.powerSocket = new InSocket(this, SocketType.Float, "label.socket.wavelength.relativePower", { sliderProps: { hasBounds: false, }, defaultValue: 1, webglOutputMapping: {[webglOuts.val]: power}, })), - (this.datasetSocket = new InSocket(this, SocketType.Dropdown, "Dataset", { + (this.datasetSocket = new InSocket(this, SocketType.Dropdown, "label.socket.cmfDataset", { showSocket: false, defaultValue: "2deg", options: [ - {value: "2deg", text: "CIE 2° observer (1931)"}, - {value: "10deg", text: "CIE 10° observer (1964)"}, + {value: "2deg", text: "label.cmfDataset.2deg"}, + {value: "10deg", text: "label.cmfDataset.10deg"}, ], valueChangeRequiresShaderReload: true, })), ); this.outs.push( - new OutSocket(this, SocketType.Vector, "XYZ", context => this.computeXyz(context), { + new OutSocket(this, SocketType.Vector, "label.xyz", context => this.computeXyz(context), { webglOutputs: socket => () => ({[webglOuts.val]: WebglTemplate.slot(xyz)}), }), - new OutSocket(this, SocketType.ColorComponents, "Color", context => new cm.Xyz(this.computeXyz(context), illuminantE), { + new OutSocket(this, SocketType.ColorComponents, "label.socket.color", context => new cm.Xyz(this.computeXyz(context), illuminantE), { webglOutputs: socket => () => ({[webglOuts.val]: WebglTemplate.source`Color(${xyz}, illuminant2_E, ${xyz})`}), }), ); @@ -523,7 +524,7 @@ export namespace models { const {xyz} = BlackbodyNode.outputSlots; this.ins.push( - (this.inSocket = new InSocket(this, SocketType.Float, "Temperature (K)", { + (this.inSocket = new InSocket(this, SocketType.Float, "label.socket.blackbody.temperature", { sliderProps: { hasBounds: false, unboundedChangePerPixel: 10, @@ -531,21 +532,21 @@ export namespace models { defaultValue: 1750, webglOutputMapping: {[webglOuts.val]: temperature}, })), - (this.datasetSocket = new InSocket(this, SocketType.Dropdown, "Dataset", { + (this.datasetSocket = new InSocket(this, SocketType.Dropdown, "label.socket.cmfDataset", { showSocket: false, defaultValue: "2deg", options: [ - {value: "2deg", text: "CIE 2° observer (1931)"}, - {value: "10deg", text: "CIE 10° observer (1964)"}, + {value: "2deg", text: "label.cmfDataset.2deg"}, + {value: "10deg", text: "label.cmfDataset.10deg"}, ], })), ); this.outs.push( - new OutSocket(this, SocketType.Vector, "XYZ", context => this.computeXyz(context), { + new OutSocket(this, SocketType.Vector, "label.xyz", context => this.computeXyz(context), { webglOutputs: socket => () => ({[webglOuts.val]: WebglTemplate.slot(xyz)}), }), - new OutSocket(this, SocketType.ColorComponents, "Color", context => new cm.Xyz(this.computeXyz(context), illuminantE), { + new OutSocket(this, SocketType.ColorComponents, "label.socket.color", context => new cm.Xyz(this.computeXyz(context), illuminantE), { webglOutputs: socket => () => ({[webglOuts.val]: WebglTemplate.source`Color(${xyz}, illuminant2_E, ${xyz})`}), }), ); @@ -588,17 +589,17 @@ export namespace models { const {xyz, xyy} = StandardIlluminantNode.outputSlots; this.ins.push( - (this.whitePointSocket = new InSocket(this, SocketType.Dropdown, "White point", whitePointSocketOptions)), + (this.whitePointSocket = new InSocket(this, SocketType.Dropdown, "label.socket.illuminant", whitePointSocketOptions)), ); this.outs.push( - new OutSocket(this, SocketType.Vector, "XYZ", context => [...cm.Xyz.from(this.getIlluminant(context))] as Vec3, { + new OutSocket(this, SocketType.Vector, "label.xyz", context => [...cm.Xyz.from(this.getIlluminant(context))] as Vec3, { webglOutputs: socket => () => ({[webglOuts.val]: WebglTemplate.slot(xyz)}), }), - new OutSocket(this, SocketType.Vector, "xyY", context => [...cm.Xyy.from(this.getIlluminant(context))] as Vec3, { + new OutSocket(this, SocketType.Vector, "label.xyy", context => [...cm.Xyy.from(this.getIlluminant(context))] as Vec3, { webglOutputs: socket => () => ({[webglOuts.val]: WebglTemplate.slot(xyy)}), }), - new OutSocket(this, SocketType.ColorComponents, "Color", context => cm.Xyz.from(this.getIlluminant(context)), { + new OutSocket(this, SocketType.ColorComponents, "label.socket.color", context => cm.Xyz.from(this.getIlluminant(context)), { webglOutputs: socket => () => ({[webglOuts.val]: WebglTemplate.source`Color(${xyz}, illuminant2_E, ${xyz})`}), }), ); diff --git a/src/models/nodetypes/organization.ts b/src/models/nodetypes/organization.ts index 01fb983..eae1ff0 100644 --- a/src/models/nodetypes/organization.ts +++ b/src/models/nodetypes/organization.ts @@ -1,3 +1,4 @@ +import { NO_DESC } from "@/strings"; import { Node, SocketType, NodeEvalContext, InSocket, OutSocket, webglOuts } from "../Node"; import { dynamicInSocketMapping, useDynamicallyTypedSockets } from "./util"; @@ -23,7 +24,7 @@ export namespace organization { ); this.ins.push( - new InSocket(this, SocketType.Any, "", { + new InSocket(this, SocketType.Any, NO_DESC, { ...dynamicTyping.inSocketOptions, //@ts-ignore webglGetOutputMapping: dynamicInSocketMapping({val, illuminant, xyz}), @@ -31,7 +32,7 @@ export namespace organization { ); this.outs.push( - new OutSocket(this, SocketType.Any, "", context => this.ins[0].inValue(context), { + new OutSocket(this, SocketType.Any, NO_DESC, context => this.ins[0].inValue(context), { ...dynamicTyping.outSocketOptions, webglOutputs: socket => () => ({[webglOuts.val]: WebglTemplate.slot(val)}), }), diff --git a/src/models/nodetypes/output.ts b/src/models/nodetypes/output.ts index bce3db2..8e898bc 100644 --- a/src/models/nodetypes/output.ts +++ b/src/models/nodetypes/output.ts @@ -20,9 +20,9 @@ export namespace output { static readonly overloadGroup = new OverloadGroup(new Map([ [CssOutputMode.RgbVector, new Overload( - "RGB vector", + "label.overload.cssOutput.rgbVector", node => [ - new InSocket(node, SocketType.Vector, "RGB").flag(SocketFlag.Rgb), + new InSocket(node, SocketType.Vector, "label.rgb").flag(SocketFlag.Rgb), ], node => [], (ins, outs, context) => ({ @@ -32,9 +32,9 @@ export namespace output { }), )], [CssOutputMode.Color, new Overload( - "Color", + "label.overload.cssOutput.color", node => [ - new InSocket(node, SocketType.ColorComponents, "Color"), + new InSocket(node, SocketType.ColorComponents, "label.socket.color"), ], node => [], (ins, outs, context) => ({ @@ -56,20 +56,20 @@ export namespace output { static readonly overloadGroup = new OverloadGroup(new Map([ [ChromaticityPlotMode.Color, new Overload( - "From colors", + "label.overload.chromaticityPlot.fromColor", node => [ - new InSocket(node, SocketType.ColorComponents, "Colors"), + new InSocket(node, SocketType.ColorComponents, "label.socket.colors"), ], node => [], )], [ChromaticityPlotMode.Xy, new Overload( - "From xy", + "label.overload.chromaticityPlot.fromXy", node => [ - new InSocket(node, SocketType.Float, "x", { + new InSocket(node, SocketType.Float, "label.xyy.x", { defaultValue: cm.illuminantsXy["2deg"]["D65"][0], }), - new InSocket(node, SocketType.Float, "y", { + new InSocket(node, SocketType.Float, "label.xyy.y", { defaultValue: cm.illuminantsXy["2deg"]["D65"][1], }), ], @@ -103,22 +103,22 @@ export namespace output { const {val, alpha} = ImagePlotNode.inputSlots; this.ins.push( - (this.normalizeCoordsSocket = new InSocket(this, SocketType.Bool, "Normalize coordinates", { + (this.normalizeCoordsSocket = new InSocket(this, SocketType.Bool, "label.socket.normalizeCoordinates", { showSocket: false, defaultValue: true, })), - new InSocket(this, SocketType.ColorComponents, "Colors", { + new InSocket(this, SocketType.ColorComponents, "label.socket.colors", { webglOutputMapping: { [webglOuts.val]: val, }, }), - (this.alphaSocket = new InSocket(this, SocketType.Float, "Alpha", { + (this.alphaSocket = new InSocket(this, SocketType.Float, "label.socket.alpha", { defaultValue: 1, webglOutputMapping: { [webglOuts.val]: alpha, }, })), - (this.widthSocket = new InSocket(this, SocketType.Float, "Width", { + (this.widthSocket = new InSocket(this, SocketType.Float, "label.socket.width", { defaultValue: 240, constant: true, sliderProps: { @@ -127,7 +127,7 @@ export namespace output { min: 1, }, })), - (this.heightSocket = new InSocket(this, SocketType.Float, "Height", { + (this.heightSocket = new InSocket(this, SocketType.Float, "label.socket.height", { defaultValue: 240, constant: true, sliderProps: { @@ -173,7 +173,7 @@ export namespace output { constructor() { super(); this.ins.push( - (this.colorsSocket = new InSocket(this, SocketType.ColorComponents, "Colors")), + (this.colorsSocket = new InSocket(this, SocketType.ColorComponents, "label.socket.colors")), ); } } diff --git a/src/models/nodetypes/spaces.ts b/src/models/nodetypes/spaces.ts index 5c2e932..c11c67e 100644 --- a/src/models/nodetypes/spaces.ts +++ b/src/models/nodetypes/spaces.ts @@ -35,31 +35,31 @@ export const oklabSliderProps = [ }, ]; -export const whitePointSocketOptions = { +export const whitePointSocketOptions = >{ options: [ - {value: "2deg/A", text: "CIE 2° / A"}, - {value: "2deg/B", text: "CIE 2° / B"}, - {value: "2deg/C", text: "CIE 2° / C"}, - {value: "2deg/D50", text: "CIE 2° / D50"}, - {value: "2deg/D55", text: "CIE 2° / D55"}, - {value: "2deg/D60", text: "CIE 2° / D60"}, - {value: "2deg/D65", text: "CIE 2° / D65"}, - {value: "2deg/D75", text: "CIE 2° / D75"}, - {value: "2deg/E", text: "CIE 2° / E"}, - {value: "10deg/A", text: "CIE 10° / A"}, - {value: "10deg/B", text: "CIE 10° / B"}, - {value: "10deg/C", text: "CIE 10° / C"}, - {value: "10deg/D50", text: "CIE 10° / D50"}, - {value: "10deg/D55", text: "CIE 10° / D55"}, - {value: "10deg/D60", text: "CIE 10° / D60"}, - {value: "10deg/D65", text: "CIE 10° / D65"}, - {value: "10deg/D75", text: "CIE 10° / D75"}, - {value: "10deg/E", text: "CIE 10° / E"}, + {value: "2deg/A", text: "label.standardIlluminant.2deg.a"}, + {value: "2deg/B", text: "label.standardIlluminant.2deg.b"}, + {value: "2deg/C", text: "label.standardIlluminant.2deg.c"}, + {value: "2deg/D50", text: "label.standardIlluminant.2deg.d50"}, + {value: "2deg/D55", text: "label.standardIlluminant.2deg.d55"}, + {value: "2deg/D60", text: "label.standardIlluminant.2deg.d60"}, + {value: "2deg/D65", text: "label.standardIlluminant.2deg.d65"}, + {value: "2deg/D75", text: "label.standardIlluminant.2deg.d75"}, + {value: "2deg/E", text: "label.standardIlluminant.2deg.e"}, + {value: "10deg/A", text: "label.standardIlluminant.10deg.a"}, + {value: "10deg/B", text: "label.standardIlluminant.10deg.b"}, + {value: "10deg/C", text: "label.standardIlluminant.10deg.c"}, + {value: "10deg/D50", text: "label.standardIlluminant.10deg.d50"}, + {value: "10deg/D55", text: "label.standardIlluminant.10deg.d55"}, + {value: "10deg/D60", text: "label.standardIlluminant.10deg.d60"}, + {value: "10deg/D65", text: "label.standardIlluminant.10deg.d65"}, + {value: "10deg/D75", text: "label.standardIlluminant.10deg.d75"}, + {value: "10deg/E", text: "label.standardIlluminant.10deg.e"}, ], showSocket: false, defaultValue: "2deg/D65", socketDesc: "desc.socket.illuminant" as StringKey, -} as SocketOptions; +}; export const getIlluminant = (socket: InSocket, context: NodeEvalContext) => { const illuminantId = socket.inValue(context); if (illuminantId !== "custom") { @@ -96,11 +96,11 @@ export namespace spaces { const {outColor, newIlluminant} = this.outputSlots; return new Overload( - "From vector", + "label.overload.fromVector", node => { const sockets: InSocket[] = []; if (node.includeWhitePoint) { - sockets.push(node.illuminantSocket = new InSocket(node, SocketType.Dropdown, "White point", whitePointSocketOptions)); + sockets.push(node.illuminantSocket = new InSocket(node, SocketType.Dropdown, "label.socket.illuminant", whitePointSocketOptions)); } const {inVal} = this.inputSlots; @@ -113,7 +113,7 @@ export namespace spaces { return sockets; }, node => [ - new OutSocket(node, SocketType.ColorComponents, "Color", context => node.computeColor(context, true), { + new OutSocket(node, SocketType.ColorComponents, "label.socket.color", context => node.computeColor(context, true), { webglOutputs: socket => () => ({[webglOuts.val]: WebglTemplate.slot(outColor)}), }), ...node.componentLabels.map( @@ -127,7 +127,7 @@ export namespace spaces { ], (ins, outs, context, node) => ({ values: node.computeColor(context, true), - labels: node.componentLabels, + labels: node.displayLabels, flags: node.displayFlags, }), (ins, outs, context, node) => { @@ -170,7 +170,7 @@ export namespace spaces { const {outColor, newIlluminant, outComponents} = this.outputSlots; return new Overload( - "From values", + "label.overload.fromValues", node => { const slots = [x, y, z]; @@ -189,19 +189,19 @@ export namespace spaces { const sockets: InSocket[] = []; if (node.includeWhitePoint) { - sockets.push(node.illuminantSocket = new InSocket(node, SocketType.Dropdown, "White point", whitePointSocketOptions)); + sockets.push(node.illuminantSocket = new InSocket(node, SocketType.Dropdown, "label.socket.illuminant", whitePointSocketOptions)); } sockets.push(...(node.valuesSockets = node.componentLabels.map((label, i) => new InSocket(node, SocketType.Float, label, individualSocketOptions[i])))); return sockets; }, node => [ - new OutSocket(node, SocketType.ColorComponents, "Color", context => node.computeColor(context, false), { + new OutSocket(node, SocketType.ColorComponents, "label.socket.color", context => node.computeColor(context, false), { webglOutputs: socket => () => ({[webglOuts.val]: WebglTemplate.slot(outColor)}), }), ], (ins, outs, context, node) => ({ values: node.computeColor(context, false), - labels: node.componentLabels, + labels: node.displayLabels, flags: node.displayFlags, }), (ins, outs, context, node) => WebglVariables.templateConcat`vec3 ${outComponents} = vec3(${x}, ${y}, ${z}); @@ -231,14 +231,18 @@ Color ${outColor} = Color(${outComponents}, ${newIlluminant}, ${node.webglCompon /** The color class to use for conversions */ abstract get ColClass(): typeof cm.Col; - abstract get componentLabels(): string[]; - + abstract get componentLabels(): StringKey[]; + + get displayLabels(): string[] { + return []; + } + get displayFlags(): SocketFlag[] { return []; } constructInSocket(socketOptions: InSocketOptions) { - return new InSocket(this, SocketType.VectorOrColor, "Vector or color"); + return new InSocket(this, SocketType.VectorOrColor, "label.socket.vectorOrColor"); } inSocketOptions(): SocketOptions { return {}; @@ -279,11 +283,11 @@ Color ${outColor} = Color(${outComponents}, ${newIlluminant}, ${node.webglCompon return [SocketFlag.Rgb, SocketFlag.Rgb, SocketFlag.Rgb]; } - get componentLabels() { - return ["R", "G", "B"]; + get componentLabels(): StringKey[] { + return ["label.rgb.r", "label.rgb.g", "label.rgb.b"]; } constructInSocket(socketOptions: SocketOptions) { - return new InSocket(this, SocketType.VectorOrColor, "RGB or color", socketOptions).flag(SocketFlag.Rgb); + return new InSocket(this, SocketType.VectorOrColor, "label.socket.rgbOrColor", socketOptions).flag(SocketFlag.Rgb); } inSocketOptions(): SocketOptions { return { @@ -342,7 +346,7 @@ Color ${outColor} = Color(${outComponents}, ${newIlluminant}, ${node.webglCompon return cm.Xyz; } constructInSocket(socketOptions: SocketOptions) { - return new InSocket(this, SocketType.VectorOrColor, "XYZ or color", socketOptions); + return new InSocket(this, SocketType.VectorOrColor, "label.socket.xyzOrColor", socketOptions); } inSocketOptions(): SocketOptions { return { @@ -353,8 +357,8 @@ Color ${outColor} = Color(${outComponents}, ${newIlluminant}, ${node.webglCompon ], }; } - get componentLabels() { - return ["X", "Y", "Z"]; + get componentLabels(): StringKey[] { + return ["label.xyz.x", "label.xyz.y", "label.xyz.z"]; } webglXyzToComponents(inColor: WebglSlot, newIlluminant: WebglSlot) { return WebglTemplate.source`adaptXyz(${inColor}.xyz, ${inColor}.illuminant, ${newIlluminant})`; @@ -378,7 +382,7 @@ Color ${outColor} = Color(${outComponents}, ${newIlluminant}, ${node.webglCompon return cm.Xyy; } constructInSocket(socketOptions: SocketOptions) { - return new InSocket(this, SocketType.VectorOrColor, "xyY or color", socketOptions); + return new InSocket(this, SocketType.VectorOrColor, "label.socket.xyyOrColor", socketOptions); // ...(this.primariesSockets = [ // new InSocket(this, SocketType.Float, "x (chromaticity 1)", true, {defaultValue: d65[0]}), // new InSocket(this, SocketType.Float, "y (chromaticity 2)", true, {defaultValue: d65[1]}), @@ -395,8 +399,8 @@ Color ${outColor} = Color(${outComponents}, ${newIlluminant}, ${node.webglCompon ], }; } - get componentLabels() { - return ["x", "y", "Y"]; + get componentLabels(): StringKey[] { + return ["label.xyy.x", "label.xyy.y", "label.xyz.y"]; } webglXyzToComponents(inColor: WebglSlot, newIlluminant: WebglSlot) { return WebglTemplate.source`xyzToXyy(adaptXyz(${inColor}.xyz, ${inColor}.illuminant, ${newIlluminant}))`; @@ -408,7 +412,7 @@ Color ${outColor} = Color(${outComponents}, ${newIlluminant}, ${node.webglCompon export class LabNode extends TripletSpaceNode { static readonly TYPE = Symbol(this.name); - static readonly id = "lab"; + static readonly id = "cielab"; get displayLabels() { return ["L*", "a*", "b*"]; @@ -418,7 +422,7 @@ Color ${outColor} = Color(${outComponents}, ${newIlluminant}, ${node.webglCompon return cm.Lab; } constructInSocket(socketOptions: SocketOptions) { - return new InSocket(this, SocketType.VectorOrColor, "Lxy or color", socketOptions); + return new InSocket(this, SocketType.VectorOrColor, "label.socket.lxyOrColor", socketOptions); } inSocketOptions(): SocketOptions { return { @@ -426,8 +430,8 @@ Color ${outColor} = Color(${outComponents}, ${newIlluminant}, ${node.webglCompon sliderProps: labSliderProps, }; } - get componentLabels() { - return ["L*", "a*", "b*"]; + get componentLabels(): StringKey[] { + return ["label.cielxy.l", "label.cielab.a", "label.cielab.b"]; } webglXyzToComponents(inColor: WebglSlot, newIlluminant: WebglSlot) { return WebglTemplate.source`xyzToLab(${inColor}.xyz, ${inColor}.illuminant, ${newIlluminant})`; @@ -439,7 +443,7 @@ Color ${outColor} = Color(${outComponents}, ${newIlluminant}, ${node.webglCompon export class LuvNode extends TripletSpaceNode { static readonly TYPE = Symbol(this.name); - static readonly id = "luv"; + static readonly id = "cieluv"; get displayLabels() { return ["L*", "u*", "v*"]; @@ -449,7 +453,7 @@ Color ${outColor} = Color(${outComponents}, ${newIlluminant}, ${node.webglCompon return cm.Luv; } constructInSocket(socketOptions: SocketOptions) { - return new InSocket(this, SocketType.VectorOrColor, "Lxy or color", socketOptions); + return new InSocket(this, SocketType.VectorOrColor, "label.socket.lxyOrColor", socketOptions); } inSocketOptions(): SocketOptions { return { @@ -457,8 +461,8 @@ Color ${outColor} = Color(${outComponents}, ${newIlluminant}, ${node.webglCompon sliderProps: labSliderProps, }; } - get componentLabels() { - return ["L*", "u*", "v*"]; + get componentLabels(): StringKey[] { + return ["label.cielxy.l", "label.cieluv.u", "label.cieluv.v"]; } webglXyzToComponents(inColor: WebglSlot, newIlluminant: WebglSlot) { return WebglTemplate.source`xyzToLuv(${inColor}.xyz, ${inColor}.illuminant, ${newIlluminant})`; @@ -480,7 +484,7 @@ Color ${outColor} = Color(${outComponents}, ${newIlluminant}, ${node.webglCompon return cm.Oklab; } constructInSocket(socketOptions: SocketOptions) { - return new InSocket(this, SocketType.VectorOrColor, "Lxy or color", socketOptions); + return new InSocket(this, SocketType.VectorOrColor, "label.socket.lxyOrColor", socketOptions); } inSocketOptions(): SocketOptions { return { @@ -488,8 +492,8 @@ Color ${outColor} = Color(${outComponents}, ${newIlluminant}, ${node.webglCompon sliderProps: oklabSliderProps, }; } - get componentLabels() { - return ["L", "a", "b"]; + get componentLabels(): StringKey[] { + return ["label.lxy.l", "label.lab.a", "label.lab.b"]; } get includeWhitePoint() { diff --git a/src/models/nodetypes/util.ts b/src/models/nodetypes/util.ts index b91e25f..8ed3d87 100644 --- a/src/models/nodetypes/util.ts +++ b/src/models/nodetypes/util.ts @@ -28,36 +28,6 @@ export const useDynamicallyTypedSockets = ( } } - // let existingOutputSocket = outSocket.links[0]?.dst; - // while (existingOutputSocket && existingOutputSocket.hasDynamicType) { - // existingOutputSocket = existingOutputSocket.node.outs[0].links[0]?.dst; - // } - // const existingOutputType = existingOutputSocket?.type ?? SocketType.Any; - - - // let existingInputSocket = ins[0].links[0]?.src; - // while (existingInputSocket && existingInputSocket.hasDynamicType) { - // // TODO this assumes the position of a Dynamic-type socket, which is not necessarily true for future node types - // existingInputSocket = existingInputSocket.node.ins[0].links[0]?.src; - // } - // let newType: SocketType = existingInputSocket?.type; - - // // There could be more links on this socket - // if (!newType) { - // let existingOutputSocket = outs[0].links[0]?.dst; - // while (existingOutputSocket && existingOutputSocket.hasDynamicType) { - // existingOutputSocket = existingOutputSocket.node.outs[0].links[0]?.dst; - // } - // newType = existingOutputSocket?.type; - // } - - // newType ??= SocketType.Any; - - // for (const socket of syncedSockets()) { - // socket.changeType(newType, tree); - // } - - return mostRestrictiveType; }; @@ -98,34 +68,5 @@ export const useDynamicallyTypedSockets = ( }; -export const dynamicInSocketMapping = ({ - val, - illuminant, - xyz, -}: { - val: WebglSlot, - illuminant: WebglSlot, - xyz: WebglSlot, -}) => - (socket: InSocket) => () => { - switch (socket.effectiveType()) { - case SocketType.Float: - case SocketType.Integer: - case SocketType.Vector: - case SocketType.Bool: - return { - [webglOuts.val]: val, - }; - - case SocketType.VectorOrColor: - case SocketType.ColorComponents: - return { - [webglOuts.val]: val, - [webglOuts.illuminant]: illuminant, - [webglOuts.xyz]: xyz, - }; - - default: - return null; - } - }; \ No newline at end of file +export const dynamicInSocketMapping = ({val}: {val: WebglSlot}) => + (socket: InSocket) => () => ({[webglOuts.val]: val}); \ No newline at end of file diff --git a/src/strings.ts b/src/strings.ts index b2d4b1e..f62c34d 100644 --- a/src/strings.ts +++ b/src/strings.ts @@ -17,6 +17,35 @@ const strings = { "label.nodeCategory.models": "Models", "label.nodeCategory.spaces": "Spaces", + + "label.rgb": "RGB", + "label.hsl": "HSL", + "label.hsv": "HSV", + "label.hwb": "HWB", + "label.cmy": "CMY", + "label.lxy": "Lxy", + "label.lch": "LCh", + "label.xyz": "XYZ", + "label.xyy": "xyY", + + "label.rgb.r": "R", + "label.rgb.g": "G", + "label.rgb.b": "B", + "label.xyz.x": "X", + "label.xyz.y": "Y", + "label.xyz.z": "Z", + "label.xyy.x": "x", + "label.xyy.y": "y", + "label.cielxy.l": "L*", + "label.cielab.a": "a*", + "label.cielab.b": "b*", + "label.cieluv.u": "u*", + "label.cieluv.v": "v*", + "label.lxy.l": "l", + "label.lab.a": "a", + "label.lab.b": "b", + + "label.node.rgb": "RGB", "label.node.hsl": "HSL", "label.node.hsv": "HSV", @@ -33,8 +62,8 @@ const strings = { "label.node.linearSrgb": "Linear sRGB", "label.node.xyz": "XYZ", "label.node.xyy": "xyY", - "label.node.lab": "L\\*a\\*b\\*", - "label.node.luv": "L\\*u\\*v\\*", + "label.node.cielab": "L\\*a\\*b\\*", + "label.node.cieluv": "L\\*u\\*v\\*", "label.node.oklab": "Oklab", "label.node.linearAdobeRgb": "Linear Adobe RGB 1998", "label.node.adobeRgb": "Adobe RGB 1998", @@ -48,6 +77,9 @@ const strings = { "label.node.contrastRatio": "Contrast ratio", "label.node.randomFloat": "Random float", + "label.node.conditional": "Conditional", + "label.node.compareFloats": "Compare floats", + "label.node.gradient": "Gradient", "label.node.imageFile": "Image file", "label.node.sample": "Sample", @@ -57,14 +89,162 @@ const strings = { "label.node.imagePlot": "Image plot", "label.node.sampleHexCodes": "Sample hex codes", - "label.node.conditional": "Conditional", - "label.node.compareFloats": "Compare floats", - "label.node.reroute": "Reroute", + "label.socket.value": "Value", + "label.socket.vector": "Vector", "label.socket.color": "Color", + "label.socket.colors": "Colors", "label.socket.illuminant": "White point", + "label.socket.min": "Min", + "label.socket.max": "Max", + "label.socket.start": "Start", + "label.socket.end": "End", + "label.socket.alpha": "Alpha", + "label.socket.width": "Width", + "label.socket.height": "Height", + "label.socket.scalar": "Scalar", + "label.socket.x": "X", + "label.socket.y": "Y", + "label.socket.1": "1", + "label.socket.2": "2", + "label.socket.3": "3", + + "label.socket.red": "Red", + "label.socket.green": "Green", + "label.socket.blue": "Blue", + "label.socket.hue": "Hue", + "label.socket.saturation": "Saturation", + "label.socket.lightness": "Lightness", + "label.socket.hsv.value": "Value", + "label.socket.whiteness": "Whiteness", + "label.socket.blackness": "Blackness", + "label.socket.cyan": "Cyan", + "label.socket.magenta": "Magenta", + "label.socket.yellow": "Yellow", + "label.socket.colorfulness": "Colorfulness", + "label.socket.redGreen": "Red–green", + "label.socket.yellowBlue": "Yellow–blue", + + "label.socket.rgbOrColor": "RGB or color", + "label.socket.lxyOrColor": "Lxy or color", + "label.socket.xyyOrColor": "xyY or color", + "label.socket.xyzOrColor": "XYZ or color", + "label.socket.labOrColor": "L*a*b* or color", + "label.socket.vectorOrColor": "Vector or color", + + "label.socket.addOperand": "Addend", + "label.socket.multiplyOperand": "Factor", + "label.socket.subtractOperand1": "Minuend", + "label.socket.subtractOperand2": "Subtrahend", + "label.socket.divideOperand1": "Dividend", + "label.socket.divideOperand2": "Divisor", + "label.socket.addOut": "Sum", + "label.socket.multiplyOut": "Product", + "label.socket.subtractOut": "Difference", + "label.socket.divideOut": "Quotient", + "label.socket.blendAmount": "Blend amount", + "label.socket.cmfDataset": "Color-matching function dataset", + "label.socket.wavelength": "Wavelength (nm)", + "label.socket.normalizeCoordinates": "Normalize coordinates", + + "label.overload.lerp": "Lerp", + "label.overload.add": "Add", + "label.overload.subtract": "Subtract", + "label.overload.screen": "Screen", + + + "label.overload.toRgb": "To RGB", + "label.overload.fromRgb": "From RGB", + "label.overload.toLxy": "To Lxy", + "label.overload.fromLxy": "From Lxy", + "label.socket.wavelength.relativePower": "Relative power", + "label.socket.blackbody.temperature": "Temperature (K)", + + "label.overload.fromVector": "From vector", + "label.overload.fromValues": "From values", + + "label.overload.vectorArithmetic.componentwiseMultiply": "Componentwise multiply", + "label.overload.vectorArithmetic.componentwiseDivide": "Componentwise divide", + "label.overload.vectorArithmetic.scalarMultiply": "Scalar multiply", + "label.overload.vectorArithmetic.distance": "Distance", + "label.socket.vectorArithmetic.distance": "Distance", + "label.overload.arithmetic.multiply": "Multiply", + "label.overload.arithmetic.divide": "Divide", + "label.overload.arithmetic.power": "Power", + "label.socket.arithmetic.powerBase": "Base", + "label.socket.arithmetic.powerExponent": "Exponent", + "label.socket.arithmetic.powerOut": "Power", + "label.overload.arithmetic.mapRange": "Map range", + "label.socket.arithmetic.mapRange.sourceValue": "Source value", + "label.socket.arithmetic.mapRange.sourceMin": "Source min", + "label.socket.arithmetic.mapRange.sourceMax": "Source max", + "label.socket.arithmetic.mapRange.targetMin": "Target min", + "label.socket.arithmetic.mapRange.targetMax": "Target max", + "label.overload.arithmetic.floor": "Floor", + "label.overload.arithmetic.sine": "Sine", + "label.overload.arithmetic.cosine": "Cosine", + "label.overload.arithmetic.tangent": "Tangent", + "label.overload.arithmetic.arcsine": "Arcsine", + "label.overload.arithmetic.arccosine": "Arccosine", + "label.overload.arithmetic.arctangent": "Arctangent", + "label.overload.arithmetic.arctangent2": "Two-argument arctangent", + "label.overload.arithmetic.hypotenuse": "Hypotenuse", + "label.socket.arithmetic.hypotenuse": "Hypotenuse", + "label.overload.arithmetic.quantize": "Quantize", + "label.socket.arithmetic.quantize.nSegments": "# segments", + "label.overload.colorDifference.deltaE1976": "ΔE* 1976", + "label.overload.colorDifference.deltaE2000": "ΔE* 2000", + "label.socket.colorDifference.difference": "Difference", + "label.socket.colorDifference.sampleLabOrColor": "Sample L*a*b* or color", + "label.socket.colorDifference.targetLabOrColor": "Target L*a*b* or color", + "label.socket.contrastRatio.ratio": "Ratio", + "label.socket.contrastRatio.aaaBody?": "Passes AAA body text?", + "label.socket.contrastRatio.aaaLarge?": "Passes AAA large text?", + "label.socket.contrastRatio.aaBody?": "Passes AA body text?", + "label.socket.contrastRatio.aaLarge?": "Passes AA large text?", + "label.socket.contrastRatio.aaUi?": "Passes AA graphical elements?", + "label.overload.randomFloat.floatSeed": "Float seed", + "label.overload.randomFloat.vectorSeed": "Vector seed", + "label.socket.randomFloat.integersOnly?": "Integers only?", + "label.socket.randomFloat.seed": "Seed", + + "label.socket.gradient.axis": "Axis", + "label.socket.gradient.from": "From", + "label.socket.gradient.to": "To", + "label.socket.gradient.values": "Values", + "label.socket.imageFile.file": "File", + "label.socket.sample.source": "Source", + + "label.overload.cssOutput.rgbVector": "RGB vector", + "label.overload.cssOutput.color": "Color", + "label.overload.chromaticityPlot.fromColor": "From colors", + "label.overload.chromaticityPlot.fromXy": "From xy", + + + "label.cmfDataset.2deg": "CIE 2° observer (1931)", + "label.cmfDataset.10deg": "CIE 10° observer (1964)", + + "label.standardIlluminant.2deg.a": "CIE 2° / A", + "label.standardIlluminant.2deg.b": "CIE 2° / B", + "label.standardIlluminant.2deg.c": "CIE 2° / C", + "label.standardIlluminant.2deg.d50": "CIE 2° / D50", + "label.standardIlluminant.2deg.d55": "CIE 2° / D55", + "label.standardIlluminant.2deg.d60": "CIE 2° / D60", + "label.standardIlluminant.2deg.d65": "CIE 2° / D65", + "label.standardIlluminant.2deg.d75": "CIE 2° / D75", + "label.standardIlluminant.2deg.e": "CIE 2° / E", + "label.standardIlluminant.10deg.a": "CIE 10° / A", + "label.standardIlluminant.10deg.b": "CIE 10° / B", + "label.standardIlluminant.10deg.c": "CIE 10° / C", + "label.standardIlluminant.10deg.d50": "CIE 10° / D50", + "label.standardIlluminant.10deg.d55": "CIE 10° / D55", + "label.standardIlluminant.10deg.d60": "CIE 10° / D60", + "label.standardIlluminant.10deg.d65": "CIE 10° / D65", + "label.standardIlluminant.10deg.d75": "CIE 10° / D75", + "label.standardIlluminant.10deg.e": "CIE 10° / E", + "label.button.deleteNodes": "Delete selected nodes", @@ -73,7 +253,7 @@ const strings = { "desc.node.hsv": "Describes RGB colors by their hue, saturation, and value/brightness.", "desc.node.hwb": "Describes RGB colors by their hue, whiteness, and blackness.", "desc.node.cmy": "Describes RGB colors by subtracting amounts of their opposites (cyan, yellow, and magenta).", - "desc.node.lxy": "Describes colors by their lightness and two chroma axes, x (red–green) and y (yellow–blue), which come from human opponent-process color vision.", + "desc.node.lxy": "Describes colors by their lightness and two chroma axes, x (red–green) and y (yellow–blue), which are derived from human opponent-process color vision.", "desc.node.lch": "A variant of Lxy that uses hue (h) and colorfulness (C) to define colors, similar to HSL.", "desc.node.vector": "A general set of three numbers, for input to color spaces.", "desc.node.spectralPowerDistribution": "Describes colors by the range of wavelengths that make them up.", @@ -90,14 +270,24 @@ const strings = { "desc.node.splitVector": "Accesses the individual components of a vector or color.", "desc.node.contrastRatio": "Compares the relative luminance between two colors.", + "desc.node.conditional": "Selects one of two values depending on whether a condition is true.", + "desc.node.compareFloats": "Outputs the result of a comparison between two numbers.", + "desc.node.gradient": "Generates a range of numbers.", "desc.node.imageFile": "Reads RGB data from a local image file.", "desc.node.sample": "Samples data from a single point in an image.", "desc.node.cssOutput": "CSS formats for an RGB color.", + "desc.socket.illuminant": `The chromaticity of the color “white”, or often the color of the light that illuminates an environment. Human eyes will adjust under different viewing circumstances, so different chromaticities and hues could be considered “white” (chromatic adaptation / white balance).[1]

${cite(1, "https://yuhaozhu.com/blog/chromatic-adaptation.html", "https://web.archive.org/web/20240226042830/https://yuhaozhu.com/blog/chromatic-adaptation.html")}`, + "desc.socket.imageFileRgb": "The RGB color data from the image file.", + "desc.socket.imageFileAlpha": "The color transparency information from the image file.", + "desc.socket.imageFileWidth": "The width of the image file.", + "desc.socket.imageFileHeight": "The height of the image file.", + + "desc.field.rgb.r": "**R**: Red light.", "desc.field.rgb.g": "**G**: Green light.", "desc.field.rgb.b": "**B**: Blue light.", @@ -137,6 +327,10 @@ const strings = { "desc.socketType.any.in": "This socket accepts any data type.", "desc.socketType.any.out": "The data type of this socket is not yet known. It will likely depend on the data type of one of the input sockets.", "label.socketType.unknown": "Unknown", + + "label.socketAttr.constant": "**Constant**", + "desc.socketAttr.constant.in": "If the input data to this socket is an image rather than a single value, this socket will always only use one value from the input data.", + "desc.socketAttr.constant.out": "This socket's outptut data will always only consist of a single value rather than an image, regardless of the inputs.", "error.import": "**Error occurred while importing tree**: ", "error.import.unknownNodeType": "Node type \"`{0}`\" does not exist.",