From 7456b703cebae265bae632df0fef1f0089f2b41e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9is=20Bazin?= Date: Fri, 17 Sep 2021 18:50:34 +0200 Subject: [PATCH 01/12] :memo: Initial TypeScript type declarations :tada: Initial working types implementation :fire: Remove unused import --- dist/types/components/buttontemplate.d.ts | 55 ++++++++ dist/types/components/rangeslider.d.ts | 39 ++++++ dist/types/components/slidertemplate.d.ts | 66 ++++++++++ dist/types/core/interface.d.ts | 96 ++++++++++++++ dist/types/core/rack.d.ts | 10 ++ dist/types/index.d.ts | 128 +++++++++++++++++++ dist/types/interfaces/button.d.ts | 46 +++++++ dist/types/interfaces/dial.d.ts | 105 ++++++++++++++++ dist/types/interfaces/envelope.d.ts | 132 +++++++++++++++++++ dist/types/interfaces/index.d.ts | 22 ++++ dist/types/interfaces/meter.d.ts | 52 ++++++++ dist/types/interfaces/multislider.d.ts | 130 +++++++++++++++++++ dist/types/interfaces/number.d.ts | 86 +++++++++++++ dist/types/interfaces/oscilloscope.d.ts | 45 +++++++ dist/types/interfaces/pan.d.ts | 64 ++++++++++ dist/types/interfaces/pan2d.d.ts | 98 +++++++++++++++ dist/types/interfaces/piano.d.ts | 88 +++++++++++++ dist/types/interfaces/position.d.ts | 131 +++++++++++++++++++ dist/types/interfaces/radiobutton.d.ts | 59 +++++++++ dist/types/interfaces/select.d.ts | 65 ++++++++++ dist/types/interfaces/sequencer.d.ts | 147 ++++++++++++++++++++++ dist/types/interfaces/slider.d.ts | 94 ++++++++++++++ dist/types/interfaces/spectrogram.d.ts | 45 +++++++ dist/types/interfaces/textbutton.d.ts | 57 +++++++++ dist/types/interfaces/tilt.d.ts | 57 +++++++++ dist/types/interfaces/toggle.d.ts | 56 +++++++++ dist/types/models/counter.d.ts | 33 +++++ dist/types/models/drunk.d.ts | 15 +++ dist/types/models/matrix.d.ts | 52 ++++++++ dist/types/models/radio.d.ts | 12 ++ dist/types/models/range.d.ts | 50 ++++++++ dist/types/models/sequence.d.ts | 25 ++++ dist/types/models/step.d.ts | 38 ++++++ dist/types/models/toggle.d.ts | 7 ++ dist/types/time/interval.d.ts | 16 +++ dist/types/tuning/tuning.d.ts | 22 ++++ dist/types/util/cssparse.d.ts | 1 + dist/types/util/dom.d.ts | 19 +++ dist/types/util/interaction.d.ts | 48 +++++++ dist/types/util/math.d.ts | 37 ++++++ dist/types/util/svg.d.ts | 10 ++ dist/types/util/touch.d.ts | 1 + dist/types/util/transform.d.ts | 3 + dist/types/util/util.d.ts | 2 + 44 files changed, 2364 insertions(+) create mode 100644 dist/types/components/buttontemplate.d.ts create mode 100644 dist/types/components/rangeslider.d.ts create mode 100644 dist/types/components/slidertemplate.d.ts create mode 100644 dist/types/core/interface.d.ts create mode 100644 dist/types/core/rack.d.ts create mode 100644 dist/types/index.d.ts create mode 100644 dist/types/interfaces/button.d.ts create mode 100644 dist/types/interfaces/dial.d.ts create mode 100644 dist/types/interfaces/envelope.d.ts create mode 100644 dist/types/interfaces/index.d.ts create mode 100644 dist/types/interfaces/meter.d.ts create mode 100644 dist/types/interfaces/multislider.d.ts create mode 100644 dist/types/interfaces/number.d.ts create mode 100644 dist/types/interfaces/oscilloscope.d.ts create mode 100644 dist/types/interfaces/pan.d.ts create mode 100644 dist/types/interfaces/pan2d.d.ts create mode 100644 dist/types/interfaces/piano.d.ts create mode 100644 dist/types/interfaces/position.d.ts create mode 100644 dist/types/interfaces/radiobutton.d.ts create mode 100644 dist/types/interfaces/select.d.ts create mode 100644 dist/types/interfaces/sequencer.d.ts create mode 100644 dist/types/interfaces/slider.d.ts create mode 100644 dist/types/interfaces/spectrogram.d.ts create mode 100644 dist/types/interfaces/textbutton.d.ts create mode 100644 dist/types/interfaces/tilt.d.ts create mode 100644 dist/types/interfaces/toggle.d.ts create mode 100644 dist/types/models/counter.d.ts create mode 100644 dist/types/models/drunk.d.ts create mode 100644 dist/types/models/matrix.d.ts create mode 100644 dist/types/models/radio.d.ts create mode 100644 dist/types/models/range.d.ts create mode 100644 dist/types/models/sequence.d.ts create mode 100644 dist/types/models/step.d.ts create mode 100644 dist/types/models/toggle.d.ts create mode 100644 dist/types/time/interval.d.ts create mode 100644 dist/types/tuning/tuning.d.ts create mode 100644 dist/types/util/cssparse.d.ts create mode 100644 dist/types/util/dom.d.ts create mode 100644 dist/types/util/interaction.d.ts create mode 100644 dist/types/util/math.d.ts create mode 100644 dist/types/util/svg.d.ts create mode 100644 dist/types/util/touch.d.ts create mode 100644 dist/types/util/transform.d.ts create mode 100644 dist/types/util/util.d.ts diff --git a/dist/types/components/buttontemplate.d.ts b/dist/types/components/buttontemplate.d.ts new file mode 100644 index 00000000..5664373a --- /dev/null +++ b/dist/types/components/buttontemplate.d.ts @@ -0,0 +1,55 @@ +import Interface from "../core/interface"; +import ToggleModel from "../models/toggle"; +import { XYPosition } from "../util/interaction"; + +type ButtonMode = "button" | "impulse" | "toggle" | "aftertouch"; +type ButtonTemplateOptions = { + mode: ButtonMode; + state: boolean; +}; + +/** +Button Template +*/ +export default class ButtonTemplate< + T extends ButtonTemplateOptions +> extends Interface { + /** + * Interaction mode: supports "button", "aftertouch", "impulse", or "toggle" + * @type {string} + * @example button.mode = 'toggle'; + */ + mode: ButtonMode; + position: XYPosition; + _state: ToggleModel; + pad: SVGElement; + interactionTarget: typeof this.pad; + render(): void; + up(): void; + bend(mouse: XYPosition): void; + down(paintbrush?: boolean): void; + timeout?: number; + set state(arg: boolean); + /** + Whether the button is on (pressed) or off (not pressed) + @type {boolean} + @example button.state = true; + */ + get state(): boolean; + /** + Change the button to its alternate state (off=>on, on=>off), or flip it to a specified state. + @param value {boolean} (Optional) State to flip to. + @example button.flip(); + */ + flip(value?: boolean): void; + /** + Turn the button's state to true. + @example button.turnOn(); + */ + turnOn(emitting?: boolean): void; + /** + Turn the button's state to false. + @example button.turnOff(); + */ + turnOff(emitting?: boolean): void; +} diff --git a/dist/types/components/rangeslider.d.ts b/dist/types/components/rangeslider.d.ts new file mode 100644 index 00000000..40d77291 --- /dev/null +++ b/dist/types/components/rangeslider.d.ts @@ -0,0 +1,39 @@ +import Interface from "../core/interface"; +import Range, { RangeOptions } from "../models/range"; +import * as Interaction from "../util/interaction"; + +type RangeSliderMode = "select" | "drag"; + +type RangeSliderOptions = RangeOptions & { + mode: RangeSliderMode; +}; + +export default class RangeSlider extends Interface { + min: number; + max: number; + step: boolean; + mode: number; + range: Range; + position: + | { + center: Interaction.Handle; + size: Interaction.Handle; + } + | { + center: Interaction.Handle; + start: Interaction.Handle; + end: Interaction.Handle; + }; + dummy: SVGRectElement; + ref: SVGGElement; + bar: SVGRect; + arrowL: SVGRectElement; + arrowR: SVGRectElement; + render(): void; + hasMoved?: boolean; + set start(value: number); + get start(): number; + set end(value: number); + get end(): number; + updatePosition(): void; +} diff --git a/dist/types/components/slidertemplate.d.ts b/dist/types/components/slidertemplate.d.ts new file mode 100644 index 00000000..fce32f18 --- /dev/null +++ b/dist/types/components/slidertemplate.d.ts @@ -0,0 +1,66 @@ +import Interface, { InterfaceOptions } from "../core/interface"; +import Step from "../models/step"; +import * as Interaction from "../util/interaction"; +import { HandleMode } from "../util/interaction"; + +export type SliderOrientation = "vertical" | "horizontal"; + +type SliderTemplateOptions = { + orientation: SliderOrientation; + hasKnob: boolean; +}; + +export default class SliderTemplate extends Interface { + orientation: SliderOrientation; + hasKnob: boolean; + _value: Step; + position: Interaction.Handle; + set value(value: number); + /** + The slider's current value. If set manually, will update the interface and trigger the output event. + @type {number} + @example slider.value = 10; + */ + get value(): number; + bar: any; + fillbar: any; + knob: any; + knobData: { + level: number; + r: number; + }; + thickness: number; + render(): void; + down(): void; + slide(): void; + up(): void; + get normalized(): number; + set min(value: number); + /** + Lower limit of the sliders's output range + @type {number} + @example slider.min = 1000; + */ + get min(): number; + set max(value: number); + /** + Upper limit of the slider's output range + @type {number} + @example slider.max = 1000; + */ + get max(): number; + set step(value: number); + /** + The increment that the slider's value changes by. + @type {number} + @example slider.step = 5; + */ + get step(): number; + set mode(mode: HandleMode); + /** + Absolute mode (slider's value jumps to mouse click position) or relative mode (mouse drag changes value relative to its current position). Default: "relative". + @type {string} + @example slider.mode = "relative"; + */ + get mode(): HandleMode; +} diff --git a/dist/types/core/interface.d.ts b/dist/types/core/interface.d.ts new file mode 100644 index 00000000..7cc989a0 --- /dev/null +++ b/dist/types/core/interface.d.ts @@ -0,0 +1,96 @@ +import EventEmitter from "events"; +import { XYPosition } from "../util/interaction"; + +type InterfaceColorTarget = + | "accent" + | "fill" + | "light" + | "dark" + | "mediumLight" + | "mediumDark"; + +type BaseInterfaceOptions = { + size: [number, number]; + target: HTMLElement; + colors: {}; + snapWithParent: boolean; + event: () => void; + component: boolean; +}; +/** +Interface +*/ +export default class Interface extends EventEmitter { + constructor( + parent: HTMLElement | string, + options?: Partial + ); + constructor( + args?: any, + options?: (keyof InterfaceSpecificOptions)[], + defaults?: Partial + ); + type: string; + width: number; + height: number; + settings: BaseInterfaceOptions; + colors: { [colorTarget in InterfaceColorTarget]: string }; + parseSettings( + args: any, + options: (keyof InterfaceSpecificOptions)[], + defaults: Partial + ): Partial; + parent: string | HTMLElement | SVGElement | undefined; + element: HTMLElement; + interactionTarget: HTMLElement | SVGElement; + event: boolean | (() => void); + init(): void; + wait: boolean; + mouse: XYPosition | {}; + buildFrame(): void; + buildInterface(): void; + sizeInterface(): void; + colorInterface(): void; + attachListeners(): void; + boundPreMove: ((evt: MouseEvent) => void) | undefined; + boundPreRelease: ((evt: MouseEvent) => void) | undefined; + finalTouches(): void; + preClick(e: MouseEvent): void; + offset?: { + top: any; + left: any; + }; + clicked?: boolean; + moveEvent?: void; + releaseEvent?: void; + preMove(e: MouseEvent): void; + preRelease(e: MouseEvent): void; + click(): void; + move(): void; + release(): void; + preTouch(e: MouseEvent): void; + preTouchMove(e: MouseEvent): void; + preTouchRelease(e: MouseEvent): void; + touch(): void; + touchMove(): void; + touchRelease(): void; + /** + * Resize the interface + * @param width {number} New width in pixels + * @param height {number} New height in pixels + * + * @example + * button.resize(100,100); + */ + resize(width: number, height: number): void; + empty(): void; + /** + * Remove the interface from the page and cancel its event listener(s). + * + * @example + * button.destroy(); + */ + destroy(): void; + customDestroy(): void; + colorize(type: string, color: string): void; +} diff --git a/dist/types/core/rack.d.ts b/dist/types/core/rack.d.ts new file mode 100644 index 00000000..af1c7b4a --- /dev/null +++ b/dist/types/core/rack.d.ts @@ -0,0 +1,10 @@ +export default class Rack { + constructor(target: any, settings: any); + meta: {}; + buildInterface(): void; + colorInterface(): void; + show(): void; + hide(): void; + colorize(type: any, color: any): void; + empty(): void; +} diff --git a/dist/types/index.d.ts b/dist/types/index.d.ts new file mode 100644 index 00000000..02491fd7 --- /dev/null +++ b/dist/types/index.d.ts @@ -0,0 +1,128 @@ +import Tune from "./tuning/tuning"; +import Interval from "./time/interval"; +import * as Transform from "./util/transform"; + +import Slider from "./interfaces/slider"; +import Position from "./interfaces/position"; + +import Radio from "./models/radio"; +import Counter from "./models/counter"; +import Drunk from "./models/drunk"; +import Sequence from "./models/sequence"; +import Matrix from "./models/matrix"; + +import Toggle from "./interfaces/toggle"; +import Button from "./interfaces/button"; +import TextButton from "./interfaces/textbutton"; +import RadioButton from "./interfaces/radiobutton"; +import Number from "./interfaces/number"; +import Select from "./interfaces/select"; +import Dial from "./interfaces/dial"; +import Piano from "./interfaces/piano"; +import Sequencer from "./interfaces/sequencer"; +import Pan2D from "./interfaces/pan2d"; +import Tilt from "./interfaces/tilt"; +import Multislider from "./interfaces/multislider"; +import Pan from "./interfaces/pan"; +import Envelope from "./interfaces/envelope"; +import Spectrogram from "./interfaces/spectrogram"; +import Meter from "./interfaces/meter"; +import Oscilloscope from "./interfaces/oscilloscope"; + +import WAAClock from "waaclock"; +import Interface from "./core/interface"; +import type { InterfaceColorTarget } from "./core/interface"; + +export function colors(): { + [colorTarget in InterfaceColorTarget]: string; +}; +export function context(): any; +export function clock(): any; +declare let Nexus: NexusUI; +/** +NexusUI => created as Nexus +*/ +declare class NexusUI { + constructor(context?: AudioContext); + _context: AudioContext; + tune: Tune; + note: (input: number, octave: number) => number; + clock: WAAClock; + Interval: typeof Interval; + colors: { + [colorTarget in InterfaceColorTarget]: string; + }; + transform: typeof Transform; + add: (type: string, parent: HTMLElement, options: any) => Interface; + Add: {}; + set context(arg: AudioContext); + get context(): AudioContext; + + Matrix: typeof Matrix; + Counter: typeof Counter; + Radio: typeof Radio; + Drunk: typeof Drunk; + Sequence: typeof Sequence; + + Position: typeof Position; + Slider: typeof Slider; + Toggle: typeof Toggle; + Button: typeof Button; + TextButton: typeof TextButton; + RadioButton: typeof RadioButton; + Number: typeof Number; + Select: typeof Select; + Dial: typeof Dial; + Piano: typeof Piano; + Sequencer: typeof Sequencer; + Pan: typeof Pan; + Pan2D: typeof Pan2D; + Tilt: typeof Tilt; + Multislider: typeof Multislider; + + Envelope: typeof Envelope; + Spectrogram: typeof Spectrogram; + Meter: typeof Meter; + Oscilloscope: typeof Oscilloscope; +} + +export default Nexus; +export as namespace Nexus; + +/* HACK(@tbazin, 2021/08/04): re-export classes as types for usage as typing hints + + Should ideally switch Nexus to a structure similar to Tone.js, where the library + is imported as: + import * as Tone from 'tone' + and Tone is therefore a namespace rather than a global constant. + In that setup classes/types are readily accessible as e.g. Tone.Transport. + The global variables (for color and context management) would then have to + be loaded directly within each class constructor independently. +*/ +export type NexusMatrix = Matrix; +export type NexusCounter = Counter; +export type NexusRadio = Radio; +export type NexusDrunk = Drunk; +export type NexusSequence = Sequence; +export type NexusPosition = Position; +export type NexusSlider = Slider; +export type NexusToggle = Toggle; +export type NexusButton = Button; +export type NexusTextButton = TextButton; +export type NexusRadioButton = RadioButton; +export type NexusNumber = Number; +export type NexusSelect = Select; +export type NexusDial = Dial; +export type NexusPiano = Piano; +export type NexusSequencer = Sequencer; +export type NexusPan = Pan; +export type NexusPan2D = Pan2D; +export type NexusTilt = Tilt; +export type NexusMultislider = Multislider; +export type NexusEnvelope = Envelope; +export type NexusSpectrogram = Spectrogram; +export type NexusMeter = Meter; +export type NexusOscilloscope = Oscilloscope; + +export { MatrixPattern, MatrixValue } from "./models/matrix"; +export { MatrixCell } from "./interfaces/sequencer"; diff --git a/dist/types/interfaces/button.d.ts b/dist/types/interfaces/button.d.ts new file mode 100644 index 00000000..2eb1bb02 --- /dev/null +++ b/dist/types/interfaces/button.d.ts @@ -0,0 +1,46 @@ +import ButtonTemplate, { + ButtonTemplateOptions, +} from "../components/buttontemplate"; +import { XYPosition } from "../util/interaction"; + +/** + * Button + * + * @description Circular button with optional aftertouch. + * + * @demo + * + * @example + * var button = new Nexus.Button('#target') + * + * @example + * var button = new Nexus.Button('#target',{ + * 'size': [80,80], + * 'mode': 'aftertouch', + * 'state': false + * }) + * + * @output + * change + * Fires any time the interface's value changes.
+ * In button mode, toggle mode, and impulse mode, the output data is a boolean describing the state of the button.
+ * In aftertouch mode, the output data is an object containing x (0-1) and y (0-1) positions of aftertouch. + * + * @outputexample + * button.on('change',function(v) { + * // v is the value of the button + * console.log(v); + * }) + * + */ +export default class Button extends ButtonTemplate { + on( + event: "change", + listener: (value: boolean | XYPosition, ...args: any[]) => void + ): this; + pad: SVGCircleElement; + interactionTarget: typeof this.pad; + defs: SVGDefsElement; + gradient: SVGRadialGradientElement; + render(): void; +} diff --git a/dist/types/interfaces/dial.d.ts b/dist/types/interfaces/dial.d.ts new file mode 100644 index 00000000..0e38b583 --- /dev/null +++ b/dist/types/interfaces/dial.d.ts @@ -0,0 +1,105 @@ +import Interface, { InterfaceOptions } from "../core/interface"; +import * as Interaction from "../util/interaction"; +import { HandleDirection, HandleMode } from "../util/interaction"; +import Step, { StepOptions } from "../models/step"; + +type DialInteraction = HandleDirection; + +type DialOptions = StepOptions & { + interaction: DialInteraction; + mode: HandleMode; +}; +/** + * Dial + * + * + * @description Dial with radial or linear interaction. + * + * @demo + * + * @example + * var dial = new Nexus.Dial('#target') + * + * @example + * var dial = new Nexus.Dial('#target',{ + * 'size': [75,75], + * 'interaction': 'radial', // "radial", "vertical", or "horizontal" + * 'mode': 'relative', // "absolute" or "relative" + * 'min': 0, + * 'max': 1, + * 'step': 0, + * 'value': 0 + * }) + * + * @output + * change + * Fires any time the interface's value changes.
+ * The event data is the number value of the interface. + * + * @outputexample + * dial.on('change',function(v) { + * console.log(v); + * }) + * + * @tutorial + * Dial + * ygGMxq + * + */ +export default class Dial extends Interface { + on(event: "change", listener: (value: number, ...args: any[]) => void): this; + interaction: DialInteraction; + _value: Step; + position: Interaction.Handle; + set value(arg: number); + /** + Dial's value. When set, it will automatically be adjust to fit min/max/step settings of the interface. + @type {number} + @example dial.value = 10; + */ + get value(): number; + previousAngle: boolean; + background: SVGCircleElement; + screw: SVGCircleElement; + handle: SVGPathElement; + handle2: SVGPathElement; + handleFill: SVGPathElement; + handle2Fill: SVGPathElement; + handleLine: SVGPathElement; + render(): void; + set min(arg: number); + /** + Lower limit of the dial's output range + @type {number} + @example dial.min = 1000; + */ + get min(): number; + set max(arg: number); + /** + Upper limit of the dial's output range + @type {number} + @example dial.max = 1000; + */ + get max(): number; + set step(arg: number); + /** + The increment that the dial's value changes by. + @type {number} + @example dial.step = 5; + */ + get step(): number; + set mode(arg: string); + /** + Absolute mode (dial's value jumps to mouse click position) or relative mode (mouse drag changes value relative to its current position). Default: "relative". + @type {string} + @example dial.mode = "relative"; + */ + get mode(): string; + set normalized(arg: number); + /** + Normalized value of the dial. + @type {number} + @example dial.normalized = 0.5; + */ + get normalized(): number; +} diff --git a/dist/types/interfaces/envelope.d.ts b/dist/types/interfaces/envelope.d.ts new file mode 100644 index 00000000..62012640 --- /dev/null +++ b/dist/types/interfaces/envelope.d.ts @@ -0,0 +1,132 @@ +import Interface, { InterfaceOptions } from "../core/interface"; +import { XYPosition } from "../util/interaction"; + +declare class Point { + x: number; + y: number; + + xMin: number; + xMax: number; + yMin: number; + yMax: number; + + envelope: Envelope; + + location: XYPosition; + + element: SVGCircleElement; + + resize(): void; + move(x: number, y: number): void; + getCoordinates(): XYPosition; + + destroy(): void; +} + +type EnvelopeOptions = { + noNewPoints: boolean; + points: XYPosition[]; +}; + +/** + * Envelope + * + * @description Interactive linear ramp visualization. + * + * @demo + * + * @example + * var envelope = new Nexus.Envelope('#target') + * + * @example + * var envelope = new Nexus.Envelope('#target',{ + * 'size': [300,150], + * 'noNewPoints': false, + * 'points': [ + * { + * x: 0.1, + * y: 0.4 + * }, + * { + * x: 0.35, + * y: 0.6 + * }, + * { + * x: 0.65, + * y: 0.2 + * }, + * { + * x: 0.9, + * y: 0.4 + * }, + * ] + * }) + * + * @output + * change + * Fires any time a node is moved.
+ * The event data is an array of point locations. Each item in the array is an object containing x and y properties describing the location of a point on the envelope. + * + * @outputexample + * envelope.on('change',function(v) { + * console.log(v); + * }) + * + */ +export default class Envelope extends Interface { + on( + event: "change", + listener: (locations: XYPosition[], ...args: any[]) => void + ): this; + points: XYPosition[]; + nodes: Point[]; + selected: boolean; + line: SVGPolylineElement; + fill: SVGPolylineElement; + render(): void; + calculatePoints(): void; + calculatePath(): void; + hasMoved: boolean | undefined; + findNearestNode(): number | null; + getIndexFromX(x: number): number; + scaleNode(i: number): void; + /** + Sort the this.points array from left-most point to right-most point. You should not regularly need to use this, however it may be useful if the points get unordered. + */ + sortPoints(): void; + /** + Add a breakpoint on the envelope. + @param x {number} x location of the point, normalized (0-1) + @param y {number} y location of the point, normalized (0-1) + */ + addPoint(x: number, y: number): void; + /** + Find the level at a certain x location on the envelope. + @param x {number} The x location to find the level of, normalized 0-1 + */ + scan(x: number): number; + /** + Move a breakpoint on the envelope. + @param index {number} The index of the breakpoint to move + @param x {number} New x location, normalized 0-1 + @param y {number} New y location, normalized 0-1 + */ + movePoint(index: number, x: number, y: number): void; + /** + Move a breakpoint on the envelope by a certain amount. + @param index {number} The index of the breakpoint to move + @param xOffset {number} X displacement, normalized 0-1 + @param yOffset {number} Y displacement, normalized 0-1 + */ + adjustPoint(index: number, xOffset: number, yOffset: number): void; + /** + Remove a breakpoint from the envelope. + @param index {number} Index of the breakpoint to remove + */ + destroyPoint(index: number): void; + /** + Remove all existing breakpoints and add an entirely new set of breakpoints. + @param allPoints {array} An array of objects with x/y properties (normalized 0-1). Each object in the array specifices the x/y location of a new breakpoint to be added. + */ + setPoints(allPoints: XYPosition[]): void; +} diff --git a/dist/types/interfaces/index.d.ts b/dist/types/interfaces/index.d.ts new file mode 100644 index 00000000..779690b5 --- /dev/null +++ b/dist/types/interfaces/index.d.ts @@ -0,0 +1,22 @@ +declare namespace _default { + const Position: typeof import("./position").default; + const Slider: typeof import("./slider").default; + const Toggle: typeof import("./toggle").default; + const Button: typeof import("./button").default; + const TextButton: typeof import("./textbutton").default; + const RadioButton: typeof import("./radiobutton").default; + const Number: typeof import("./number").default; + const Select: typeof import("./select").default; + const Dial: typeof import("./dial").default; + const Piano: typeof import("./piano").default; + const Sequencer: typeof import("./sequencer").default; + const Pan2D: typeof import("./pan2d").default; + const Tilt: typeof import("./tilt").default; + const Multislider: typeof import("./multislider").default; + const Pan: typeof import("./pan").default; + const Envelope: typeof import("./envelope").default; + const Spectrogram: typeof import("./spectrogram").default; + const Meter: typeof import("./meter").default; + const Oscilloscope: typeof import("./oscilloscope").default; +} +export default _default; diff --git a/dist/types/interfaces/meter.d.ts b/dist/types/interfaces/meter.d.ts new file mode 100644 index 00000000..d66d2f8c --- /dev/null +++ b/dist/types/interfaces/meter.d.ts @@ -0,0 +1,52 @@ +import Interface, { InterfaceOptions } from "../core/interface"; +import dom = require("../util/dom"); + +/** + * Meter + * + * @description Stereo decibel meter + * + * @demo + * + * @example + * var meter = new Nexus.Meter('#target') + * meter.connect(myWebAudioNode) + * + * @example + * var meter = new Nexus.Meter('#target', { + * size: [75,75] + * }) + * meter.connect(myWebAudioNode) + * + * @output + *   + * No events + * + */ +export default class Meter extends Interface<{}> { + channels: number; + splitter: ChannelSplitterNode | null; + analysers: AnalyserNode[]; + bufferLength: number; + dataArray: Float32Array | null; + active: boolean; + source: AudioNode | null; + db: number; + meterWidth: number; + buildFrame(): void; + canvas: dom.SmartCanvas; + element: HTMLCanvasElement; + render(): void; + /** + Equivalent to "patching in" an audio node to visualize. + @param node {AudioNode} The audio node to visualize + @param channels {number} (optional) The number of channels in the source node to watch. If not specified, the interface will look for a .channelCount property on the input node. If it does not exist, the interface will default to 1 channel. + @example meter.connect( Tone.Master, 2 ); + */ + connect(node: AudioNode, channels: number): void; + /** + Stop visualizing the source node and disconnect it. + */ + disconnect(): void; + customDestroy(): void; +} diff --git a/dist/types/interfaces/multislider.d.ts b/dist/types/interfaces/multislider.d.ts new file mode 100644 index 00000000..8c2cc69d --- /dev/null +++ b/dist/types/interfaces/multislider.d.ts @@ -0,0 +1,130 @@ +import Interface, { InterfaceOptions } from "../core/interface"; +import { StepOptions } from "../models/step"; + +type MultiSliderMode = "bar" | "line"; + +type MultiSliderOptions = StepOptions & { + numberOfSliders: number; + candycane: number; + values: number[]; + smoothing: number; +}; + +/** + * Multislider + * + * @description Multislider + * + * @demo + * + * @example + * var multislider = new Nexus.Multislider('#target') + * + * @example + * var multislider = new Nexus.Multislider('#target',{ + * 'size': [200,100], + * 'numberOfSliders': 5, + * 'min': 0, + * 'max': 1, + * 'step': 0, + * 'candycane': 3, + * 'values': [0.9,0.8,0.7,0.6,0.5,0.4,0.3,0.2,0.1], + * 'smoothing': 0, + * 'mode': 'bar' // 'bar' or 'line' + *}) + * + * @output + * change + * Fires any time the interface's value changes.
+ * The event data is an object containing index and value properties + * + * @outputexample + * multislider.on('change',function(v) { + * console.log(v); + * }) + * + */ +export default class Multislider extends Interface { + on( + event: "change", + listener: ( + sliderValue: { index: number; value: number }, + ...args: any[] + ) => void + ): this; + _numberOfSliders: number; + _min: number; + _max: number; + _step: number; + _mode: MultiSliderMode; + values: number[]; + candycane: number; + sliderWidth: number; + /** + Applies a simple low-pass filter to the multislider as it is interacted with. A smoothing of 0 will be no smoothing. A smoothing of 1 will smooth 1 slider on each side of the interaction. A smoothing of 2 will smooth 2 sliders on each side, and so on. + @type {Number} + */ + smoothing: number; + line: SVGPolylineElement; + fill: SVGPolylineElement; + nodes: SVGCircleElement[]; + bars: SVGRectElement[]; + caps: SVGRectElement[]; + getBarX(index: number): number; + getX(index: number): number; + getY(value: number): number; + getValueFromY(y: number): number; + getIndexFromX(x: number): number; + adjustValueToStep(value: number): number; + adjustAllValues(): void; + getNormalizedValues(): void; + normalizedValues: number[] | undefined; + render(): void; + hasMoved?: boolean; + previousSlider?: number | boolean; + selectedSlider?: number; + scan(): void; + update(index: number, value: number): void; + /** + Get the number of sliders + @type {Number} + */ + get numberOfSliders(): number; + set min(arg: number); + /** + Lower limit of the multislider's output range + @type {number} + @example multislider.min = 1000; + */ + get min(): number; + set max(arg: number); + /** + Upper limit of the multislider's output range + @type {number} + @example multislider.max = 1000; + */ + get max(): number; + set step(arg: number); + /** + The increment that the multislider's value changes by. + @type {number} + @example multislider.step = 5; + */ + get step(): number; + /** + Set the value of an individual slider + @param index {number} Slider index + @param value {number} New slider value + @example + // Set the first slider to value 0.5 + multislider.setSlider(0,0.5) + */ + setSlider(index: number, value: number): void; + /** + Set the value of all sliders at once. If the size of the input array does not match the current number of sliders, the value array will repeat until all sliders have been set. I.e. an input array of length 1 will set all sliders to that value. + @param values {Array} All slider values + @example + multislider.setAllSliders([0.2,0.3,0.4,0.5,0.6]) + */ + setAllSliders(values: number[]): void; +} diff --git a/dist/types/interfaces/number.d.ts b/dist/types/interfaces/number.d.ts new file mode 100644 index 00000000..6b43aab0 --- /dev/null +++ b/dist/types/interfaces/number.d.ts @@ -0,0 +1,86 @@ +import Interface, { InterfaceOptions } from "../core/interface"; +import Step, { StepOptions } from "../models/step"; + +type NumberOptions = StepOptions; + +/** + * Number + * + * @description Number interface which is controllable by dragging or typing. + * + * @demo + * + * @example + * var number = new Nexus.Number('#target') + * + * @example + * var number = new Nexus.Number('#target',{ + * 'size': [60,30], + * 'value': 0, + * 'min': 0, + * 'max': 20000, + * 'step': 1 + * }) + * + * @output + * change + * Fires any time the interface's value changes.
+ * The event data is the number value of the interface. + * + * @outputexample + * number.on('change',function(v) { + * console.log(v); + * }) + * + * + */ +export default class Number extends Interface { + on(event: "change", listener: (value: number, ...args: any[]) => void): this; + _value: Step; + decimalPlaces: number; + actual: number; + set max(arg: number); + /** + Upper limit of the number's output range + @type {number} + @example number.max = 1000; + */ + get max(): number; + set min(arg: number); + /** + Lower limit of the number's output range + @type {number} + @example number.min = 1000; + */ + get min(): number; + set step(arg: number); + /** + The increment that the number's value changes by. + @type {number} + @example number.step = 5; + */ + get step(): number; + _minDimension?: number; + render(): void; + hasMoved?: boolean; + initial?: { + y: number; + }; + changeFactor?: number; + set value(arg: number); + /** + The interface's current value. If set manually, will update the interface and trigger the output event. + @type {number} + @example number.value = 10; + */ + get value(): number; + /** + Connect this number interface to a dial or slider + @param {Interface} element Element to connect to. + @example number.link(slider) + */ + link( + destination: Interface + ): void; + passiveUpdate(value: number): void; +} diff --git a/dist/types/interfaces/oscilloscope.d.ts b/dist/types/interfaces/oscilloscope.d.ts new file mode 100644 index 00000000..e23c42df --- /dev/null +++ b/dist/types/interfaces/oscilloscope.d.ts @@ -0,0 +1,45 @@ +import Interface, { InterfaceOptions } from "../core/interface"; +import dom = require("../util/dom"); + +/** + * Oscilloscope + * + * @description Visualizes a waveform's stream of values. + * + * @demo + * + * @example + * var oscilloscope = new Nexus.Oscilloscope('#target') + * oscilloscope.connect(myWebAudioNode) + * + * @example + * var oscilloscope = new Nexus.Oscilloscope('#target',{ + * 'size': [300,150] + * }) + * oscilloscope.connect(myWebAudioNode) + * + * @output + *   + * No events + * + */ +export default class Oscilloscope extends Interface<{}> { + analyser: AnalyserNode | null; + bufferLength: number; + dataArray: Uint8Array | null; + active: boolean; + source: AudioNode | null; + canvas: dom.SmartCanvas; + render(): void; + /** + Equivalent to "patching in" an audio node to visualize. + @param node {AudioNode} The audio node to visualize + @example oscilloscope.connect( Tone.Master ); + */ + connect(node: AudioNode): void; + /** + Stop visualizing the source node and disconnect it. + */ + disconnect(): void; + customDestroy(): void; +} diff --git a/dist/types/interfaces/pan.d.ts b/dist/types/interfaces/pan.d.ts new file mode 100644 index 00000000..7db226d7 --- /dev/null +++ b/dist/types/interfaces/pan.d.ts @@ -0,0 +1,64 @@ +import { + SliderOrientation, + SliderTemplateOptions, +} from "../components/slidertemplate"; +import Interface, { InterfaceOptions } from "../core/interface"; +import Step from "../models/step"; +import * as Interaction from "../util/interaction"; + +type PanOptions = Interaction.HandleMode & + Interaction.HandleDirection & + SliderTemplateOptions; + +/** + * Pan + * + * @description Stereo crossfader. + * + * @demo + * + * @example + * var pan = new Nexus.Pan('#target') + * + * @output + * change + * Fires any time the interface's value changes.
+ * The event data is an object containing the interface's value (-1 to 1), as well as L and R amplitude values (0-1) for left and right speakers, calculated by a square-root crossfade algorithm. + * + * @outputexample + * pan.on('change',function(v) { + * console.log(v); + * }) + * + * + */ +export default class Pan extends Interface { + on( + event: "change", + listener: ( + panValue: { value: number; L: number; R: number }, + ...args: any[] + ) => void + ): this; + orientation: SliderOrientation; + mode: Interaction.HandleMode; + hasKnob: boolean; + step: number; + _value: Step; + position: Interaction.Handle; + set value(arg: number); + /** + The position of crossfader, from -1 (left) to 1 (right). Setting this value updates the interface and triggers the output event. + @type {number} + */ + get value(): number; + bar: SVGRectElement; + knob: SVGCircleElement; + knobData?: { + level: number; + r: number; + }; + thickness: number | undefined; + render(): void; + get normalized(): number; +} diff --git a/dist/types/interfaces/pan2d.d.ts b/dist/types/interfaces/pan2d.d.ts new file mode 100644 index 00000000..36d2ec64 --- /dev/null +++ b/dist/types/interfaces/pan2d.d.ts @@ -0,0 +1,98 @@ +import Interface, { InterfaceOptions } from "../core/interface"; +import Step from "../models/step"; +import * as Interaction from "../util/interaction"; + +type Pan2DOptions = { + range: number; + mode: Interaction.HandleMode; + speakers: Interaction.XYPosition[]; +}; + +/** + * Pan2D + * + * @description Interface for moving a sound around an array of speakers. Speaker locations can be customized. The interface calculates the closeness of the sound source to each speaker and returns that distance as a numeric value. + * + * @demo + * + * @example + * var pan2d = new Nexus.Pan2d('#target') + * + * @example + * var pan2d = new Nexus.Pan2D('#target',{ + * 'size': [200,200], + * 'range': 0.5, // detection radius of each speaker + * 'mode': 'absolute', // 'absolute' or 'relative' sound movement + * 'speakers': [ // the speaker [x,y] positions + * [0.5,0.2], + * [0.75,0.25], + * [0.8,0.5], + * [0.75,0.75], + * [0.5,0.8], + * [0.25,0.75] + * [0.2,0.5], + * [0.25,0.25] + * ] + * }) + * + * @output + * change + * Fires any time the "source" node's position changes.
+ * The event data is an array of the amplitudes (0-1), representing the level of each speaker (as calculated by its distance to the audio source). + * + * @outputexample + * pan2d.on('change',function(v) { + * console.log(v); + * }) + * + */ +export default class Pan2D extends Interface { + on( + event: "change", + listener: (speakerAmplitudes: number[], ...args: any[]) => void + ): this; + value: { + [axis in keyof Interaction.XYPosition]: Step; + }; + /** + Absolute or relative mouse interaction. In "absolute" mode, the source node will jump to your mouse position on mouse click. In "relative" mode, it does not. + */ + mode: Interaction.HandleMode; + position: { [axis in keyof Interaction.XYPosition]: Interaction.Handle }; + /** + An array of speaker locations. Update this with .moveSpeaker() or .moveAllSpeakers() + */ + speakers: Interaction.XYPosition[]; + /** + Rewrite: The maximum distance from a speaker that the source node can be for it to be heard from that speaker. A low range (0.1) will result in speakers only playing when the sound is very close it. Default is 0.5 (half of the interface). + */ + range: number; + /** + The current levels for each speaker. This is calculated when a source node or speaker node is moved through interaction or programatically. + */ + levels: number[]; + knob: SVGCircleElement; + speakerElements: SVGCircleElement[]; + sizeInterface(): void; + _minDimension: number; + knobRadius: { + off: number; + }; + render(): void; + knobCoordinates: Interaction.XYPosition; + get normalized(): Interaction.XYPosition; + calculateLevels(): void; + /** + Move the audio source node and trigger the output event. + @param x {number} New x location, normalized 0-1 + @param y {number} New y location, normalized 0-1 + */ + moveSource(x: number, y: number): void; + /** + Move a speaker node and trigger the output event. + @param index {number} Index of the speaker to move + @param x {number} New x location, normalized 0-1 + @param y {number} New y location, normalized 0-1 + */ + moveSpeaker(index: number, x: number, y: number): void; +} diff --git a/dist/types/interfaces/piano.d.ts b/dist/types/interfaces/piano.d.ts new file mode 100644 index 00000000..c54da464 --- /dev/null +++ b/dist/types/interfaces/piano.d.ts @@ -0,0 +1,88 @@ +import Interface, { InterfaceOptions } from "../core/interface"; +import ButtonTemplate, { + ButtonMode, + ButtonTemplateOptions, +} from "../components/buttontemplate"; + +declare type PianoKeyColor = "b" | "w"; +type PianoKeyOptions = ButtonTemplateOptions & { + note: number; + color: PianoKeyColor; +}; + +declare class PianoKey extends ButtonTemplate { + note: number; + color: PianoKeyColor; +} + +type PianoOptions = { + lowNote: number; + highNote: number; + mode: ButtonMode; +}; + +/** + * Piano + * + * @description Piano keyboard interface + * + * @demo
+ * + * @example + * var piano = new Nexus.Piano('#target') + * + * @example + * var piano = new Nexus.Piano('#target',{ + * 'size': [500,125], + * 'mode': 'button', // 'button', 'toggle', or 'impulse' + * 'lowNote': 24, + * 'highNote': 60 + * }) + * + * @output + * change + * Fires any time a new key is pressed or released
+ * The event data is an object containing note and state properties. + * + * @outputexample + * piano.on('change',function(v) { + * console.log(v); + * }) + * + */ +export default class Piano extends Interface { + on( + event: "change", + listener: (note: { note: number; state: boolean }, ...args: any[]) => void + ): this; + keyPattern: PianoKeyColor[]; + paintbrush: boolean; + mode: ButtonMode; + range: { + low: number; + high: number; + }; + keys: PianoKey[]; + toggleTo: boolean; + keyChange(note: number, on: boolean | { state: boolean }): void; + render(): void; + addTouchListeners(): void; + /** + Define the pitch range (lowest and highest note) of the piano keyboard. + @param low {number} MIDI note value of the lowest note on the keyboard + @param high {number} MIDI note value of the highest note on the keyboard + */ + setRange(low: number, high: number): void; + /** + Turn a key on or off using its MIDI note value; + @param note {number} MIDI note value of the key to change + @param on {boolean} Whether the note should turn on or off + */ + toggleKey(note: number, on: boolean): void; + /** + Turn a key on or off using its key index on the piano interface. + @param index {number} Index of the key to change + @param on {boolean} Whether the note should turn on or off + */ + toggleIndex(index: number, on: boolean): void; +} diff --git a/dist/types/interfaces/position.d.ts b/dist/types/interfaces/position.d.ts new file mode 100644 index 00000000..3be53b16 --- /dev/null +++ b/dist/types/interfaces/position.d.ts @@ -0,0 +1,131 @@ +import Interface from "../core/interface"; +import Step from "../models/step"; +import * as Interaction from "../util/interaction"; + +type PositionOptions = { + mode: Interaction.HandleMode; + x: number; + y: number; + minX: number; + maxX: number; + minY: number; + maxY: number; + stepX: number; + stepY: number; +}; + +/** + * Position + * + * @description Two-dimensional touch slider. + * + * @demo + * + * @example + * var position = new Nexus.Position('#target') + * + * @example + * var position = new Nexus.Position('#target',{ + * 'size': [200,200], + * 'mode': 'absolute', // "absolute" or "relative" + * 'x': 0.5, // initial x value + * 'minX': 0, + * 'maxX': 1, + * 'stepX': 0, + * 'y': 0.5, // initial y value + * 'minY': 0, + * 'maxY': 1, + * 'stepY': 0 + * }) + * + * @output + * change + * Fires any time the interface's value changes.
+ * The event data is an object with x and y properties containing the x and y values of the interface. + * + * @outputexample + * position.on('change',function(v) { + * console.log(v); + * }) + * + * + */ +export default class Position extends Interface { + on( + event: "change", + listener: (position: Interaction.XYPosition, ...args: any[]) => void + ): this; + _x: Step; + _y: Step; + position: { [axis in keyof Interaction.XYPosition]: Interaction.Handle }; + knob: SVGCircleElement; + _minDimension: number; + knobRadius: { + on: number; + off: number; + }; + render(): void; + knobCoordinates: Interaction.XYPosition; + on( + event: "change", + callback: (v: Interaction.XYPosition, ...args: any[]) => void + ): this; + set x(arg: number); + /** + * The interface's x value. When set, it will automatically adjust to fit min/max/step settings of the interface. + * @type {number} + * @example position.x = 0.5; + */ + get x(): number; + set y(arg: number); + /** + * The interface's y values. When set, it will automatically adjust to fit min/max/step settings of the interface. + * @type {number} + * @example position.x = 0.5; + */ + get y(): number; + get normalized(): Interaction.XYPosition; + set minX(arg: number); + /** + * The lower limit of value on the x axis + * @type {number} + */ + get minX(): number; + set minY(arg: number); + /** + * The lower limit of value on the y axis + * @type {number} + */ + get minY(): number; + set maxX(arg: number); + /** + * The upper limit of value on the x axis + * @type {number} + */ + get maxX(): number; + set maxY(arg: number); + /** + * The upper limit of value on the y axis + * @type {number} + */ + get maxY(): number; + set stepX(arg: number); + /** + * The incremental step of values on the x axis + * @type {number} + */ + get stepX(): number; + set stepY(arg: number); + /** + * The incremental step of values on the y axis + * @type {number} + */ + get stepY(): number; + set mode(arg: string); + /** + Absolute mode (position's value jumps to mouse click position) or relative mode (mouse drag changes value relative to its current position). Default: "absolute". + @type {string} + @example position.mode = "relative"; + */ + get mode(): string; +} diff --git a/dist/types/interfaces/radiobutton.d.ts b/dist/types/interfaces/radiobutton.d.ts new file mode 100644 index 00000000..29bdfff0 --- /dev/null +++ b/dist/types/interfaces/radiobutton.d.ts @@ -0,0 +1,59 @@ +import Interface, { InterfaceOptions } from "../core/interface"; +import Button from "./button"; + +type RadioButtonOptions = { + numberOfButtons: number; + active: number; +}; + +/** + * RadioButton + * + * @description An array of buttons. By default, selecting one button will deselect all other buttons, but this can be customized using the API below. + * + * @demo
+ * + * @example + * var radiobutton = new Nexus.RadioButton('#target') + * + * @example + * var radiobutton = new Nexus.RadioButton('#target',{ + * 'size': [120,25], + * 'numberOfButtons': 4, + * 'active': -1 + * }) + * + * @output + * change + * Fires any time the interface's value changes.
+ * The event data is an integer, the index of the button that is currently on. If no button is selected, the value will be -1. + * + * @outputexample + * radiobutton.on('change',function(v) { + * console.log(v); + * }) + * + */ +export default class RadioButton extends Interface { + on(event: "change", listener: (index: number, ...args: any[]) => void): this; + render(): void; + buttons: Button[]; + active: number; + _numberOfButtons: number; + update(index: number): void; + /** + Select one button and deselect all other buttons. + @param index {number} The index of the button to select + */ + select(index: number): void; + /** + Deselect all buttons. + */ + deselect(): void; + /** + * Update how many buttons are in the interface + * @param {number} buttons How many buttons are in the interface + */ + set numberOfButtons(arg: number); + get numberOfButtons(): number; +} diff --git a/dist/types/interfaces/select.d.ts b/dist/types/interfaces/select.d.ts new file mode 100644 index 00000000..21a455f2 --- /dev/null +++ b/dist/types/interfaces/select.d.ts @@ -0,0 +1,65 @@ +import Interface from "../core/interface"; + +type SelectOptions = { + options: string[]; +}; + +/** + * Select + * + * @description Dropdown menu + * + * @demo + * + * @example + * var select = new Nexus.Select('#target') + * + * @example + * var select = new Nexus.Select('#target',{ + * 'size': [100,30], + * 'options': ['default','options'] + * }) + * + * @output + * change + * Fires any time the interface's value changes.
+ * The event data is an object containing the text value of the selected option, as well as the numeric index of the selection. + * + * @outputexample + * select.on('change',function(v) { + * console.log(v); + * }) + * + * + */ +export default class Select extends Interface { + on( + event: "change", + listener: (value: { value: string; index: number }, ...args: any[]) => void + ): this; + _selectedIndex: number; + _value: boolean | string; + _options: string[]; + render(): void; + boundRender: typeof this.render; + /** + * Update the list of options. This removes all existing options and creates a new list of options. + * @param {array} options New array of options + */ + defineOptions(options: any): void; + set value(arg: string); + /** + The text of the option that is currently selected. If set, will update the interface and trigger the output event. + @type {String} + @example select.value = "sawtooth"; + */ + get value(): string; + set selectedIndex(arg: number); + /** + The numeric index of the option that is currently selected. If set, will update the interface and trigger the output event. + @type {number} + @example select.selectedIndex = 2; + */ + get selectedIndex(): number; + customDestroy(): void; +} diff --git a/dist/types/interfaces/sequencer.d.ts b/dist/types/interfaces/sequencer.d.ts new file mode 100644 index 00000000..be8185a8 --- /dev/null +++ b/dist/types/interfaces/sequencer.d.ts @@ -0,0 +1,147 @@ +import ButtonTemplate, { + ButtonMode, + ButtonTemplateOptions, +} from "../components/buttontemplate"; +import Interface, { InterfaceOptions } from "../core/interface"; +import Counter from "../models/counter"; +import Matrix from "../models/matrix"; +import Interval from "../time/interval"; + +type MatrixCellOptions = ButtonTemplateOptions & { + value: number; + paddingRow: number; + paddingColumn: number; + target: false; +}; + +export class MatrixCell extends ButtonTemplate { + pad: SVGRectElement; + index: number; + row: number; + column: number; + matrix: Matrix; + paddingRow: number; + paddingColumn: number; + interacting: boolean; + paintbrush: boolean; +} + +type SequencerOptions = { + mode: ButtonMode; + rows: number; + column: number; + paddingRow: number; + paddingColumn: number; +}; + +/** + * Sequencer + * + * @description Grid of buttons with built-in step sequencer. + * + * @demo
+ * + * @example + * var sequencer = new Nexus.Sequencer('#target') + * + * @example + * var sequencer = new Nexus.Sequencer('#target',{ + * 'size': [400,200], + * 'mode': 'toggle', + * 'rows': 5, + * 'columns': 10, + * 'paddingRow': 10, + * 'paddingColumn': 20 + *}) + * + * @output + * change + * Fires whenever a value is received. For example, when clicking a cell from off to on.
+ * The event data is an object containing row (number), column (number), and state (boolean) properties. + * + * @outputexample + * sequencer.on('change',function(v) { + * console.log(v); + * }) + * + * @output + * step + * Fires any time the sequencer steps to the next column, in sequece mode.
+ * The event data is an array containing all values in the column, bottom row first. + * + * @outputexample + * sequencer.on('step',function(v) { + * console.log(v); + * }) + */ +export default class Sequencer extends Interface { + on( + event: "change", + listener: ( + cellValue: { row: number; column: number; state: boolean }, + ...args: any[] + ) => void + ): this; + on( + event: "step", + listener: (columnValues: number[], ...args: any[]) => void + ): this; + + active: number; + /** + * Button interaction mode: see Button + * @type {string} + * @example button.mode = 'toggle'; + */ + mode: ButtonMode; + /** + * The interval object which controls timing and sequence scheduling. + * @type {interval} + */ + interval: Interval; + /** + * A Matrix model containing methods for manipulating the sequencer's array of values. To learn how to manipulate the matrix, read about the matrix model. + * @type {matrix} + */ + matrix: Matrix; + /** + * A Counter model which the sequencer steps through. For example, you could use this model to step through the sequencer in reverse, randomly, or in a drunk walk. + * @type {counter} + */ + stepper: Counter; + paddingRow: number; + paddingColumn: number; + render(): void; + cells: MatrixCell[]; + update(): void; + keyChange(note: any, on: any): void; + /** + * Start sequencing + * @param {number} ms Beat tempo in milliseconds + */ + start(ms: number): void; + /** + Stop sequencing + */ + stop(): void; + /** + Manually jump to the next column and trigger the 'change' event. The "next" column is determined by your mode of sequencing. + */ + next(): void; + addTouchListeners(): void; + currentElement?: false | number; + paintbrush?: boolean; + interacting?: boolean; + set rows(arg: number); + /** + Number of rows in the sequencer + @type {number} + */ + get rows(): number; + set columns(arg: number); + /** + Number of columns in the sequencer + @type {number} + */ + get columns(): number; +} diff --git a/dist/types/interfaces/slider.d.ts b/dist/types/interfaces/slider.d.ts new file mode 100644 index 00000000..ce2f16b8 --- /dev/null +++ b/dist/types/interfaces/slider.d.ts @@ -0,0 +1,94 @@ +import Interface, { InterfaceOptions } from "../core/interface"; +import Step, { StepOptions } from "../models/step"; +import * as Interaction from "../util/interaction"; +import { HandleMode } from "../util/interaction"; +import { SliderOrientation } from "../components/slidertemplate"; + +type SliderMode = HandleMode; +type SliderOptions = StepOptions & { + mode: SliderMode; +}; + +/** + * Slider + * + * @description Horizontal or vertical slider with settable interaction modes. + * + * @demo + * + * @example + * var slider = new Nexus.Slider('#target') + * + * @example + * var slider = new Nexus.Slider('#target',{ + * 'size': [120,20], + * 'mode': 'relative', // 'relative' or 'absolute' + * 'min': 0, + * 'max': 1, + * 'step': 0, + * 'value': 0 + * }) + * + * @output + * change + * Fires when the interface's value changes.
+ * Event data: number The number value of the interface. + * + * @outputexample + * slider.on('change',function(v) { + * console.log(v); + * }) + * + * + */ +export default class Slider extends Interface { + on(event: "change", listener: (number: number, ...args: any[]) => void): this; + orientation: SliderOrientation; + _value: Step; + position: Interaction.Handle; + bar: SVGRectElement; + fillbar: SVGRectElement; + knob: SVGCircleElement; + knobData: { + level: number; + r: number; + }; + thickness: number; + render(): void; + get normalized(): any; + set value(arg: number); + /** + The slider's current value. If set manually, will update the interface and trigger the output event. + @type {number} + @example slider.value = 10; + */ + get value(): number; + set min(arg: number); + /** + Lower limit of the sliders's output range + @type {number} + @example slider.min = 1000; + */ + get min(): number; + set max(arg: number); + /** + Upper limit of the slider's output range + @type {number} + @example slider.max = 1000; + */ + get max(): number; + set step(arg: number); + /** + The increment that the slider's value changes by. + @type {number} + @example slider.step = 5; + */ + get step(): number; + set mode(arg: string); + /** + Absolute mode (slider's value jumps to mouse click position) or relative mode (mouse drag changes value relative to its current position). Default: "relative". + @type {string} + @example slider.mode = "relative"; + */ + get mode(): string; +} diff --git a/dist/types/interfaces/spectrogram.d.ts b/dist/types/interfaces/spectrogram.d.ts new file mode 100644 index 00000000..d5c3919d --- /dev/null +++ b/dist/types/interfaces/spectrogram.d.ts @@ -0,0 +1,45 @@ +import Interface, { InterfaceOptions } from "../core/interface"; +import dom = require("../util/dom"); + +/** + * Spectrogram + * + * @description Audio spectrum visualization + * + * @demo + * + * @example + * var spectrogram = new Nexus.Spectrogram('#target') + * spectrogram.connect(myWebAudioNode) + * + * @example + * var spectrogram = new Nexus.Spectrogram('#target',{ + * 'size': [300,150] + * }) + * spectrogram.connect(myWebAudioNode) + * + * @output + *   + * No events + * + */ +export default class Spectrogram extends Interface<{}> { + analyser: AnalyserNode | null; + bufferLength: number; + dataArray: Uint8Array | null; + active: boolean; + source: AudioNode | null; + canvas: dom.SmartCanvas | undefined; + render(): void; + /** + Equivalent to "patching in" an audio node to visualize. + @param node {AudioNode} The audio node to visualize + @example spectrogram.connect( Tone.Master ); + */ + connect(node: AudioNode): void; + /** + Stop visualizing the source node and disconnect it. + */ + disconnect(): void; + customDestroy(): void; +} diff --git a/dist/types/interfaces/textbutton.d.ts b/dist/types/interfaces/textbutton.d.ts new file mode 100644 index 00000000..2fad3d2f --- /dev/null +++ b/dist/types/interfaces/textbutton.d.ts @@ -0,0 +1,57 @@ +import ButtonTemplate, { + ButtonTemplateOptions, +} from "../components/buttontemplate"; + +type TextButtonOptions = ButtonTemplateOptions & { + text: string; + alternateText: string | any; +}; + +/** + * TextButton + * + * @description Text button + * + * @demo + * + * @example + * var textbutton = new Nexus.TextButton('#target') + * + * @example + * var textbutton = new Nexus.TextButton('#target',{ + * 'size': [150,50], + * 'state': false, + * 'text': 'Play', + * 'alternateText': 'Stop' + * }) + * + * @output + * change + * Fires any time the interface's value changes.
+ * The event data is a string of the text on the button at the moment it was clicked. + * + * @outputexample + * textbutton.on('change',function(v) { + * console.log(v); + * }) + * + */ +export default class TextButton extends ButtonTemplate { + on(event: "change", listener: (text: string, ...args: any[]) => void): this; + _text: string; + _alternateText: string; + textElement: HTMLDivElement | undefined; + render(): void; + set alternateText(arg: string); + /** + The text to display when the button is in its "on" state. If set, this puts the button in "toggle" mode. + @type {String} + */ + get alternateText(): string; + set text(arg: string); + /** + The text to display. (If .alternateText exists, then this .text will only be displayed when the button is in its "off" state.) + @type {String} + */ + get text(): string; +} diff --git a/dist/types/interfaces/tilt.d.ts b/dist/types/interfaces/tilt.d.ts new file mode 100644 index 00000000..1e8037af --- /dev/null +++ b/dist/types/interfaces/tilt.d.ts @@ -0,0 +1,57 @@ +import Interface from "../core/interface"; +import { XYPosition } from "../util/interaction"; + +type XYZPosition = XYPosition & { + z: number; +}; + +/** + * Tilt + * + * @description Device tilt sensor with 2 or 3 axes (depending on your device and browser). + * + * @demo + * + * @example + * var tilt = new Nexus.Tilt('#target') + * + * @output + * change + * Fires at a regular interval, as long as this interface is active (see the interface's .active property)
+ * The event data is an object containing x (number) and y (number) properties which represent the current tilt state of the device. + * + * @outputexample + * tilt.on('change',function(v) { + * console.log(v); + * }) + * + * + */ +export default class Tilt extends Interface<{}> { + on( + event: "change", + listener: (tiltData: XYZPosition, ...args: any[]) => void + ): this; + _active: boolean; + orientationListener: void; + title: SVGTextElement; + circleX: SVGCircleElement; + circleY: SVGCircleElement; + circleZ: SVGCircleElement; + barX: SVGPathElement; + barY: SVGPathElement; + barZ: SVGPathElement; + barX2: SVGPathElement; + barY2: SVGPathElement; + barZ2: SVGPathElement; + update(v: { alpha: number; beta: number; gamma: number }): void; + boundUpdate: typeof this.update; + click(): void; + set active(arg: boolean); + /** + Whether the interface is on (emitting values) or off (paused & not emitting values). Setting this property will update it. + @type {boolean} + */ + get active(): boolean; + customDestroy(): void; +} diff --git a/dist/types/interfaces/toggle.d.ts b/dist/types/interfaces/toggle.d.ts new file mode 100644 index 00000000..5cebe4e7 --- /dev/null +++ b/dist/types/interfaces/toggle.d.ts @@ -0,0 +1,56 @@ +import Interface from "../core/interface"; + +type ToggleOptions = { + state: boolean; + value: any; +}; + +/** + * Toggle + * + * @description Binary switch + * + * @demo + * + * @example + * var toggle = new Nexus.Toggle('#target') + * + * @example + * var toggle = new Nexus.Toggle('#target',{ + * 'size': [40,20], + * 'state': false + * }) + * + * @output + * change + * Fires any time the interface's value changes.
+ * Parameter: The boolean state of the interface. + * + * @outputexample + * toggle.on('change',function(v) { + * console.log(v); + * }) + * + * + */ +export default class Toggle extends Interface { + on(event: "change", listener: (state: boolean, ...args: any[]) => void): this; + _state: any; + bar: SVGRectElement; + knob: SVGCircleElement; + knobSize: number | undefined; + render(): void; + set state(arg: boolean); + /** + Whether the toggle is currently on or off. Setting this property will update the toggle interface and trigger the output event. + @type {boolean} + @example toggle.state = false; + */ + get state(): boolean; + /** + * Switch the toggle state to its opposite state + * @example + * toggle.flip(); + */ + flip(): void; +} diff --git a/dist/types/models/counter.d.ts b/dist/types/models/counter.d.ts new file mode 100644 index 00000000..555d7b87 --- /dev/null +++ b/dist/types/models/counter.d.ts @@ -0,0 +1,33 @@ +import Drunk from "./drunk"; + +type CounterMode = "up" | "down" | "random" | "drunk"; + +export default class Counter { + constructor( + min?: number, + max?: number, + mode?: CounterMode, + value?: number | boolean + ); + min: number; + max: number; + value: number | boolean; + set mode(arg: CounterMode); + get mode(): CounterMode; + _mode: CounterMode; + first(): number; + drunkWalk: Drunk; + next: () => number; + startValues: + | { + up: number; + down: number; + drunk: number; + random: number; + } + | undefined; + up(): number | boolean; + down(): number | boolean; + random(): number | boolean; + drunk(): number | boolean; +} diff --git a/dist/types/models/drunk.d.ts b/dist/types/models/drunk.d.ts new file mode 100644 index 00000000..1c732e67 --- /dev/null +++ b/dist/types/models/drunk.d.ts @@ -0,0 +1,15 @@ +export default class Drunk { + constructor( + min?: number, + max?: number, + value?: number, + increment?: number, + loop?: boolean + ); + min: number; + max: number; + value: number; + increment: number; + loop: boolean; + next(): number; +} diff --git a/dist/types/models/matrix.d.ts b/dist/types/models/matrix.d.ts new file mode 100644 index 00000000..9bcfc07d --- /dev/null +++ b/dist/types/models/matrix.d.ts @@ -0,0 +1,52 @@ +type MatrixValue = number; +type MatrixPattern = MatrixValue[][]; +type MatrixCell = { row: number; column: number }; + +export default class Matrix { + constructor(rows: number, columns: number); + pattern: MatrixPattern; + toggle: { + cell: (column: number, row: number) => void; + all: () => void; + row: (row: number) => void; + column: (column: number) => void; + }; + set: { + cell: (column: number, row: number, value: MatrixValue) => void; + all: (values: MatrixValue[][]) => void; + row: (row: number, values: MatrixValue[]) => void; + column: (column: number, values: MatrixValue[]) => void; + }; + rotate: { + all: (amount: number) => void; + row: (row: number, amount: number) => void; + column: (column: number, amount: number) => void; + }; + populate: { + all: (odds: number | number[]) => void; + row: (row?: number, odds?: number | number[]) => void; + column: (column?: number, odds?: number | number[]) => void; + }; + erase: { + all: () => void; + row: (row: number) => void; + column: (column: number) => void; + }; + create(rows: number, columns: number): void; + iterate( + f: (row: number) => void, + f2: (row: number, column: number, index: number) => void + ): void; + formatAsText(): string; + log(): void; + update(pattern: MatrixPattern): void; + get length(): number; + locate(index: number): MatrixCell; + indexOf(row: number, column: number): number; + row(row: number): number[]; + column(column: number): number[]; + set rows(rows: number); + get rows(): number; + set columns(columns: number); + get columns(): any; +} diff --git a/dist/types/models/radio.d.ts b/dist/types/models/radio.d.ts new file mode 100644 index 00000000..ec266606 --- /dev/null +++ b/dist/types/models/radio.d.ts @@ -0,0 +1,12 @@ +type RadioValue = 0 | 1; + +export default class Radio { + constructor(length?: number, ...onVals: any[]); + length: number; + onVals: any[]; + array: RadioValue[]; + select(value: number): RadioValue[]; + flip(...values: number[]): RadioValue[]; + on(...values: number[]): RadioValue[]; + off(...values: number[]): RadioValue[]; +} diff --git a/dist/types/models/range.d.ts b/dist/types/models/range.d.ts new file mode 100644 index 00000000..38122fc4 --- /dev/null +++ b/dist/types/models/range.d.ts @@ -0,0 +1,50 @@ +import Step from "./step"; + +type RangeOptions = Partial<{ + min: number; + max: number; + step: boolean; +}>; + +/** + Creates an abstract model of a steppable range slider with start and end values which are constricted by a minimum, maximum, and step size. + @param {number} [min=0] minimum + @param {number} [max=1] maximum + @param {number} [step=0] + @returns {Object} Step +*/ +export default class Range { + constructor(min?: number, max?: number, step?: boolean); + /** + {number} Minimum value of the range + */ + min: number; + /** + {number} Maximum value of the range + */ + max: number; + /** + {Step} Start value of the range selection + */ + start: Step; + /** + {Step} End value of the range selection + */ + end: Step; + set center(arg: number); + /** + {number} Center of the range selection + */ + get center(): number; + set size(arg: number); + /** + {number} Size of the range selection + */ + get size(): number; + /** + Move the range selection + @param {number} start New start value of the range selection + @param {number} end New end value of the range selection + */ + move(start: number, end: number): void; +} diff --git a/dist/types/models/sequence.d.ts b/dist/types/models/sequence.d.ts new file mode 100644 index 00000000..9c4f3e21 --- /dev/null +++ b/dist/types/models/sequence.d.ts @@ -0,0 +1,25 @@ +import Counter, { CounterMode } from "./counter"; + +export default class Sequence { + constructor( + sequence?: ValuesType[], + mode?: CounterMode, + position?: false | number + ); + values: ValuesType[]; + _mode: CounterMode; + position: boolean; + drunkWalk: Drunk; + startValues: { [mode in CounterMode]: number }; + next: ValuesType; + set mode(arg: CounterMode); + get mode(): CounterMode; + set value(arg: ValuesType); + get value(): ValuesType; + first(): ValuesType; + up(): ValuesType; + down(): ValuesType; + random(): ValuesType; + drunk(): ValuesType; +} +import Drunk from "./drunk"; diff --git a/dist/types/models/step.d.ts b/dist/types/models/step.d.ts new file mode 100644 index 00000000..d83c3428 --- /dev/null +++ b/dist/types/models/step.d.ts @@ -0,0 +1,38 @@ +export type StepOptions = Partial<{ + min: number; + max: number; + step: number; + value: number; +}>; + +/** + Creates a steppable value with minimum, maximum, and step size. This is used in many interfaces to constrict their values to certain ranges. + @param {number} [min=0] minimum + @param {number} [max=1] maximum + @param {number} [step=0] + @param {number} [value=0] initial value + @returns {Object} Step +*/ +export default class Step implements StepOptions { + constructor(min?: number, max?: number, step?: number, value?: number); + min: number; + max: number; + step: number; + value: number; + changed: boolean; + oldValue: boolean; + /** + Update with a new value. The value will be auto-adjusted to fit the min/max/step. + @param {number} value + */ + update(value: number): number; + /** + Update with a normalized value 0-1. + @param {number} value + */ + updateNormal(value: number): number; + /** + Get a normalized version of this.value . Not settable. + */ + get normalized(): number; +} diff --git a/dist/types/models/toggle.d.ts b/dist/types/models/toggle.d.ts new file mode 100644 index 00000000..ab78b020 --- /dev/null +++ b/dist/types/models/toggle.d.ts @@ -0,0 +1,7 @@ +export default class Toggle { + constructor(state?: boolean); + state: boolean; + flip(state: any): void; + on(): void; + off(): void; +} diff --git a/dist/types/time/interval.d.ts b/dist/types/time/interval.d.ts new file mode 100644 index 00000000..f179fa29 --- /dev/null +++ b/dist/types/time/interval.d.ts @@ -0,0 +1,16 @@ +import WAAClock from "waaclock"; + +export default class Interval { + constructor(rate: number, func: (...args: any[]) => void, on: boolean); + rate: number; + on: boolean; + clock: WAAClock; + pattern: number[]; + index: number; + event: any; + _event(e: any): void; + stop(): void; + start(): void; + interval: any; + ms(newrate: number): void; +} diff --git a/dist/types/tuning/tuning.d.ts b/dist/types/tuning/tuning.d.ts new file mode 100644 index 00000000..fc3b6082 --- /dev/null +++ b/dist/types/tuning/tuning.d.ts @@ -0,0 +1,22 @@ +type TuningOutputMode = "frequency" | "ratio" | "MIDI"; +type TuningInputMode = "step" | "midi" | "MIDI"; + +export default class Tune { + scale: number[]; + mode: { + output: TuningOutputMode; + input: TuningInputMode; + }; + etmajor: number[]; + root: number; + note(input: number, octave?: number): number; + frequency(stepIn: number, octaveIn?: number): number; + ratio(stepIn: number, octaveIn?: number): number; + MIDI(stepIn: number, octaveIn?: number): number; + createScale(...args: number[]): void; + createJIScale(...args: number[]): void; + loadScaleFromFrequencies(freqs: number[]): void; + loadScale(name: string): void; + search(letters: string): string[]; + chord(midis: number[]): number[]; +} diff --git a/dist/types/util/cssparse.d.ts b/dist/types/util/cssparse.d.ts new file mode 100644 index 00000000..36f5b7c4 --- /dev/null +++ b/dist/types/util/cssparse.d.ts @@ -0,0 +1 @@ +export function parseSize(element: any): void; diff --git a/dist/types/util/dom.d.ts b/dist/types/util/dom.d.ts new file mode 100644 index 00000000..21c70f25 --- /dev/null +++ b/dist/types/util/dom.d.ts @@ -0,0 +1,19 @@ +export function findPosition(el: any): { + top: any; + left: any; +}; +export function parseElement(parent: any): HTMLElement | SVGElement | "No valid parent argument"; +export function locateMouse(e: any, offset: any): { + x: number; + y: number; +}; +export function locateTouch(e: any, offset: any): { + x: number | boolean; + y: number | boolean; +}; +export class SmartCanvas { + constructor(parent: any); + element: HTMLCanvasElement; + context: CanvasRenderingContext2D | null; + resize(w: any, h: any): void; +} diff --git a/dist/types/util/interaction.d.ts b/dist/types/util/interaction.d.ts new file mode 100644 index 00000000..03ca20d2 --- /dev/null +++ b/dist/types/util/interaction.d.ts @@ -0,0 +1,48 @@ +import ToggleModel from "../models/toggle"; + +type XYPosition = { + x: number; + y: number; +}; +export type HandleDirection = "radial" | "vertical" | "horizontal"; +export type HandleMode = "absolute" | "relative"; + +export class Handle { + constructor( + mode?: string, + direction?: string, + xbound?: [number, number], + ybound?: [number, number] + ); + mode: string; + direction: string; + previous: number; + value: number; + sensitivity: number; + resize(xbound: [number, number], ybound: [number, number]): void; + boundary: { + min: XYPosition; + max: XYPosition; + center: XYPosition; + }; + set anchor(mouse: XYPosition); + // @ts-expect-error: anchor get/set implementation does not respect rule + // ts(2380) of conformity between getter and setter types + get anchor(): number; + _anchor: XYPosition; + update(mouse: XYPosition): void; + convertPositionToValue(current: XYPosition): number; +} + +// FIXME: apparently not used anywhere in the code-base +export class Button { + constructor(mode?: string); + mode: string; + state: ToggleModel; + paintbrush: boolean; + click(): void; + timeout?: number; + position?: XYPosition; + move(): void; + release(): void; +} diff --git a/dist/types/util/math.d.ts b/dist/types/util/math.d.ts new file mode 100644 index 00000000..eff2aff4 --- /dev/null +++ b/dist/types/util/math.d.ts @@ -0,0 +1,37 @@ +import { XYPosition } from "../util/interaction"; + +export function clip(value: number, min: number, max: number): number; +export function normalize(value: any, min: any, max: any): number; +export function scale( + inNum: number, + inMin: number, + inMax: number, + outMin: number, + outMax: number +): number; +export function toPolar( + x: any, + y: any +): { + radius: number; + angle: number; +}; +export function toCartesian(radius: any, angle: any): XYPosition; +export function prune(data: any, scale: any): number; +export function invert(inNum: any): number; +export function mtof(midi: number): number; +export function interp(loc: number, min: number, max: number): number; +export function pick(...args: any[]): any; +export function octave(num: number): number; +export function ri(bound1: number, bound2: number): number; +export function rf(bound1: number, bound2: number): number; +export function cycle(input: any, min: any, max: any): any; +export function average(data: any[]): number; +export function distance( + x1: number, + y1: number, + x2: number, + y2: number +): number; +export function gainToDB(gain: any): number; +export function coin(odds?: number | undefined): number; diff --git a/dist/types/util/svg.d.ts b/dist/types/util/svg.d.ts new file mode 100644 index 00000000..e8dc66c8 --- /dev/null +++ b/dist/types/util/svg.d.ts @@ -0,0 +1,10 @@ +declare namespace _default { + function create(type: any): any; + function arc(x: any, y: any, radius: any, startAngle: any, endAngle: any): string; + function radialGradient(defs: any, numberOfStops: any): { + id: string; + stops: SVGStopElement[]; + element: SVGRadialGradientElement; + }; +} +export default _default; diff --git a/dist/types/util/touch.d.ts b/dist/types/util/touch.d.ts new file mode 100644 index 00000000..787e6bee --- /dev/null +++ b/dist/types/util/touch.d.ts @@ -0,0 +1 @@ +export var exists: boolean; diff --git a/dist/types/util/transform.d.ts b/dist/types/util/transform.d.ts new file mode 100644 index 00000000..5093155a --- /dev/null +++ b/dist/types/util/transform.d.ts @@ -0,0 +1,3 @@ +export function element(element: any, type: any, options: any): any; +export function section(parent: any, keyword: any): {}; +export function add(type: any, parent: any, options: any): any; diff --git a/dist/types/util/util.d.ts b/dist/types/util/util.d.ts new file mode 100644 index 00000000..19701da4 --- /dev/null +++ b/dist/types/util/util.d.ts @@ -0,0 +1,2 @@ +export function isObject(obj: any): boolean; +export function setInputFilter(textbox: any, inputFilter: any): void; From e7cce03325f52c957130bc7c339e0b979d884ec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9is=20Bazin?= Date: Thu, 3 Feb 2022 11:36:44 +0100 Subject: [PATCH 02/12] :memo: Add third dimension in doc --- lib/interfaces/tilt.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/interfaces/tilt.js b/lib/interfaces/tilt.js index 59109e59..a1881ab1 100644 --- a/lib/interfaces/tilt.js +++ b/lib/interfaces/tilt.js @@ -17,7 +17,7 @@ let Interface = require('../core/interface'); * @output * change * Fires at a regular interval, as long as this interface is active (see the interface's .active property)
-* The event data is an object containing x (number) and y (number) properties which represent the current tilt state of the device. +* The event data is an object containing x (number) and y (number) (and, potentially, z (number)) properties which represent the current tilt state of the device. * * @outputexample * tilt.on('change',function(v) { From 1754a1a1b8339c2a360e1a2777bbccacb728403a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9is=20Bazin?= Date: Thu, 3 Feb 2022 12:03:25 +0100 Subject: [PATCH 03/12] :wrench: Provide types location --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index febf0521..b1b1466d 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "type": "git", "url": "https://github.com/nexus-js/ui" }, + "types": "dist/types/index.d.ts", "keywords": [], "author": "Benjamin Taylor", "license": "MIT", From 016eb2ac94f2e4144462f4cf4c1da092820ade7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9is=20Bazin?= Date: Mon, 21 Feb 2022 18:08:57 +0100 Subject: [PATCH 04/12] :bug: Fix column typo in SequencerOptions --- dist/types/interfaces/sequencer.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/types/interfaces/sequencer.d.ts b/dist/types/interfaces/sequencer.d.ts index be8185a8..eee3bf3f 100644 --- a/dist/types/interfaces/sequencer.d.ts +++ b/dist/types/interfaces/sequencer.d.ts @@ -2,7 +2,7 @@ import ButtonTemplate, { ButtonMode, ButtonTemplateOptions, } from "../components/buttontemplate"; -import Interface, { InterfaceOptions } from "../core/interface"; +import Interface from "../core/interface"; import Counter from "../models/counter"; import Matrix from "../models/matrix"; import Interval from "../time/interval"; @@ -29,7 +29,7 @@ export class MatrixCell extends ButtonTemplate { type SequencerOptions = { mode: ButtonMode; rows: number; - column: number; + columns: number; paddingRow: number; paddingColumn: number; }; From 58ecf508dff2fd0de6177dd943ed0e14e5732050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9is=20Bazin?= Date: Tue, 12 Apr 2022 16:52:35 +0200 Subject: [PATCH 05/12] :recycle: Remove usage of `this` --- dist/types/components/buttontemplate.d.ts | 2 +- dist/types/interfaces/button.d.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/types/components/buttontemplate.d.ts b/dist/types/components/buttontemplate.d.ts index 5664373a..dcd088fe 100644 --- a/dist/types/components/buttontemplate.d.ts +++ b/dist/types/components/buttontemplate.d.ts @@ -23,7 +23,7 @@ export default class ButtonTemplate< position: XYPosition; _state: ToggleModel; pad: SVGElement; - interactionTarget: typeof this.pad; + interactionTarget: SVGElement; render(): void; up(): void; bend(mouse: XYPosition): void; diff --git a/dist/types/interfaces/button.d.ts b/dist/types/interfaces/button.d.ts index 2eb1bb02..c8ff58f6 100644 --- a/dist/types/interfaces/button.d.ts +++ b/dist/types/interfaces/button.d.ts @@ -39,7 +39,7 @@ export default class Button extends ButtonTemplate { listener: (value: boolean | XYPosition, ...args: any[]) => void ): this; pad: SVGCircleElement; - interactionTarget: typeof this.pad; + interactionTarget: SVGCircleElement; defs: SVGDefsElement; gradient: SVGRadialGradientElement; render(): void; From f54be82607c0f4838d7f2c1b02b001c28e5f44b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9is=20Bazin?= Date: Tue, 12 Apr 2022 16:56:27 +0200 Subject: [PATCH 06/12] :bug: Add correct type on columns getter --- dist/types/models/matrix.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/types/models/matrix.d.ts b/dist/types/models/matrix.d.ts index 9bcfc07d..b348a64e 100644 --- a/dist/types/models/matrix.d.ts +++ b/dist/types/models/matrix.d.ts @@ -48,5 +48,5 @@ export default class Matrix { set rows(rows: number); get rows(): number; set columns(columns: number); - get columns(): any; + get columns(): number; } From b0066f93b43dcc4ca509860c727c1d7581608db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9is=20Bazin?= Date: Tue, 12 Apr 2022 16:57:28 +0200 Subject: [PATCH 07/12] :recycle: Refactor types to interfaces --- dist/types/interfaces/sequencer.d.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dist/types/interfaces/sequencer.d.ts b/dist/types/interfaces/sequencer.d.ts index eee3bf3f..25a99b9d 100644 --- a/dist/types/interfaces/sequencer.d.ts +++ b/dist/types/interfaces/sequencer.d.ts @@ -7,12 +7,12 @@ import Counter from "../models/counter"; import Matrix from "../models/matrix"; import Interval from "../time/interval"; -type MatrixCellOptions = ButtonTemplateOptions & { +interface MatrixCellOptions extends ButtonTemplateOptions { value: number; paddingRow: number; paddingColumn: number; target: false; -}; +} export class MatrixCell extends ButtonTemplate { pad: SVGRectElement; @@ -26,13 +26,13 @@ export class MatrixCell extends ButtonTemplate { paintbrush: boolean; } -type SequencerOptions = { +interface SequencerOptions { mode: ButtonMode; rows: number; columns: number; paddingRow: number; paddingColumn: number; -}; +} /** * Sequencer From 900384697ffe5a58ef1e55dade6ae7834262eb99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9is=20Bazin?= Date: Tue, 12 Apr 2022 16:58:13 +0200 Subject: [PATCH 08/12] :bug: Remove improper import of InterfaceOptions --- dist/types/components/slidertemplate.d.ts | 2 +- dist/types/interfaces/dial.d.ts | 2 +- dist/types/interfaces/envelope.d.ts | 2 +- dist/types/interfaces/meter.d.ts | 2 +- dist/types/interfaces/multislider.d.ts | 2 +- dist/types/interfaces/number.d.ts | 6 +++--- dist/types/interfaces/oscilloscope.d.ts | 2 +- dist/types/interfaces/pan.d.ts | 2 +- dist/types/interfaces/pan2d.d.ts | 2 +- dist/types/interfaces/piano.d.ts | 2 +- dist/types/interfaces/radiobutton.d.ts | 2 +- dist/types/interfaces/slider.d.ts | 2 +- dist/types/interfaces/spectrogram.d.ts | 2 +- 13 files changed, 15 insertions(+), 15 deletions(-) diff --git a/dist/types/components/slidertemplate.d.ts b/dist/types/components/slidertemplate.d.ts index fce32f18..9a6a1da6 100644 --- a/dist/types/components/slidertemplate.d.ts +++ b/dist/types/components/slidertemplate.d.ts @@ -1,4 +1,4 @@ -import Interface, { InterfaceOptions } from "../core/interface"; +import Interface from "../core/interface"; import Step from "../models/step"; import * as Interaction from "../util/interaction"; import { HandleMode } from "../util/interaction"; diff --git a/dist/types/interfaces/dial.d.ts b/dist/types/interfaces/dial.d.ts index 0e38b583..75be752d 100644 --- a/dist/types/interfaces/dial.d.ts +++ b/dist/types/interfaces/dial.d.ts @@ -1,4 +1,4 @@ -import Interface, { InterfaceOptions } from "../core/interface"; +import Interface from "../core/interface"; import * as Interaction from "../util/interaction"; import { HandleDirection, HandleMode } from "../util/interaction"; import Step, { StepOptions } from "../models/step"; diff --git a/dist/types/interfaces/envelope.d.ts b/dist/types/interfaces/envelope.d.ts index 62012640..ec8518c3 100644 --- a/dist/types/interfaces/envelope.d.ts +++ b/dist/types/interfaces/envelope.d.ts @@ -1,4 +1,4 @@ -import Interface, { InterfaceOptions } from "../core/interface"; +import Interface from "../core/interface"; import { XYPosition } from "../util/interaction"; declare class Point { diff --git a/dist/types/interfaces/meter.d.ts b/dist/types/interfaces/meter.d.ts index d66d2f8c..b27726c6 100644 --- a/dist/types/interfaces/meter.d.ts +++ b/dist/types/interfaces/meter.d.ts @@ -1,4 +1,4 @@ -import Interface, { InterfaceOptions } from "../core/interface"; +import Interface from "../core/interface"; import dom = require("../util/dom"); /** diff --git a/dist/types/interfaces/multislider.d.ts b/dist/types/interfaces/multislider.d.ts index 8c2cc69d..9a09f9e6 100644 --- a/dist/types/interfaces/multislider.d.ts +++ b/dist/types/interfaces/multislider.d.ts @@ -1,4 +1,4 @@ -import Interface, { InterfaceOptions } from "../core/interface"; +import Interface from "../core/interface"; import { StepOptions } from "../models/step"; type MultiSliderMode = "bar" | "line"; diff --git a/dist/types/interfaces/number.d.ts b/dist/types/interfaces/number.d.ts index 6b43aab0..07179813 100644 --- a/dist/types/interfaces/number.d.ts +++ b/dist/types/interfaces/number.d.ts @@ -1,4 +1,4 @@ -import Interface, { InterfaceOptions } from "../core/interface"; +import Interface from "../core/interface"; import Step, { StepOptions } from "../models/step"; type NumberOptions = StepOptions; @@ -79,8 +79,8 @@ export default class Number extends Interface { @param {Interface} element Element to connect to. @example number.link(slider) */ - link( - destination: Interface + link( + destination: Interface ): void; passiveUpdate(value: number): void; } diff --git a/dist/types/interfaces/oscilloscope.d.ts b/dist/types/interfaces/oscilloscope.d.ts index e23c42df..07cdeacc 100644 --- a/dist/types/interfaces/oscilloscope.d.ts +++ b/dist/types/interfaces/oscilloscope.d.ts @@ -1,4 +1,4 @@ -import Interface, { InterfaceOptions } from "../core/interface"; +import Interface from "../core/interface"; import dom = require("../util/dom"); /** diff --git a/dist/types/interfaces/pan.d.ts b/dist/types/interfaces/pan.d.ts index 7db226d7..194406d2 100644 --- a/dist/types/interfaces/pan.d.ts +++ b/dist/types/interfaces/pan.d.ts @@ -2,7 +2,7 @@ import { SliderOrientation, SliderTemplateOptions, } from "../components/slidertemplate"; -import Interface, { InterfaceOptions } from "../core/interface"; +import Interface from "../core/interface"; import Step from "../models/step"; import * as Interaction from "../util/interaction"; diff --git a/dist/types/interfaces/pan2d.d.ts b/dist/types/interfaces/pan2d.d.ts index 36d2ec64..22a48e3d 100644 --- a/dist/types/interfaces/pan2d.d.ts +++ b/dist/types/interfaces/pan2d.d.ts @@ -1,4 +1,4 @@ -import Interface, { InterfaceOptions } from "../core/interface"; +import Interface from "../core/interface"; import Step from "../models/step"; import * as Interaction from "../util/interaction"; diff --git a/dist/types/interfaces/piano.d.ts b/dist/types/interfaces/piano.d.ts index c54da464..13b105a6 100644 --- a/dist/types/interfaces/piano.d.ts +++ b/dist/types/interfaces/piano.d.ts @@ -1,4 +1,4 @@ -import Interface, { InterfaceOptions } from "../core/interface"; +import Interface from "../core/interface"; import ButtonTemplate, { ButtonMode, ButtonTemplateOptions, diff --git a/dist/types/interfaces/radiobutton.d.ts b/dist/types/interfaces/radiobutton.d.ts index 29bdfff0..75222436 100644 --- a/dist/types/interfaces/radiobutton.d.ts +++ b/dist/types/interfaces/radiobutton.d.ts @@ -1,4 +1,4 @@ -import Interface, { InterfaceOptions } from "../core/interface"; +import Interface from "../core/interface"; import Button from "./button"; type RadioButtonOptions = { diff --git a/dist/types/interfaces/slider.d.ts b/dist/types/interfaces/slider.d.ts index ce2f16b8..3a51c58d 100644 --- a/dist/types/interfaces/slider.d.ts +++ b/dist/types/interfaces/slider.d.ts @@ -1,4 +1,4 @@ -import Interface, { InterfaceOptions } from "../core/interface"; +import Interface from "../core/interface"; import Step, { StepOptions } from "../models/step"; import * as Interaction from "../util/interaction"; import { HandleMode } from "../util/interaction"; diff --git a/dist/types/interfaces/spectrogram.d.ts b/dist/types/interfaces/spectrogram.d.ts index d5c3919d..12c4085c 100644 --- a/dist/types/interfaces/spectrogram.d.ts +++ b/dist/types/interfaces/spectrogram.d.ts @@ -1,4 +1,4 @@ -import Interface, { InterfaceOptions } from "../core/interface"; +import Interface from "../core/interface"; import dom = require("../util/dom"); /** From 5d60364de049b3d7d421bfe4468a94947559e06f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9is=20Bazin?= Date: Tue, 12 Apr 2022 17:15:26 +0200 Subject: [PATCH 09/12] :memo: Add @types/waaclock dependency --- package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package.json b/package.json index b1b1466d..58c99bd1 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,9 @@ "url": "https://github.com/nexus-js/ui/issues" }, "homepage": "https://nexus-js.github.io/ui", + "dependencies": { + "@types/waaclock": "^0.5.0" + }, "devDependencies": { "babel-core": "^4.7.16", "babel-jest": "^4.0.0", From e6704513dbe5b2f0cb20b209eeaceb848b3f07cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9is=20Bazin?= Date: Tue, 12 Apr 2022 17:22:06 +0200 Subject: [PATCH 10/12] :bookmark: Bump version number --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 58c99bd1..83f840d2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nexusui", - "version": "2.1.6", + "version": "2.2.0", "description": "NexusUI: Web Audio Interfaces", "main": "dist/NexusUI.js", "scripts": { From 906ac25df796e60000f93bbede8f68f44de15844 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9is=20Bazin?= Date: Fri, 29 Apr 2022 19:18:29 +0200 Subject: [PATCH 11/12] :memo: Simplify over-specific type-signature --- dist/types/interfaces/button.d.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/dist/types/interfaces/button.d.ts b/dist/types/interfaces/button.d.ts index c8ff58f6..aa117d1e 100644 --- a/dist/types/interfaces/button.d.ts +++ b/dist/types/interfaces/button.d.ts @@ -38,9 +38,4 @@ export default class Button extends ButtonTemplate { event: "change", listener: (value: boolean | XYPosition, ...args: any[]) => void ): this; - pad: SVGCircleElement; - interactionTarget: SVGCircleElement; - defs: SVGDefsElement; - gradient: SVGRadialGradientElement; - render(): void; } From 3950e4720d6064755770fcbfd92275a567cb56de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9is=20Bazin?= Date: Wed, 13 Jul 2022 17:16:27 +0200 Subject: [PATCH 12/12] :fire: Untrack .DS_Store files --- .DS_Store | Bin 6148 -> 0 bytes .gitignore | 1 + lib/.DS_Store | Bin 6148 -> 0 bytes 3 files changed, 1 insertion(+) delete mode 100644 .DS_Store delete mode 100644 lib/.DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index ad060841e9b4428b4670b3a4ebcc16873a17baf7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKOHKko5PjtkC2_;jWnY0CbO@e+3-}|31d)Imm$UQQzWP9%8Qi+Ss-)^o*JnEY z7F}HcWcL0v1ttK-R7HHL8H&bL2XYaf5mEFXyUqG_^X#iZ_GyRKHn_(YtB*ye{t8Qc zGV;RM8p~d^p>KtUp7#=aJYvVl7H_@S>HX823?u`|Kr)aF{5J;JvsK2|j%kyDWFQ$h zGNAWEp(@tE*3qsG8XEzK`iwW>x6Km7q7GsWY#r&Lh?f$*RAR&sFQ>mmUJYy=y&Mw5 zhs4ej6N=dG{C}}@NOeq`3?u_x1{z;ZwEy2yf0_TgMY&1_l7X{gKt}V$e8wY1Zyg*? wdu^fKQ4hjgOQ*3`Ote-s>2%40X`wRTRDoVZ}KLCP&kkBE8M}1Yki%(GT^h`ooY`MLYV&MIR>I`7!w0k^or7O#`)(+THZ;0XiX$U5ME zY<9!*%kY?YpC&6S1*Cu!kOERb3jA6D@4dA7Wul@KkOETRTLJ$*G`eFi924Wy!4M+= zamI8Q*D*^Fn`tS2f; z0V!~-z