diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 82f94394..94f46f44 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -392,7 +392,7 @@ export const { loop } = registerControl('loop'); * @synonyms loopb * @example * s("space").loop(1) - * .loopBegin("<0 .125 .25>").scope() + * .loopBegin("<0 .125 .25>")._scope() */ export const { loopBegin, loopb } = registerControl('loopBegin', 'loopb'); /** @@ -405,7 +405,7 @@ export const { loopBegin, loopb } = registerControl('loopBegin', 'loopb'); * @synonyms loope * @example * s("space").loop(1) - * .loopEnd("<1 .75 .5 .25>").scope() + * .loopEnd("<1 .75 .5 .25>")._scope() */ export const { loopEnd, loope } = registerControl('loopEnd', 'loope'); /** diff --git a/packages/draw/pianoroll.mjs b/packages/draw/pianoroll.mjs index d0480ef5..2c6742cd 100644 --- a/packages/draw/pianoroll.mjs +++ b/packages/draw/pianoroll.mjs @@ -67,6 +67,7 @@ Pattern.prototype.pianoroll = function (options = {}) { * Displays a midi-style piano roll * * @name pianoroll + * @synonyms punchcard * @param {Object} options Object containing all the optional following parameters as key value pairs: * @param {integer} cycles number of cycles to be displayed at the same time - defaults to 4 * @param {number} playhead location of the active notes on the time axis - 0 to 1, defaults to 0.5 @@ -94,7 +95,11 @@ Pattern.prototype.pianoroll = function (options = {}) { * @param {boolean} autorange automatically calculate the minMidi and maxMidi parameters - 0 by default * * @example - * note("C2 A2 G2").euclid(5,8).s('piano').clip(1).color('salmon').pianoroll({vertical:1, labels:1}) + * note("c2 a2 eb2") + * .euclid(5,8) + * .s('sawtooth') + * .lpenv(4).lpf(300) + * ._pianoroll({ labels: 1 }) */ export function pianoroll({ time, @@ -113,7 +118,7 @@ export function pianoroll({ maxMidi = 90, autorange = 0, timeframe: timeframeProp, - fold = 0, + fold = 1, vertical = 0, labels = false, fill = 1, diff --git a/packages/draw/pitchwheel.mjs b/packages/draw/pitchwheel.mjs index 8d3cfe61..ba76df07 100644 --- a/packages/draw/pitchwheel.mjs +++ b/packages/draw/pitchwheel.mjs @@ -113,6 +113,23 @@ export function pitchwheel({ return; } +/** + * Renders a pitch circle to visualize frequencies within one octave + * @name pitchwheel + * @param {number} hapcircles + * @param {number} circle + * @param {number} edo + * @param {string} root + * @param {number} thickness + * @param {number} hapRadius + * @param {string} mode + * @param {number} margin + * @example + * n("0 .. 12").scale("C:chromatic") + * .s("sawtooth") + * .lpf(500) + * ._pitchwheel() + */ Pattern.prototype.pitchwheel = function (options = {}) { let { ctx = getDrawContext(), id = 1 } = options; return this.tag(id).onPaint((_, time, haps) => diff --git a/packages/draw/spiral.mjs b/packages/draw/spiral.mjs index 22f93f5d..cebf3d37 100644 --- a/packages/draw/spiral.mjs +++ b/packages/draw/spiral.mjs @@ -125,6 +125,33 @@ function drawSpiral(options) { }); } +/** + * Displays a spiral visual. + * + * @name spiral + * @param {Object} options Object containing all the optional following parameters as key value pairs: + * @param {number} stretch controls the rotations per cycle ratio, where 1 = 1 cycle / 360 degrees + * @param {number} size the diameter of the spiral + * @param {number} thickness line thickness + * @param {string} cap style of line ends: butt (default), round, square + * @param {string} inset number of rotations before spiral starts (default 3) + * @param {string} playheadColor color of playhead, defaults to white + * @param {number} playheadLength length of playhead in rotations, defaults to 0.02 + * @param {number} playheadThickness thickness of playheadrotations, defaults to thickness + * @param {number} padding space around spiral + * @param {number} steady steadyness of spiral vs playhead. 1 = spiral doesn't move, playhead does. + * @param {number} activeColor color of active segment. defaults to foreground of theme + * @param {number} inactiveColor color of inactive segments. defaults to gutterForeground of theme + * @param {boolean} colorizeInactive wether or not to colorize inactive segments, defaults to 0 + * @param {boolean} fade wether or not past and future should fade out. defaults to 1 + * @param {boolean} logSpiral wether or not the spiral should be logarithmic. defaults to 0 + * @example + * note("c2 a2 eb2") + * .euclid(5,8) + * .s('sawtooth') + * .lpenv(4).lpf(300) + * ._spiral({ steady: .96 }) + */ Pattern.prototype.spiral = function (options = {}) { return this.onPaint((ctx, time, haps, drawTime) => drawSpiral({ ctx, time, haps, drawTime, ...options })); }; diff --git a/packages/webaudio/scope.mjs b/packages/webaudio/scope.mjs index fbf4c8fc..e423b20f 100644 --- a/packages/webaudio/scope.mjs +++ b/packages/webaudio/scope.mjs @@ -130,7 +130,7 @@ Pattern.prototype.fscope = function (config = {}) { * @param {number} pos y-position relative to screen height. 0 = top, 1 = bottom of screen * @param {number} trigger amplitude value that is used to align the scope. defaults to 0. * @example - * s("sawtooth").scope() + * s("sawtooth")._scope() */ let latestColor = {}; Pattern.prototype.tscope = function (config = {}) { diff --git a/website/src/docs/MiniRepl.jsx b/website/src/docs/MiniRepl.jsx index 3559b341..56548471 100644 --- a/website/src/docs/MiniRepl.jsx +++ b/website/src/docs/MiniRepl.jsx @@ -34,9 +34,9 @@ export function MiniRepl({ }) { const code = tunes ? tunes[0] : tune; const id = useMemo(() => s4(), []); - const canvasId = useMemo(() => `canvas-${id}`, [id]); - autodraw = !!punchcard || !!claviature || !!autodraw; const shouldShowCanvas = !!punchcard; + const canvasId = shouldShowCanvas ? useMemo(() => `canvas-${id}`, [id]) : null; + autodraw = !!punchcard || !!claviature || !!autodraw; drawTime = drawTime ?? punchcard ? [0, 4] : [-2, 2]; if (claviature) { drawTime = [0, 0]; diff --git a/website/src/pages/learn/visual-feedback.mdx b/website/src/pages/learn/visual-feedback.mdx index ed5b16c2..25eae30c 100644 --- a/website/src/pages/learn/visual-feedback.mdx +++ b/website/src/pages/learn/visual-feedback.mdx @@ -31,55 +31,70 @@ You can change the color as well, even pattern it: .color("cyan magenta")`} /> -## Pianoroll and Punchcard +## Global vs Inline Visuals + +The following functions all come with in 2 variants. + +**Without prefix**: renders the visual to the background of the page: + + + +**With `_` prefix**: renders the visual inside the code. Allows for multiple visuals + + + +Here we see the 2 variants for `punchcard`. The same goes for all others below. +To improve readability the following demos will all use the inline variant. + +## Punchcard / Pianoroll + +These 2 functions render a pianoroll style visual. +The only difference between the 2 is that `pianoroll` will render the pattern directly, +while `punchcard` will also take the transformations into account that occur afterwards: *8") -.scale("/4:minor:pentatonic") -.s("supersaw").lpf(300).lpenv("<4 3 2>*4") -._punchcard()`} + tune={`note("c a f e").color("white") +._punchcard() +.color("cyan")`} autodraw /> +Here, the `color` is still visible in the visual, even if it is applied after `_punchcard`. +On the contrary, the color is not visible when using `_pianoroll`: + *8") -.scale("/4:minor:pentatonic") -.s("supersaw").lpf(300).lpenv("<4 3 2>\*4") -.\_pianoroll()`} + tune={`note("c a f e").color("white") +._pianoroll() +.color("cyan")`} autodraw /> +import Box from '@components/Box.astro'; + +
+ + + +`punchcard` is less resource intensive because it uses the same data as used for the mini notation highlighting. + + + +The visual can be customized by passing options. Those options are the same for both functions. + +What follows is the API doc of all the options you can pass: + + + ## Spiral -*8") -.scale("/4:minor:pentatonic") -.s("supersaw").lpf(300).lpenv("<4 3 2>*4") -._spiral()`} - autodraw -/> + ## Scope -*8") -.scale("/4:minor:pentatonic") -.s("supersaw").lpf(300).lpenv("<4 3 2>*4") -._scope()`} -/> + ## Pitchwheel -*8") -.scale("/4:minor:pentatonic") -.s("supersaw").lpf(300).lpenv("<4 3 2>*4") -._pitchwheel()`} -/> - -{/* */} +