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()`}
-/>
-
-{/* */}
+