Adding mouseX() and mouseY() to arrays
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
import { type UserAPI } from "./API";
|
||||
import { safeScale, stepsToScale } from "zifferjs";
|
||||
export {};
|
||||
export { };
|
||||
|
||||
declare global {
|
||||
interface Array<T> {
|
||||
@ -8,6 +8,8 @@ declare global {
|
||||
sub(amount: number): number[];
|
||||
mult(amount: number): number[];
|
||||
div(amount: number): number[];
|
||||
mouseX(): T[],
|
||||
mouseY(): T[],
|
||||
palindrome(): T[];
|
||||
random(index: number): T;
|
||||
rand(index: number): T;
|
||||
@ -34,14 +36,36 @@ declare global {
|
||||
}
|
||||
|
||||
export const makeArrayExtensions = (api: UserAPI) => {
|
||||
Array.prototype.square = function (): number[] {
|
||||
|
||||
Array.prototype.mouseX = function <T>(this: T[]): T {
|
||||
/**
|
||||
* @returns Value from list based on mouse X position
|
||||
*/
|
||||
const mouse_position = api.mouseX();
|
||||
const screenWidth = window.innerWidth;
|
||||
const zoneWidth = screenWidth / this.length;
|
||||
const zoneIndex = Math.floor(mouse_position / zoneWidth);
|
||||
|
||||
return this[zoneIndex];
|
||||
};
|
||||
|
||||
Array.prototype.mouseY = function <T>(this: T[]): T {
|
||||
const mouse_position = api.mouseY();
|
||||
const screenHeight = window.innerHeight;
|
||||
const zoneHeight = screenHeight / this.length;
|
||||
const zoneIndex = Math.floor(mouse_position / zoneHeight);
|
||||
|
||||
return this[zoneIndex];
|
||||
};
|
||||
|
||||
Array.prototype.square = function(): number[] {
|
||||
/**
|
||||
* @returns New array with squared values.
|
||||
*/
|
||||
return this.map((x: number) => x * x);
|
||||
};
|
||||
|
||||
Array.prototype.sometimes = function (func: Function): number[] {
|
||||
Array.prototype.sometimes = function(func: Function): number[] {
|
||||
if (api.randomGen() < 0.5) {
|
||||
return func(this);
|
||||
} else {
|
||||
@ -49,11 +73,11 @@ export const makeArrayExtensions = (api: UserAPI) => {
|
||||
}
|
||||
};
|
||||
|
||||
Array.prototype.apply = function (func: Function): number[] {
|
||||
Array.prototype.apply = function(func: Function): number[] {
|
||||
return func(this);
|
||||
};
|
||||
|
||||
Array.prototype.sqrt = function (): number[] {
|
||||
Array.prototype.sqrt = function(): number[] {
|
||||
/**
|
||||
* @returns New array with square roots of values. Throws if any element is negative.
|
||||
*/
|
||||
@ -62,7 +86,7 @@ export const makeArrayExtensions = (api: UserAPI) => {
|
||||
return this.map((x: number) => Math.sqrt(x));
|
||||
};
|
||||
|
||||
Array.prototype.add = function (amount: number): number[] {
|
||||
Array.prototype.add = function(amount: number): number[] {
|
||||
/**
|
||||
* @param amount - The value to add to each element in the array.
|
||||
* @returns New array with added values.
|
||||
@ -70,7 +94,7 @@ export const makeArrayExtensions = (api: UserAPI) => {
|
||||
return this.map((x: number) => x + amount);
|
||||
};
|
||||
|
||||
Array.prototype.sub = function (amount: number): number[] {
|
||||
Array.prototype.sub = function(amount: number): number[] {
|
||||
/**
|
||||
* @param amount - The value to subtract from each element in the array.
|
||||
* @returns New array with subtracted values.
|
||||
@ -78,7 +102,7 @@ export const makeArrayExtensions = (api: UserAPI) => {
|
||||
return this.map((x: number) => x - amount);
|
||||
};
|
||||
|
||||
Array.prototype.mult = function (amount: number): number[] {
|
||||
Array.prototype.mult = function(amount: number): number[] {
|
||||
/**
|
||||
* @param amount - The value to multiply with each element in the array.
|
||||
* @returns New array with multiplied values.
|
||||
@ -86,7 +110,7 @@ export const makeArrayExtensions = (api: UserAPI) => {
|
||||
return this.map((x: number) => x * amount);
|
||||
};
|
||||
|
||||
Array.prototype.div = function (amount: number): number[] {
|
||||
Array.prototype.div = function(amount: number): number[] {
|
||||
/**
|
||||
* @param amount - The value to divide each element in the array by.
|
||||
* @returns New array with divided values. Throws if division by zero.
|
||||
@ -95,7 +119,7 @@ export const makeArrayExtensions = (api: UserAPI) => {
|
||||
return this.map((x: number) => x / amount);
|
||||
};
|
||||
|
||||
Array.prototype.pick = function () {
|
||||
Array.prototype.pick = function() {
|
||||
/**
|
||||
* Returns a random element from an array.
|
||||
*
|
||||
@ -104,7 +128,7 @@ export const makeArrayExtensions = (api: UserAPI) => {
|
||||
return this[Math.floor(api.randomGen() * this.length)];
|
||||
};
|
||||
|
||||
Array.prototype.gen = function (min: number, max: number, times: number) {
|
||||
Array.prototype.gen = function(min: number, max: number, times: number) {
|
||||
/**
|
||||
* Returns an array of random numbers.
|
||||
* @param min - The minimum value of the random numbers
|
||||
@ -121,7 +145,7 @@ export const makeArrayExtensions = (api: UserAPI) => {
|
||||
);
|
||||
};
|
||||
|
||||
Array.prototype.bar = function (value: number = 1) {
|
||||
Array.prototype.bar = function(value: number = 1) {
|
||||
/**
|
||||
* Returns an element from an array based on the current bar.
|
||||
*
|
||||
@ -136,7 +160,7 @@ export const makeArrayExtensions = (api: UserAPI) => {
|
||||
}
|
||||
};
|
||||
|
||||
Array.prototype.beat = function (divisor: number = 1) {
|
||||
Array.prototype.beat = function(divisor: number = 1) {
|
||||
const chunk_size = divisor; // Get the first argument (chunk size)
|
||||
const timepos = api.app.clock.pulses_since_origin;
|
||||
const slice_count = Math.floor(
|
||||
@ -146,7 +170,7 @@ export const makeArrayExtensions = (api: UserAPI) => {
|
||||
};
|
||||
Array.prototype.b = Array.prototype.beat;
|
||||
|
||||
Array.prototype.shuffle = function () {
|
||||
Array.prototype.shuffle = function() {
|
||||
/**
|
||||
* Shuffles the array in place.
|
||||
*
|
||||
@ -165,7 +189,7 @@ export const makeArrayExtensions = (api: UserAPI) => {
|
||||
return this;
|
||||
};
|
||||
|
||||
Array.prototype.rotate = function (steps: number) {
|
||||
Array.prototype.rotate = function(steps: number) {
|
||||
/**
|
||||
* Rotates the array in place.
|
||||
*
|
||||
@ -185,7 +209,7 @@ export const makeArrayExtensions = (api: UserAPI) => {
|
||||
return this;
|
||||
};
|
||||
|
||||
Array.prototype.unique = function () {
|
||||
Array.prototype.unique = function() {
|
||||
/**
|
||||
* Removes duplicate elements from the array in place.
|
||||
*
|
||||
@ -218,7 +242,7 @@ export const makeArrayExtensions = (api: UserAPI) => {
|
||||
if (this.length <= 1) {
|
||||
return this;
|
||||
}
|
||||
for (let i = 0; i < this.length; ) {
|
||||
for (let i = 0; i < this.length;) {
|
||||
const rand = api.randomGen() * 100;
|
||||
if (rand < amount) {
|
||||
if (this.length > 1) {
|
||||
@ -331,7 +355,7 @@ export const makeArrayExtensions = (api: UserAPI) => {
|
||||
return left_to_right.concat(right_to_left);
|
||||
};
|
||||
|
||||
Array.prototype.loop = function (index: number) {
|
||||
Array.prototype.loop = function(index: number) {
|
||||
/**
|
||||
* Returns an element from the array based on the index.
|
||||
* The index will wrap over the array.
|
||||
@ -342,7 +366,7 @@ export const makeArrayExtensions = (api: UserAPI) => {
|
||||
return this[index % this.length];
|
||||
};
|
||||
|
||||
Array.prototype.random = function () {
|
||||
Array.prototype.random = function() {
|
||||
/**
|
||||
* Returns a random element from the array.
|
||||
*
|
||||
@ -353,7 +377,7 @@ export const makeArrayExtensions = (api: UserAPI) => {
|
||||
Array.prototype.rand = Array.prototype.random;
|
||||
};
|
||||
|
||||
Array.prototype.scale = function (
|
||||
Array.prototype.scale = function(
|
||||
scale: string = "major",
|
||||
base_note: number = 0
|
||||
) {
|
||||
@ -377,7 +401,7 @@ Array.prototype.scale = function (
|
||||
});
|
||||
};
|
||||
|
||||
Array.prototype.scaleArp = function (
|
||||
Array.prototype.scaleArp = function(
|
||||
scaleName: string = "major",
|
||||
boundary: number = 0
|
||||
) {
|
||||
|
||||
@ -23,7 +23,7 @@ beat([0.5, 1].beat(4)) :: sound('kick').out()
|
||||
beat(2)::snd('snare').shape(.5).out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
)}
|
||||
${makeExample(
|
||||
"Using beat to create arpeggios",
|
||||
`
|
||||
@ -40,7 +40,7 @@ beat([.5, .25].beat(2)) :: sound('sine')
|
||||
.out()
|
||||
`,
|
||||
false
|
||||
)}
|
||||
)}
|
||||
${makeExample(
|
||||
"Cool ambiance",
|
||||
`
|
||||
@ -50,7 +50,7 @@ flip(2)::beat(1)::snd('clap').out()
|
||||
flip(4)::beat(2)::snd('pad').n(2).shape(.5).orbit(2).room(0.9).size(0.9).release(0.5).out()
|
||||
`,
|
||||
false
|
||||
)}
|
||||
)}
|
||||
|
||||
- <ic>bar(value: number = 1)</ic>: returns the next value every bar (if <ic>value = 1</ic>). Using a larger value will return the next value every <ic>n</ic> bars.
|
||||
|
||||
@ -61,7 +61,7 @@ beat(1)::sound(['kick', 'hat', 'snare', 'hat'].beat()).out()
|
||||
beat(1.5)::sound(['jvbass', 'clap'].beat()).out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
)}
|
||||
|
||||
${makeExample(
|
||||
"Using beat, pulse and bar in the same code",
|
||||
@ -71,7 +71,19 @@ beat([1, 0.5].beat()) :: sound(['bass3'].bar())
|
||||
.speed([1,2,3].pulse())
|
||||
.out()
|
||||
`
|
||||
)}
|
||||
)}
|
||||
|
||||
- <ic>mouseX()</ic> / <ic>mouseY()</ic>: divides the screen in <ic>n</ic> zones and returns the value corresponding to the mouse position on screen.</ic>
|
||||
|
||||
${makeExample(
|
||||
"Controlling an arpeggio (octave and note) with mouse", `
|
||||
beat(0.25)::sound('wt_piano')
|
||||
.note([0,2,3,4,5,7,8,9,11,12].scale(
|
||||
'minor', 30 + [0,12,24].mouseY()).mouseX())
|
||||
.room(0.5).size(4).lpad(-2, .2).lpf(500, 0.3)
|
||||
.ad(0, .2).out()
|
||||
`, true
|
||||
)}
|
||||
|
||||
- <ic>palindrome()</ic>: Concatenates a list with the same list in reverse.
|
||||
|
||||
@ -87,7 +99,7 @@ beat([1,.5,.25].beat()) :: snd('sine')
|
||||
.out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
)}
|
||||
|
||||
- <ic>random(index: number)</ic>: pick a random element in the given list.
|
||||
- <ic>rand(index: number)</ic>: shorter alias for the same method.
|
||||
@ -106,13 +118,13 @@ beat([.5, 1].random() / 2) :: snd(
|
||||
.end(0.2).out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
)}
|
||||
|
||||
${makeExample(
|
||||
"Generate a list of random numbers",
|
||||
`beat(0.5) && sound('arp').freq([].gen(300,600,10).beat(3)).out()`,
|
||||
true
|
||||
)}
|
||||
)}
|
||||
|
||||
- <ic>degrade(amount: number)</ic>: removes _n_% of the list elements. Lists can be degraded as long as one element remains. The amount of degradation is given as a percentage.
|
||||
|
||||
@ -123,7 +135,7 @@ ${makeExample(
|
||||
beat(.25)::snd('amencutup').n([1,2,3,4,5,6,7,8,9].degrade(20).loop($(1))).out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
)}
|
||||
|
||||
- <ic>repeat(amount: number)</ic>: repeat every list elements _n_ times.
|
||||
- <ic>repeatEven(amount: number)</ic>: repeaet every pair element of the list _n_ times.
|
||||
@ -136,7 +148,7 @@ ${makeExample(
|
||||
beat(.25)::sound('amencutup').n([1,2,3,4,5,6,7,8].repeatAll(4).beat()).out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
)}
|
||||
|
||||
- <ic>loop(index: number)</ic>: loop takes one argument, the _index_. It allows you to iterate over a list using an iterator such as a counter. This is super useful to control how you are accessing values in a list without relying on a temporal method such as <ic>.beat()</ic> or </ic>.bar()</ic>.
|
||||
|
||||
@ -146,7 +158,7 @@ ${makeExample(
|
||||
beat(1) :: sound('numbers').n([1,2,3,4,5].loop($(3, 10, 2))).out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
)}
|
||||
|
||||
- <ic>shuffle(): this</ic>: shuffles a list! Simple enough!
|
||||
|
||||
@ -156,7 +168,7 @@ ${makeExample(
|
||||
beat(1) :: sound('numbers').n([1,2,3,4,5].shuffle().loop($(1)).out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
)}
|
||||
|
||||
- <ic>rotate(steps: number)</ic>: rotate a list to the right _n_ times. The last value become the first, rinse and repeat.
|
||||
|
||||
@ -171,7 +183,7 @@ beat(.5) :: snd('sine')
|
||||
.out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
)}
|
||||
|
||||
- <ic>unique()</ic>: filter a list to remove repeated values.
|
||||
|
||||
@ -182,7 +194,7 @@ ${makeExample(
|
||||
beat(1)::snd('sine').sustain(0.1).freq([100,100,100,100,200].unique().beat()).out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
)}
|
||||
|
||||
- <ic>scale(scale: string, base note: number)</ic>: Map each element of the list to the closest note of the slected scale. [0, 2, 3, 5 ].scale("major", 50) returns [50, 52, <ic>54</ic>, 55]. You can use western scale names like (Major, Minor, Minor pentatonic ...) or [zeitler](https://ianring.com/musictheory/scales/traditions/zeitler) scale names. Alternatively you can also use the integers as used by Ian Ring in his [study of scales](https://ianring.com/musictheory/scales/).
|
||||
|
||||
@ -194,7 +206,7 @@ beat(1) :: snd('gtr')
|
||||
.out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
)}
|
||||
|
||||
- <ic>scaleArp(scale: string, mask: number)</ic>: extrapolate a custom-masked scale from each list elements. [0].scale("major", 3) returns [0,2,4]. <ic>scaleArp</ic> supports the same scales as <ic>scale</ic>.
|
||||
|
||||
@ -206,7 +218,7 @@ beat(1) :: snd('gtr')
|
||||
.out()
|
||||
`,
|
||||
true
|
||||
)}
|
||||
)}
|
||||
|
||||
|
||||
- <ic>add()</ic>: add a given amount to every list element.
|
||||
|
||||
Reference in New Issue
Block a user