diff --git a/.vscode/settings.json b/.vscode/settings.json index 4c6d477..e6cf923 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,5 @@ { "editor.tabSize": 4, - "rust-analyzer.linkedProjects": ["lms_bridge\\Cargo.toml"] + "rust-analyzer.linkedProjects": ["lms_bridge\\Cargo.toml"], + "typescript.tsdk": "node_modules\\typescript\\lib" } diff --git a/src/graph/nodes/effects/RepeatNode.ts b/src/graph/nodes/effects/RepeatNode.ts new file mode 100644 index 0000000..f54b15b --- /dev/null +++ b/src/graph/nodes/effects/RepeatNode.ts @@ -0,0 +1,28 @@ +import { defineNode } from "@baklavajs/core"; +import { scaleColorArray } from "@/utils"; +import { LmsCalculationContext } from "../../types"; +import { ColorArrayInterface, IntegerInterface } from "../../interfaces"; +import { Color } from "../../colors"; + +export const RepeatNode = defineNode({ + type: "Repeat", + inputs: { + colors: () => new ColorArrayInterface("Input", []), + amount: () => new IntegerInterface("Amount", 4, 1), + }, + outputs: { + colors: () => new ColorArrayInterface("Value", []), + }, + calculate(inputs, context: LmsCalculationContext) { + const { colors, amount } = inputs; + const part = scaleColorArray(colors, Math.floor(context.globalValues.resolution / amount)); + const outputColors: Color[] = []; + for (let i = 0; i < amount; i++) { + outputColors.push(...part); + } + while (outputColors.length < context.globalValues.resolution) { + outputColors.push([0, 0, 0]); + } + return { colors: outputColors }; + }, +}); diff --git a/src/graph/nodes/effects/StrobeNode.ts b/src/graph/nodes/effects/StrobeNode.ts new file mode 100644 index 0000000..83ff10e --- /dev/null +++ b/src/graph/nodes/effects/StrobeNode.ts @@ -0,0 +1,36 @@ +import { defineNode } from "@baklavajs/core"; +import { SelectInterface } from "@baklavajs/renderer-vue"; +import { TICKS_PER_BEAT } from "@/constants"; +import { LmsCalculationContext } from "../../types"; +import { ColorArrayInterface } from "../../interfaces"; +import { Color } from "../../colors"; + +const rates = [ + { text: "1/8 Beat", value: TICKS_PER_BEAT / 8 }, + { text: "1/6 Beat", value: TICKS_PER_BEAT / 6 }, + { text: "1/4 Beat", value: TICKS_PER_BEAT / 4 }, + { text: "1/3 Beat", value: TICKS_PER_BEAT / 3 }, + { text: "1/2 Beat", value: TICKS_PER_BEAT / 2 }, + { text: "1 Beat", value: TICKS_PER_BEAT }, + { text: "2 Beats", value: 2 * TICKS_PER_BEAT }, + { text: "4 Beats", value: 4 * TICKS_PER_BEAT }, + { text: "8 Beats", value: 8 * TICKS_PER_BEAT }, +]; + +export const StrobeNode = defineNode({ + type: "Strobe", + inputs: { + colors: () => new ColorArrayInterface("Input", []), + rate: () => new SelectInterface("Rate", TICKS_PER_BEAT / 2, rates).setPort(false), + }, + outputs: { + colors: () => new ColorArrayInterface("Value", []), + }, + calculate(inputs, context: LmsCalculationContext) { + const { colors, rate } = inputs; + const x = (context.globalValues.position % rate) / rate; + const v = Math.sin(Math.PI * 2 * x) >= 0 ? 1 : 0; + const outputColors = colors.map((color) => color.map((c) => c * v)) as Color[]; + return { colors: outputColors }; + }, +}); diff --git a/src/graph/nodes/effects/index.ts b/src/graph/nodes/effects/index.ts index 5e580df..fc58462 100644 --- a/src/graph/nodes/effects/index.ts +++ b/src/graph/nodes/effects/index.ts @@ -1,4 +1,6 @@ export * from "./AfterglowNode"; export * from "./MirrorNode"; +export * from "./RepeatNode"; export * from "./RotateNode"; export * from "./SplitNode"; +export * from "./StrobeNode";