diff --git a/src/graph/nodes/colors/ColorRampNode.ts b/src/graph/nodes/colors/ColorRampNode.ts index 61d53b7..f39154e 100644 --- a/src/graph/nodes/colors/ColorRampNode.ts +++ b/src/graph/nodes/colors/ColorRampNode.ts @@ -1,7 +1,8 @@ import { markRaw } from "vue"; import { NodeInterface, defineNode } from "baklavajs"; import { ColorArrayInterface, ColorSingleInterface, SliderInterface } from "../../interfaces"; -import { Color } from "../../colors"; +import { Color, mix } from "../../colors"; +import { LmsCalculationContext } from "../../types"; import ColorRampOption from "../../options/ColorRampOption.vue"; export interface ColorRampStop { @@ -11,7 +12,7 @@ export interface ColorRampStop { } export interface ColorRampValue { - mode: "RGB" | "HSV" | "HSL"; + mode: "rgb" | "hsl"; stops: ColorRampStop[]; } @@ -19,7 +20,7 @@ export const ColorRampNode = defineNode({ type: "Color Ramp", inputs: { colorRamp: () => - new NodeInterface("Color Ramp", { mode: "RGB", stops: [] }) + new NodeInterface("Color Ramp", { mode: "rgb", stops: [] }) .setPort(false) .setComponent(markRaw(ColorRampOption)), factor: () => new SliderInterface("Factor", 0.5, 0, 1), @@ -28,4 +29,43 @@ export const ColorRampNode = defineNode({ colorRamp: () => new ColorArrayInterface("Color Ramp"), value: () => new ColorSingleInterface("Value").setComponent(null), }, + calculate({ colorRamp, factor }, ctx: LmsCalculationContext) { + if (colorRamp.stops.length === 0) { + return { + colorRamp: [[0, 0, 0]] as Color[], + value: [0, 0, 0] as Color, + }; + } else if (colorRamp.stops.length === 1) { + return { + colorRamp: [colorRamp.stops[0].color], + value: colorRamp.stops[0].color, + }; + } + + const stops = colorRamp.stops.sort((a, b) => a.position - b.position); + + function getColorAtPosition(position: number) { + const nextStopIndex = stops.findIndex((stop) => stop.position > position); + if (nextStopIndex === -1) { + return stops[stops.length - 1].color; + } else if (nextStopIndex === 0) { + return stops[0].color; + } + const prevStop = stops[nextStopIndex - 1]; + const nextStop = stops[nextStopIndex]; + const f = (position - prevStop.position) / (nextStop.position - prevStop.position); + return mix(prevStop.color, nextStop.color, f, colorRamp.mode); + } + + const ramp: Color[] = []; + for (let i = 0; i < ctx.globalValues.resolution; i++) { + const position = i / (ctx.globalValues.resolution - 1); + ramp.push(getColorAtPosition(position)); + } + + return { + colorRamp: ramp, + value: getColorAtPosition(Math.max(0, Math.min(1, factor))), + }; + }, }); diff --git a/src/graph/options/ColorRampOption.vue b/src/graph/options/ColorRampOption.vue index 25bc47d..41032ad 100644 --- a/src/graph/options/ColorRampOption.vue +++ b/src/graph/options/ColorRampOption.vue @@ -3,17 +3,18 @@
-
+
@@ -24,18 +25,30 @@