├── .gitignore
├── LICENSE
├── README.md
├── examples
├── crazy_patterns
│ ├── index.html
│ ├── libraries
│ │ ├── p5.min.js
│ │ └── p5.sound.min.js
│ ├── sketch.js
│ └── style.css
├── gradients
│ ├── index.html
│ ├── libraries
│ │ ├── p5.min.js
│ │ └── p5.sound.min.js
│ ├── sketch.js
│ └── style.css
└── patterns
│ ├── brick_small.jpg
│ ├── index.html
│ ├── libraries
│ ├── p5.min.js
│ └── p5.sound.min.js
│ ├── sketch.js
│ └── style.css
├── p5.patgrad.js
└── patterns.gif
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | ANTI-CAPITALIST SOFTWARE LICENSE (v 1.4)
2 |
3 | Copyright © 2021 Sam Lavigne
4 |
5 | This is anti-capitalist software, released for free use by individuals and
6 | organizations that do not operate by capitalist principles.
7 |
8 | Permission is hereby granted, free of charge, to any person or organization
9 | (the "User") obtaining a copy of this software and associated documentation
10 | files (the "Software"), to use, copy, modify, merge, distribute, and/or sell
11 | copies of the Software, subject to the following conditions:
12 |
13 | 1. The above copyright notice and this permission notice shall be included in
14 | all copies or modified versions of the Software.
15 |
16 | 2. The User is one of the following: a. An individual person, laboring for
17 | themselves b. A non-profit organization c. An educational institution d. An
18 | organization that seeks shared profit for all of its members, and allows
19 | non-members to set the cost of their labor
20 |
21 | 3. If the User is an organization with owners, then all owners are workers and
22 | all workers are owners with equal equity and/or equal vote.
23 |
24 | 4. If the User is an organization, then the User is not law enforcement or
25 | military, or working for or under either.
26 |
27 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY
28 | KIND, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
29 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE
30 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
31 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
32 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # p5.PatGrad
2 |
3 | 
4 |
5 | p5.patgrad.js a relatively easy way to add patterns and gradients to your p5.js sketches. Read below for brief examples and functionality, or see the [examples](https://github.com/antiboredom/p5.patgrad/tree/main/examples) folder.
6 |
7 | ## Installation
8 |
9 | [Download the library](https://raw.githubusercontent.com/antiboredom/p5.patgrad/main/p5.patgrad.js) and add the script tag to your index.html file, after you load in p5:
10 |
11 | ```html
12 |
13 | ```
14 |
15 | Or just load it up from github:
16 |
17 | ```html
18 |
19 | ```
20 |
21 | ## Patterns
22 |
23 | You can create repeating patterns from images or from p5Graphics objects using the `createPattern()` function, and then use them to fill shapes with `fillPattern()`, or stroke shapes with `strokePattern()`.
24 |
25 | ### Image patterns
26 |
27 | To use with images, just load an image and then create a new pattern with `createPattern(img)`.
28 |
29 | ```javascript
30 | let pattern;
31 | let img;
32 |
33 | function preload() {
34 | img = loadImage("pattern.png");
35 | }
36 |
37 | function setup() {
38 | createCanvas(500, 500);
39 | pattern = createPattern(img);
40 | }
41 |
42 | function draw() {
43 | background(255);
44 |
45 | fillPattern(pattern);
46 | ellipse(0, 0, 200, 200);
47 | }
48 | ```
49 |
50 | ### Graphics patterns
51 |
52 | You can also create a p5 Graphics object and use that for your pattern.
53 |
54 | ```javascript
55 | let pattern;
56 |
57 | function setup() {
58 | createCanvas(500, 500);
59 | let buffer = createGraphics(5, 5);
60 | buffer.pixelDensity(1);
61 | buffer.background(255);
62 | buffer.line(0, 0, 5, 5);
63 | pattern = createPattern(buffer);
64 | }
65 |
66 | function draw() {
67 | background(255);
68 |
69 | fillPattern(pattern);
70 | rect(0, 0, 200, 200);
71 | }
72 | ```
73 |
74 | ## Gradients
75 |
76 | Use the `createLinearGradient()`, `createRadialGradient()`, or `createConicGradient()` to make gradients, set their colors with the `colors()` function, and then apply them to shapes with `fillGradient()`.
77 |
78 | ```javascript
79 | let gradient;
80 |
81 | function setup() {
82 | createCanvas(400, 400);
83 | // create a linear gradient that's angled at 0 radians, and is 200px wide
84 | gradient = createLinearGradient(0, 200);
85 | // add some colors
86 | // at 0% make it lightblue, then at 50% make it pink, and at 100% make it magenta
87 | gradient.colors(0, "lightblue", 0.5, "pink", 1, "magenta");
88 | }
89 |
90 | function draw() {
91 | background(255);
92 |
93 | fillGradient(gradient);
94 | rect(0, 0, 200, 200);
95 | }
96 | ```
97 |
98 | ## Caveats
99 |
100 | Because of the (perhaps strange) way that the canvas api deals with gradients and patterns, you **must** use `translate()` to position your shapes if they are not located at `(0, 0)`. You also have to call the `fillPattern` and `fillGradient` functions _outside_ of `push` and `pop`. For example, to use a pattern in a shape that follows the mouse:
101 |
102 | ```javascript
103 | function draw() {
104 | background(255);
105 |
106 | fillPattern(pattern);
107 |
108 | push();
109 | translate(mouseX, mouseY);
110 | rect(0, 0, 200, 200);
111 | pop();
112 | }
113 | ```
114 |
115 | ALSO, if you're using a graphics object as a pattern, set it's pixel density to 1 to avoid everything being twice as big as you intended...
116 |
117 | ## Functions
118 |
119 | ### `createPattern(patternElement, repeat)`
120 |
121 | Creates a pattern, and return a pattern object.
122 |
123 | `patternElement`: can either be an image, p5Graphics object, video, or a canvas.
124 |
125 | `repeat`: determines how the pattern is repeated. Can either be `"repeat"` (default), `"no-repeat"`, `"repeat-x"` or `"repeat-y"`.
126 |
127 | ---
128 |
129 | ### `fillPattern(pattern)`
130 |
131 | Sets the fill style to your pattern. Just like the `fill()` function.
132 |
133 | ---
134 |
135 | ### `strokePattern(pattern)`
136 |
137 | Sets the stroke style to your pattern. Just like the `stroke()` function.
138 |
139 | ---
140 |
141 | ### `backgroundPattern(pattern)`
142 |
143 | Sets the background to your pattern.
144 |
145 | ---
146 |
147 | ### `createLinearGradient(angle, width)`
148 |
149 | Creates a linear gradient and returns a gradient object.
150 |
151 | `angle`: the angle of the gradient (by default 0, in radians)
152 |
153 | `width`: how wide the gradient should be.
154 |
155 | ---
156 |
157 | ### `createRadialGradient(innerRadius, outerRadius, x, y)`
158 |
159 | Creates a radial gradient and returns a gradient object.
160 |
161 | `innerRadius`: the inner radius of the gradient
162 |
163 | `outerRadius`: the outer radius of the gradient
164 |
165 | `x`: the x position of the gradient (optional)
166 |
167 | `y`: the y position of the gradient (optional)
168 |
169 | ---
170 |
171 | ### `createConicGradient(angle, x, y)`
172 |
173 | Creates a conic gradient and returns a gradient object.
174 |
175 | `angle`: the start angle of the gradient
176 |
177 | `x`: the x position of the gradient
178 |
179 | `y`: the y position of the gradient
180 |
181 | ---
182 |
183 | ### `Gradient.colors(position1, color1, position2, color2...)`
184 |
185 | Fills a gradient with colors. Takes any number of position (a number from 0 to 1) and color values. You can also call the function multiple times to continue to add colors.
186 |
187 | `position`: where the color should start. Must be a number between 0 and 1, where 0 represents 0% and 1 represents 100%.
188 |
189 | `color`: a color to start at the position you've selected. Can be a p5 color (using the `color()` function), or anything that's recognizable as a css color (a hex value, a color name, etc).
190 |
191 | Example:
192 |
193 | ```javascript
194 | let gradient = createLinearGradient(0, 100);
195 |
196 | // this works
197 | gradient.colors(0, 'red', 1, 'blue')
198 |
199 | // so does this
200 | gradient.colors(0, 'red', 0.5, 'blue', 0.75, 'orange', 1, 'magenta`)
201 |
202 | // so does this
203 | gradient.colors(0, color(255, 0, 0), 1, color(255, 255, 0));
204 | ```
205 |
206 | ---
207 |
208 | ### `fillGradient(gradient)`
209 |
210 | Sets the fill style to your gradient. Just like the `fill()` function.
211 |
212 | ---
213 |
214 | ### `strokeGradient(gradient)`
215 |
216 | Sets the stroke style to your gradient. Just like the `stroke()` function.
217 |
218 | ---
219 |
220 | ### `backgroundGradient(gradient)`
221 |
222 | Sets the background to your gradient.
223 |
--------------------------------------------------------------------------------
/examples/crazy_patterns/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Sketch
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/examples/crazy_patterns/sketch.js:
--------------------------------------------------------------------------------
1 | let shapes = [];
2 |
3 | function setup() {
4 | createCanvas(500, 500);
5 | let w = width;
6 | for (let i = 0; i < 20; i++) {
7 | let buffer = createGraphics(5, 5);
8 | buffer.pixelDensity(1);
9 | buffer.background(255);
10 | buffer.stroke(0);
11 | buffer.strokeWeight(1);
12 | buffer.line(random(5), random(5), random(5), random(5));
13 | buffer.ellipse(0, 0, random(5), random(5));
14 |
15 | shapes.push({
16 | pattern: createPattern(buffer),
17 | w: w,
18 | speed: random(100, 1000),
19 | });
20 | w -= 25;
21 | }
22 | }
23 |
24 | function draw() {
25 | backgroundPattern(shapes[0].pattern);
26 |
27 | for (let s of shapes) {
28 | fillPattern(s.pattern);
29 | noStroke();
30 | push();
31 | translate(width / 2, height / 2);
32 | rotate(frameCount / s.speed);
33 | ellipse(0, 0, s.w, s.w);
34 | pop();
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/examples/crazy_patterns/style.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | margin: 0;
3 | padding: 0;
4 | }
5 |
6 | canvas {
7 | display: block;
8 | }
9 |
--------------------------------------------------------------------------------
/examples/gradients/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Sketch
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/examples/gradients/libraries/p5.sound.min.js:
--------------------------------------------------------------------------------
1 | /** [p5.sound] Version: 1.0.1 - 2021-05-25 */
2 | !function(n){var i={};function r(t){if(i[t])return i[t].exports;var e=i[t]={i:t,l:!1,exports:{}};return n[t].call(e.exports,e,e.exports,r),e.l=!0,e.exports}r.m=n,r.c=i,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)r.d(n,i,function(t){return e[t]}.bind(null,i));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=40)}([function(t,e,n){var i;void 0===(i=function(){"use strict";function l(t,e){this.isUndef(t)||1===t?this.input=this.context.createGain():1t)this.cancelScheduledValues(t),this.linearRampToValueAtTime(e,t);else{var i=this._searchAfter(t);i&&(this.cancelScheduledValues(t),i.type===u.TimelineSignal.Type.Linear?this.linearRampToValueAtTime(e,t):i.type===u.TimelineSignal.Type.Exponential&&this.exponentialRampToValueAtTime(e,t)),this.setValueAtTime(e,t)}return this},u.TimelineSignal.prototype.linearRampToValueBetween=function(t,e,n){return this.setRampPoint(e),this.linearRampToValueAtTime(t,n),this},u.TimelineSignal.prototype.exponentialRampToValueBetween=function(t,e,n){return this.setRampPoint(e),this.exponentialRampToValueAtTime(t,n),this},u.TimelineSignal.prototype._searchBefore=function(t){return this._events.get(t)},u.TimelineSignal.prototype._searchAfter=function(t){return this._events.getAfter(t)},u.TimelineSignal.prototype.getValueAtTime=function(t){t=this.toSeconds(t);var e=this._searchAfter(t),n=this._searchBefore(t),i=this._initial;if(null===n)i=this._initial;else if(n.type===u.TimelineSignal.Type.Target){var r,o=this._events.getBefore(n.time);r=null===o?this._initial:o.value,i=this._exponentialApproach(n.time,r,n.value,n.constant,t)}else i=n.type===u.TimelineSignal.Type.Curve?this._curveInterpolate(n.time,n.value,n.duration,t):null===e?n.value:e.type===u.TimelineSignal.Type.Linear?this._linearInterpolate(n.time,n.value,e.time,e.value,t):e.type===u.TimelineSignal.Type.Exponential?this._exponentialInterpolate(n.time,n.value,e.time,e.value,t):n.value;return i},u.TimelineSignal.prototype.connect=u.SignalBase.prototype.connect,u.TimelineSignal.prototype._exponentialApproach=function(t,e,n,i,r){return n+(e-n)*Math.exp(-(r-t)/i)},u.TimelineSignal.prototype._linearInterpolate=function(t,e,n,i,r){return e+(r-t)/(n-t)*(i-e)},u.TimelineSignal.prototype._exponentialInterpolate=function(t,e,n,i,r){return(e=Math.max(this._minOutput,e))*Math.pow(i/e,(r-t)/(n-t))},u.TimelineSignal.prototype._curveInterpolate=function(t,e,n,i){var r=e.length;if(t+n<=i)return e[r-1];if(i<=t)return e[0];var o=(i-t)/n,s=Math.floor((r-1)*o),a=Math.ceil((r-1)*o),u=e[s],c=e[a];return a===s?u:this._linearInterpolate(s,u,a,c,o*(r-1))},u.TimelineSignal.prototype.dispose=function(){u.Signal.prototype.dispose.call(this),u.Param.prototype.dispose.call(this),this._events.dispose(),this._events=null},u.TimelineSignal}.apply(e,i))||(t.exports=r)},function(t,e,n){var i,r;i=[n(0),n(4),n(1),n(2)],void 0===(r=function(n){"use strict";return n.Scale=function(t,e){this._outputMin=this.defaultArg(t,0),this._outputMax=this.defaultArg(e,1),this._scale=this.input=new n.Multiply(1),this._add=this.output=new n.Add(0),this._scale.connect(this._add),this._setRange()},n.extend(n.Scale,n.SignalBase),Object.defineProperty(n.Scale.prototype,"min",{get:function(){return this._outputMin},set:function(t){this._outputMin=t,this._setRange()}}),Object.defineProperty(n.Scale.prototype,"max",{get:function(){return this._outputMax},set:function(t){this._outputMax=t,this._setRange()}}),n.Scale.prototype._setRange=function(){this._add.value=this._outputMin,this._scale.value=this._outputMax-this._outputMin},n.Scale.prototype.dispose=function(){return n.prototype.dispose.call(this),this._add.dispose(),this._add=null,this._scale.dispose(),this._scale=null,this},n.Scale}.apply(e,i))||(t.exports=r)},function(t,e,n){var i,r;i=[n(0),n(16),n(30),n(31),n(12)],void 0===(r=function(e){return e.Type={Default:"number",Time:"time",Frequency:"frequency",TransportTime:"transportTime",Ticks:"ticks",NormalRange:"normalRange",AudioRange:"audioRange",Decibels:"db",Interval:"interval",BPM:"bpm",Positive:"positive",Cents:"cents",Degrees:"degrees",MIDI:"midi",BarsBeatsSixteenths:"barsBeatsSixteenths",Samples:"samples",Hertz:"hertz",Note:"note",Milliseconds:"milliseconds",Seconds:"seconds",Notation:"notation"},e.prototype.toSeconds=function(t){return this.isNumber(t)?t:this.isUndef(t)?this.now():this.isString(t)?new e.Time(t).toSeconds():t instanceof e.TimeBase?t.toSeconds():void 0},e.prototype.toFrequency=function(t){return this.isNumber(t)?t:this.isString(t)||this.isUndef(t)?new e.Frequency(t).valueOf():t instanceof e.TimeBase?t.toFrequency():void 0},e.prototype.toTicks=function(t){return this.isNumber(t)||this.isString(t)?new e.TransportTime(t).toTicks():this.isUndef(t)?e.Transport.ticks:t instanceof e.TimeBase?t.toTicks():void 0},e}.apply(e,i))||(t.exports=r)},function(t,e,n){var i,r;i=[n(0),n(18),n(9)],void 0===(r=function(n){"use strict";return window.GainNode&&!AudioContext.prototype.createGain&&(AudioContext.prototype.createGain=AudioContext.prototype.createGainNode),n.Gain=function(){var t=this.optionsObject(arguments,["gain","units"],n.Gain.defaults);this.input=this.output=this._gainNode=this.context.createGain(),this.gain=new n.Param({param:this._gainNode.gain,units:t.units,value:t.gain,convert:t.convert}),this._readOnly("gain")},n.extend(n.Gain),n.Gain.defaults={gain:1,convert:!0},n.Gain.prototype.dispose=function(){n.Param.prototype.dispose.call(this),this._gainNode.disconnect(),this._gainNode=null,this._writable("gain"),this.gain.dispose(),this.gain=null},n.prototype.createInsOuts=function(t,e){1===t?this.input=new n.Gain:1this._nextTick&&this._state;){var e=this._state.getValueAtTime(this._nextTick);if(e!==this._lastState){this._lastState=e;var n=this._state.get(this._nextTick);e===r.State.Started?(this._nextTick=n.time,this.isUndef(n.offset)||(this.ticks=n.offset),this.emit("start",n.time,this.ticks)):e===r.State.Stopped?(this.ticks=0,this.emit("stop",n.time)):e===r.State.Paused&&this.emit("pause",n.time)}var i=this._nextTick;this.frequency&&(this._nextTick+=1/this.frequency.getValueAtTime(this._nextTick),e===r.State.Started&&(this.callback(i),this.ticks++))}},r.Clock.prototype.getStateAtTime=function(t){return t=this.toSeconds(t),this._state.getValueAtTime(t)},r.Clock.prototype.dispose=function(){r.Emitter.prototype.dispose.call(this),this.context.off("tick",this._boundLoop),this._writable("frequency"),this.frequency.dispose(),this.frequency=null,this._boundLoop=null,this._nextTick=1/0,this.callback=null,this._state.dispose(),this._state=null},r.Clock}.apply(e,i))||(t.exports=r)},function(t,e,n){var i,r;i=[n(0),n(14)],void 0===(r=function(i){function t(t,e,n){if(t.input)Array.isArray(t.input)?(i.prototype.isUndef(n)&&(n=0),this.connect(t.input[n])):this.connect(t.input,e,n);else try{t instanceof AudioNode?r.call(this,t,e,n):r.call(this,t,e)}catch(e){throw new Error("error connecting to node: "+t+"\n"+e)}}var r,o;return!window.hasOwnProperty("AudioContext")&&window.hasOwnProperty("webkitAudioContext")&&(window.AudioContext=window.webkitAudioContext),i.Context=function(t){for(var e in i.Emitter.call(this),t=t||new window.AudioContext,this._context=t,this._context)this._defineProperty(this._context,e);this._latencyHint="interactive",this._lookAhead=.1,this._updateInterval=this._lookAhead/3,this._computedUpdateInterval=0,this._worker=this._createWorker(),this._constants={}},i.extend(i.Context,i.Emitter),i.Emitter.mixin(i.Context),i.Context.prototype._defineProperty=function(e,n){this.isUndef(this[n])&&Object.defineProperty(this,n,{get:function(){return"function"==typeof e[n]?e[n].bind(e):e[n]},set:function(t){e[n]=t}})},i.Context.prototype.now=function(){return this._context.currentTime},i.Context.prototype._createWorker=function(){window.URL=window.URL||window.webkitURL;var t=new Blob(["var timeoutTime = "+(1e3*this._updateInterval).toFixed(1)+";self.onmessage = function(msg){\ttimeoutTime = parseInt(msg.data);};function tick(){\tsetTimeout(tick, timeoutTime);\tself.postMessage('tick');}tick();"]),e=URL.createObjectURL(t),n=new Worker(e);return n.addEventListener("message",function(){this.emit("tick")}.bind(this)),n.addEventListener("message",function(){var t=this.now();if(this.isNumber(this._lastUpdate)){var e=t-this._lastUpdate;this._computedUpdateInterval=Math.max(e,.97*this._computedUpdateInterval)}this._lastUpdate=t}.bind(this)),n},i.Context.prototype.getConstant=function(t){if(this._constants[t])return this._constants[t];for(var e=this._context.createBuffer(1,128,this._context.sampleRate),n=e.getChannelData(0),i=0;ithis.memory){var n=this.length-this.memory;this._timeline.splice(0,n)}return this},e.Timeline.prototype.remove=function(t){if(this._iterating)this._toRemove.push(t);else{var e=this._timeline.indexOf(t);-1!==e&&this._timeline.splice(e,1)}return this},e.Timeline.prototype.get=function(t){var e=this._search(t);return-1!==e?this._timeline[e]:null},e.Timeline.prototype.peek=function(){return this._timeline[0]},e.Timeline.prototype.shift=function(){return this._timeline.shift()},e.Timeline.prototype.getAfter=function(t){var e=this._search(t);return e+1=t&&(this._timeline=[]);return this},e.Timeline.prototype.cancelBefore=function(t){if(this._timeline.length){var e=this._search(t);0<=e&&(this._timeline=this._timeline.slice(e+1))}return this},e.Timeline.prototype._search=function(t){var e=0,n=this._timeline.length,i=n;if(0t)return r;o.time>t?i=r:o.time=t;)n--;return this._iterate(e,n+1),this},e.Timeline.prototype.forEachAtTime=function(e,n){var t=this._search(e);return-1!==t&&this._iterate(function(t){t.time===e&&n(t)},0,t),this},e.Timeline.prototype.dispose=function(){e.prototype.dispose.call(this),this._timeline=null,this._toRemove=null},e.Timeline}.apply(e,i))||(t.exports=r)},function(t,e,n){var i,r;i=[n(0),n(1),n(2)],void 0===(r=function(t){"use strict";return t.Negate=function(){this._multiply=this.input=this.output=new t.Multiply(-1)},t.extend(t.Negate,t.SignalBase),t.Negate.prototype.dispose=function(){return t.prototype.dispose.call(this),this._multiply.dispose(),this._multiply=null,this},t.Negate}.apply(e,i))||(t.exports=r)},function(t,e,n){var i,r;i=[n(0),n(2),n(1),n(6)],void 0===(r=function(t){"use strict";return t.GreaterThanZero=function(){this._thresh=this.output=new t.WaveShaper(function(t){return t<=0?0:1},127),this._scale=this.input=new t.Multiply(1e4),this._scale.connect(this._thresh)},t.extend(t.GreaterThanZero,t.SignalBase),t.GreaterThanZero.prototype.dispose=function(){return t.prototype.dispose.call(this),this._scale.dispose(),this._scale=null,this._thresh.dispose(),this._thresh=null,this},t.GreaterThanZero}.apply(e,i))||(t.exports=r)},function(t,e,n){var i,r,o;r=[],void 0===(o="function"==typeof(i=function(){var s=function(t,e){this._dragged=!1,this._element=t,this._bindedMove=this._moved.bind(this),this._bindedEnd=this._ended.bind(this,e),t.addEventListener("touchstart",this._bindedEnd),t.addEventListener("touchmove",this._bindedMove),t.addEventListener("touchend",this._bindedEnd),t.addEventListener("mouseup",this._bindedEnd)};function o(t){return"running"===t.state}return s.prototype._moved=function(t){this._dragged=!0},s.prototype._ended=function(t){this._dragged||function(t){var e=t.createBuffer(1,1,t.sampleRate),n=t.createBufferSource();n.buffer=e,n.connect(t.destination),n.start(0),t.resume&&t.resume()}(t),this._dragged=!1},s.prototype.dispose=function(){this._element.removeEventListener("touchstart",this._bindedEnd),this._element.removeEventListener("touchmove",this._bindedMove),this._element.removeEventListener("touchend",this._bindedEnd),this._element.removeEventListener("mouseup",this._bindedEnd),this._bindedMove=null,this._bindedEnd=null,this._element=null},function(e,t,n){var i=new Promise(function(t){!function(e,n){o(e)?n():function t(){o(e)?n():(requestAnimationFrame(t),e.resume&&e.resume())}()}(e,t)}),r=[];return function t(e,n,i){if(Array.isArray(e)||NodeList&&e instanceof NodeList)for(var r=0;r= this._length) {\n this._writeIndex = 0;\n } // For excessive frames, the buffer will be overwritten.\n\n\n this._framesAvailable += sourceLength;\n\n if (this._framesAvailable > this._length) {\n this._framesAvailable = this._length;\n }\n }\n /**\n * Pull data out of buffer and fill a given sequence of Float32Arrays.\n *\n * @param {array} arraySequence An array of Float32Arrays.\n */\n\n }, {\n key: "pull",\n value: function pull(arraySequence) {\n // The channel count of arraySequence and the length of each channel must\n // match with this buffer obejct.\n // If the FIFO is completely empty, do nothing.\n if (this._framesAvailable === 0) {\n return;\n }\n\n var destinationLength = arraySequence[0].length; // Transfer data from the internal buffer to the |arraySequence| storage.\n\n for (var i = 0; i < destinationLength; ++i) {\n var readIndex = (this._readIndex + i) % this._length;\n\n for (var channel = 0; channel < this._channelCount; ++channel) {\n arraySequence[channel][i] = this._channelData[channel][readIndex];\n }\n }\n\n this._readIndex += destinationLength;\n\n if (this._readIndex >= this._length) {\n this._readIndex = 0;\n }\n\n this._framesAvailable -= destinationLength;\n\n if (this._framesAvailable < 0) {\n this._framesAvailable = 0;\n }\n }\n }, {\n key: "framesAvailable",\n get: function get() {\n return this._framesAvailable;\n }\n }]);\n\n return RingBuffer;\n }()\n}["default"];\n\nvar RecorderProcessor =\n/*#__PURE__*/\nfunction (_AudioWorkletProcesso) {\n _inherits(RecorderProcessor, _AudioWorkletProcesso);\n\n function RecorderProcessor(options) {\n var _this;\n\n _classCallCheck(this, RecorderProcessor);\n\n _this = _possibleConstructorReturn(this, _getPrototypeOf(RecorderProcessor).call(this));\n var processorOptions = options.processorOptions || {};\n _this.numOutputChannels = options.outputChannelCount || 2;\n _this.numInputChannels = processorOptions.numInputChannels || 2;\n _this.bufferSize = processorOptions.bufferSize || 1024;\n _this.recording = false;\n\n _this.clear();\n\n _this.port.onmessage = function (event) {\n var data = event.data;\n\n if (data.name === \'start\') {\n _this.record(data.duration);\n } else if (data.name === \'stop\') {\n _this.stop();\n }\n };\n\n return _this;\n }\n\n _createClass(RecorderProcessor, [{\n key: "process",\n value: function process(inputs) {\n if (!this.recording) {\n return true;\n } else if (this.sampleLimit && this.recordedSamples >= this.sampleLimit) {\n this.stop();\n return true;\n }\n\n var input = inputs[0];\n this.inputRingBuffer.push(input);\n\n if (this.inputRingBuffer.framesAvailable >= this.bufferSize) {\n this.inputRingBuffer.pull(this.inputRingBufferArraySequence);\n\n for (var channel = 0; channel < this.numOutputChannels; ++channel) {\n var inputChannelCopy = this.inputRingBufferArraySequence[channel].slice();\n\n if (channel === 0) {\n this.leftBuffers.push(inputChannelCopy);\n\n if (this.numInputChannels === 1) {\n this.rightBuffers.push(inputChannelCopy);\n }\n } else if (channel === 1 && this.numInputChannels > 1) {\n this.rightBuffers.push(inputChannelCopy);\n }\n }\n\n this.recordedSamples += this.bufferSize;\n }\n\n return true;\n }\n }, {\n key: "record",\n value: function record(duration) {\n if (duration) {\n this.sampleLimit = Math.round(duration * sampleRate);\n }\n\n this.recording = true;\n }\n }, {\n key: "stop",\n value: function stop() {\n this.recording = false;\n var buffers = this.getBuffers();\n var leftBuffer = buffers[0].buffer;\n var rightBuffer = buffers[1].buffer;\n this.port.postMessage({\n name: \'buffers\',\n leftBuffer: leftBuffer,\n rightBuffer: rightBuffer\n }, [leftBuffer, rightBuffer]);\n this.clear();\n }\n }, {\n key: "getBuffers",\n value: function getBuffers() {\n var buffers = [];\n buffers.push(this.mergeBuffers(this.leftBuffers));\n buffers.push(this.mergeBuffers(this.rightBuffers));\n return buffers;\n }\n }, {\n key: "mergeBuffers",\n value: function mergeBuffers(channelBuffer) {\n var result = new Float32Array(this.recordedSamples);\n var offset = 0;\n var lng = channelBuffer.length;\n\n for (var i = 0; i < lng; i++) {\n var buffer = channelBuffer[i];\n result.set(buffer, offset);\n offset += buffer.length;\n }\n\n return result;\n }\n }, {\n key: "clear",\n value: function clear() {\n var _this2 = this;\n\n this.leftBuffers = [];\n this.rightBuffers = [];\n this.inputRingBuffer = new RingBuffer(this.bufferSize, this.numInputChannels);\n this.inputRingBufferArraySequence = new Array(this.numInputChannels).fill(null).map(function () {\n return new Float32Array(_this2.bufferSize);\n });\n this.recordedSamples = 0;\n this.sampleLimit = null;\n }\n }]);\n\n return RecorderProcessor;\n}(_wrapNativeSuper(AudioWorkletProcessor));\n\nregisterProcessor(processorNames.recorderProcessor, RecorderProcessor);'},function(t,e,n){"use strict";n.r(e),e.default='function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn\'t been initialised - super() hasn\'t been called"); } return self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\n\nfunction isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\n\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n// import dependencies via preval.require so that they\'re available as values at compile time\nvar processorNames = {\n "recorderProcessor": "recorder-processor",\n "soundFileProcessor": "sound-file-processor",\n "amplitudeProcessor": "amplitude-processor"\n};\nvar RingBuffer = {\n "default":\n /*#__PURE__*/\n function () {\n /**\n * @constructor\n * @param {number} length Buffer length in frames.\n * @param {number} channelCount Buffer channel count.\n */\n function RingBuffer(length, channelCount) {\n _classCallCheck(this, RingBuffer);\n\n this._readIndex = 0;\n this._writeIndex = 0;\n this._framesAvailable = 0;\n this._channelCount = channelCount;\n this._length = length;\n this._channelData = [];\n\n for (var i = 0; i < this._channelCount; ++i) {\n this._channelData[i] = new Float32Array(length);\n }\n }\n /**\n * Getter for Available frames in buffer.\n *\n * @return {number} Available frames in buffer.\n */\n\n\n _createClass(RingBuffer, [{\n key: "push",\n\n /**\n * Push a sequence of Float32Arrays to buffer.\n *\n * @param {array} arraySequence A sequence of Float32Arrays.\n */\n value: function push(arraySequence) {\n // The channel count of arraySequence and the length of each channel must\n // match with this buffer obejct.\n // Transfer data from the |arraySequence| storage to the internal buffer.\n var sourceLength = arraySequence[0] ? arraySequence[0].length : 0;\n\n for (var i = 0; i < sourceLength; ++i) {\n var writeIndex = (this._writeIndex + i) % this._length;\n\n for (var channel = 0; channel < this._channelCount; ++channel) {\n this._channelData[channel][writeIndex] = arraySequence[channel][i];\n }\n }\n\n this._writeIndex += sourceLength;\n\n if (this._writeIndex >= this._length) {\n this._writeIndex = 0;\n } // For excessive frames, the buffer will be overwritten.\n\n\n this._framesAvailable += sourceLength;\n\n if (this._framesAvailable > this._length) {\n this._framesAvailable = this._length;\n }\n }\n /**\n * Pull data out of buffer and fill a given sequence of Float32Arrays.\n *\n * @param {array} arraySequence An array of Float32Arrays.\n */\n\n }, {\n key: "pull",\n value: function pull(arraySequence) {\n // The channel count of arraySequence and the length of each channel must\n // match with this buffer obejct.\n // If the FIFO is completely empty, do nothing.\n if (this._framesAvailable === 0) {\n return;\n }\n\n var destinationLength = arraySequence[0].length; // Transfer data from the internal buffer to the |arraySequence| storage.\n\n for (var i = 0; i < destinationLength; ++i) {\n var readIndex = (this._readIndex + i) % this._length;\n\n for (var channel = 0; channel < this._channelCount; ++channel) {\n arraySequence[channel][i] = this._channelData[channel][readIndex];\n }\n }\n\n this._readIndex += destinationLength;\n\n if (this._readIndex >= this._length) {\n this._readIndex = 0;\n }\n\n this._framesAvailable -= destinationLength;\n\n if (this._framesAvailable < 0) {\n this._framesAvailable = 0;\n }\n }\n }, {\n key: "framesAvailable",\n get: function get() {\n return this._framesAvailable;\n }\n }]);\n\n return RingBuffer;\n }()\n}["default"];\n\nvar SoundFileProcessor =\n/*#__PURE__*/\nfunction (_AudioWorkletProcesso) {\n _inherits(SoundFileProcessor, _AudioWorkletProcesso);\n\n function SoundFileProcessor(options) {\n var _this;\n\n _classCallCheck(this, SoundFileProcessor);\n\n _this = _possibleConstructorReturn(this, _getPrototypeOf(SoundFileProcessor).call(this));\n var processorOptions = options.processorOptions || {};\n _this.bufferSize = processorOptions.bufferSize || 256;\n _this.inputRingBuffer = new RingBuffer(_this.bufferSize, 1);\n _this.inputRingBufferArraySequence = [new Float32Array(_this.bufferSize)];\n return _this;\n }\n\n _createClass(SoundFileProcessor, [{\n key: "process",\n value: function process(inputs) {\n var input = inputs[0]; // we only care about the first input channel, because that contains the position data\n\n this.inputRingBuffer.push([input[0]]);\n\n if (this.inputRingBuffer.framesAvailable >= this.bufferSize) {\n this.inputRingBuffer.pull(this.inputRingBufferArraySequence);\n var inputChannel = this.inputRingBufferArraySequence[0];\n var position = inputChannel[inputChannel.length - 1] || 0;\n this.port.postMessage({\n name: \'position\',\n position: position\n });\n }\n\n return true;\n }\n }]);\n\n return SoundFileProcessor;\n}(_wrapNativeSuper(AudioWorkletProcessor));\n\nregisterProcessor(processorNames.soundFileProcessor, SoundFileProcessor);'},function(t,e,n){"use strict";n.r(e),e.default='function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn\'t been initialised - super() hasn\'t been called"); } return self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\n\nfunction isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\n\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n// import dependencies via preval.require so that they\'re available as values at compile time\nvar processorNames = {\n "recorderProcessor": "recorder-processor",\n "soundFileProcessor": "sound-file-processor",\n "amplitudeProcessor": "amplitude-processor"\n};\nvar RingBuffer = {\n "default":\n /*#__PURE__*/\n function () {\n /**\n * @constructor\n * @param {number} length Buffer length in frames.\n * @param {number} channelCount Buffer channel count.\n */\n function RingBuffer(length, channelCount) {\n _classCallCheck(this, RingBuffer);\n\n this._readIndex = 0;\n this._writeIndex = 0;\n this._framesAvailable = 0;\n this._channelCount = channelCount;\n this._length = length;\n this._channelData = [];\n\n for (var i = 0; i < this._channelCount; ++i) {\n this._channelData[i] = new Float32Array(length);\n }\n }\n /**\n * Getter for Available frames in buffer.\n *\n * @return {number} Available frames in buffer.\n */\n\n\n _createClass(RingBuffer, [{\n key: "push",\n\n /**\n * Push a sequence of Float32Arrays to buffer.\n *\n * @param {array} arraySequence A sequence of Float32Arrays.\n */\n value: function push(arraySequence) {\n // The channel count of arraySequence and the length of each channel must\n // match with this buffer obejct.\n // Transfer data from the |arraySequence| storage to the internal buffer.\n var sourceLength = arraySequence[0] ? arraySequence[0].length : 0;\n\n for (var i = 0; i < sourceLength; ++i) {\n var writeIndex = (this._writeIndex + i) % this._length;\n\n for (var channel = 0; channel < this._channelCount; ++channel) {\n this._channelData[channel][writeIndex] = arraySequence[channel][i];\n }\n }\n\n this._writeIndex += sourceLength;\n\n if (this._writeIndex >= this._length) {\n this._writeIndex = 0;\n } // For excessive frames, the buffer will be overwritten.\n\n\n this._framesAvailable += sourceLength;\n\n if (this._framesAvailable > this._length) {\n this._framesAvailable = this._length;\n }\n }\n /**\n * Pull data out of buffer and fill a given sequence of Float32Arrays.\n *\n * @param {array} arraySequence An array of Float32Arrays.\n */\n\n }, {\n key: "pull",\n value: function pull(arraySequence) {\n // The channel count of arraySequence and the length of each channel must\n // match with this buffer obejct.\n // If the FIFO is completely empty, do nothing.\n if (this._framesAvailable === 0) {\n return;\n }\n\n var destinationLength = arraySequence[0].length; // Transfer data from the internal buffer to the |arraySequence| storage.\n\n for (var i = 0; i < destinationLength; ++i) {\n var readIndex = (this._readIndex + i) % this._length;\n\n for (var channel = 0; channel < this._channelCount; ++channel) {\n arraySequence[channel][i] = this._channelData[channel][readIndex];\n }\n }\n\n this._readIndex += destinationLength;\n\n if (this._readIndex >= this._length) {\n this._readIndex = 0;\n }\n\n this._framesAvailable -= destinationLength;\n\n if (this._framesAvailable < 0) {\n this._framesAvailable = 0;\n }\n }\n }, {\n key: "framesAvailable",\n get: function get() {\n return this._framesAvailable;\n }\n }]);\n\n return RingBuffer;\n }()\n}["default"];\n\nvar AmplitudeProcessor =\n/*#__PURE__*/\nfunction (_AudioWorkletProcesso) {\n _inherits(AmplitudeProcessor, _AudioWorkletProcesso);\n\n function AmplitudeProcessor(options) {\n var _this;\n\n _classCallCheck(this, AmplitudeProcessor);\n\n _this = _possibleConstructorReturn(this, _getPrototypeOf(AmplitudeProcessor).call(this));\n var processorOptions = options.processorOptions || {};\n _this.numOutputChannels = options.outputChannelCount || 1;\n _this.numInputChannels = processorOptions.numInputChannels || 2;\n _this.normalize = processorOptions.normalize || false;\n _this.smoothing = processorOptions.smoothing || 0;\n _this.bufferSize = processorOptions.bufferSize || 2048;\n _this.inputRingBuffer = new RingBuffer(_this.bufferSize, _this.numInputChannels);\n _this.outputRingBuffer = new RingBuffer(_this.bufferSize, _this.numOutputChannels);\n _this.inputRingBufferArraySequence = new Array(_this.numInputChannels).fill(null).map(function () {\n return new Float32Array(_this.bufferSize);\n });\n _this.stereoVol = [0, 0];\n _this.stereoVolNorm = [0, 0];\n _this.volMax = 0.001;\n\n _this.port.onmessage = function (event) {\n var data = event.data;\n\n if (data.name === \'toggleNormalize\') {\n _this.normalize = data.normalize;\n } else if (data.name === \'smoothing\') {\n _this.smoothing = Math.max(0, Math.min(1, data.smoothing));\n }\n };\n\n return _this;\n } // TO DO make this stereo / dependent on # of audio channels\n\n\n _createClass(AmplitudeProcessor, [{\n key: "process",\n value: function process(inputs, outputs) {\n var input = inputs[0];\n var output = outputs[0];\n var smoothing = this.smoothing;\n this.inputRingBuffer.push(input);\n\n if (this.inputRingBuffer.framesAvailable >= this.bufferSize) {\n this.inputRingBuffer.pull(this.inputRingBufferArraySequence);\n\n for (var channel = 0; channel < this.numInputChannels; ++channel) {\n var inputBuffer = this.inputRingBufferArraySequence[channel];\n var bufLength = inputBuffer.length;\n var sum = 0;\n\n for (var i = 0; i < bufLength; i++) {\n var x = inputBuffer[i];\n\n if (this.normalize) {\n sum += Math.max(Math.min(x / this.volMax, 1), -1) * Math.max(Math.min(x / this.volMax, 1), -1);\n } else {\n sum += x * x;\n }\n } // ... then take the square root of the sum.\n\n\n var rms = Math.sqrt(sum / bufLength);\n this.stereoVol[channel] = Math.max(rms, this.stereoVol[channel] * smoothing);\n this.volMax = Math.max(this.stereoVol[channel], this.volMax);\n } // calculate stero normalized volume and add volume from all channels together\n\n\n var volSum = 0;\n\n for (var index = 0; index < this.stereoVol.length; index++) {\n this.stereoVolNorm[index] = Math.max(Math.min(this.stereoVol[index] / this.volMax, 1), 0);\n volSum += this.stereoVol[index];\n } // volume is average of channels\n\n\n var volume = volSum / this.stereoVol.length; // normalized value\n\n var volNorm = Math.max(Math.min(volume / this.volMax, 1), 0);\n this.port.postMessage({\n name: \'amplitude\',\n volume: volume,\n volNorm: volNorm,\n stereoVol: this.stereoVol,\n stereoVolNorm: this.stereoVolNorm\n }); // pass input through to output\n\n this.outputRingBuffer.push(this.inputRingBufferArraySequence);\n } // pull 128 frames out of the ring buffer\n // if the ring buffer does not have enough frames, the output will be silent\n\n\n this.outputRingBuffer.pull(output);\n return true;\n }\n }]);\n\n return AmplitudeProcessor;\n}(_wrapNativeSuper(AudioWorkletProcessor));\n\nregisterProcessor(processorNames.amplitudeProcessor, AmplitudeProcessor);'},function(t,e,n){var i,r;i=[n(0),n(17)],void 0===(r=function(r){r.Frequency=function(t,e){if(!(this instanceof r.Frequency))return new r.Frequency(t,e);r.TimeBase.call(this,t,e)},r.extend(r.Frequency,r.TimeBase),r.Frequency.prototype._primaryExpressions=Object.create(r.TimeBase.prototype._primaryExpressions),r.Frequency.prototype._primaryExpressions.midi={regexp:/^(\d+(?:\.\d+)?midi)/,method:function(t){return this.midiToFrequency(t)}},r.Frequency.prototype._primaryExpressions.note={regexp:/^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i,method:function(t,e){var n=i[t.toLowerCase()]+12*(parseInt(e)+1);return this.midiToFrequency(n)}},r.Frequency.prototype._primaryExpressions.tr={regexp:/^(\d+(?:\.\d+)?):(\d+(?:\.\d+)?):?(\d+(?:\.\d+)?)?/,method:function(t,e,n){var i=1;return t&&"0"!==t&&(i*=this._beatsToUnits(this._timeSignature()*parseFloat(t))),e&&"0"!==e&&(i*=this._beatsToUnits(parseFloat(e))),n&&"0"!==n&&(i*=this._beatsToUnits(parseFloat(n)/4)),i}},r.Frequency.prototype.transpose=function(t){return this._expr=function(t,e){return t()*this.intervalToFrequencyRatio(e)}.bind(this,this._expr,t),this},r.Frequency.prototype.harmonize=function(t){return this._expr=function(t,e){for(var n=t(),i=[],r=0;rthis.buffer.duration)throw"jump time out of range";if(e>this.buffer.duration-t)throw"end time out of range";var n=t||0,i=e||void 0;this.isPlaying()&&(this.stop(0),this.play(0,this.playbackRate,this.output.gain.value,n,i))}},{key:"channels",value:function(){return this.buffer.numberOfChannels}},{key:"sampleRate",value:function(){return this.buffer.sampleRate}},{key:"frames",value:function(){return this.buffer.length}},{key:"getPeaks",value:function(t){if(!this.buffer)throw"Cannot load peaks yet, buffer is not loaded";if(t=t||5*window.width,this.buffer){for(var e=this.buffer,n=e.length/t,i=~~(n/10)||1,r=e.numberOfChannels,o=new Float32Array(Math.round(t)),s=0;so[u])&&(o[u]=h)}return o}}},{key:"reverseBuffer",value:function(){if(!this.buffer)throw"SoundFile is not done loading";var t=this._lastPos/R.sampleRate,e=this.getVolume();this.setVolume(0,.001);for(var n=this.buffer.numberOfChannels,i=0;it[o].hi&&o++,r[o]=void 0!==r[o]?(r[o]+n[s])/2:n[s]}return r}},{key:"getOctaveBands",value:function(t,e){var n=t||3,i=e||15.625,r=[],o={lo:i/Math.pow(2,1/(2*n)),ctr:i,hi:i*Math.pow(2,1/(2*n))};r.push(o);for(var s=p.audiocontext.sampleRate/2;o.hi=this._maxDelay)throw new Error("Delay Time exceeds maximum delay time of "+this._maxDelay+" second.");t.connect(this.input),this.leftDelay.delayTime.setValueAtTime(o,this.ac.currentTime),this.rightDelay.delayTime.setValueAtTime(o,this.ac.currentTime),this._leftGain.gain.value=r,this._rightGain.gain.value=r,i&&(this._leftFilter.freq(i),this._rightFilter.freq(i))}},{key:"delayTime",value:function(t){"number"!=typeof t?(t.connect(this.leftDelay.delayTime),t.connect(this.rightDelay.delayTime)):(this.leftDelay.delayTime.cancelScheduledValues(this.ac.currentTime),this.rightDelay.delayTime.cancelScheduledValues(this.ac.currentTime),this.leftDelay.delayTime.linearRampToValueAtTime(t,this.ac.currentTime),this.rightDelay.delayTime.linearRampToValueAtTime(t,this.ac.currentTime))}},{key:"feedback",value:function(t){if(t&&"number"!=typeof t)t.connect(this._leftGain.gain),t.connect(this._rightGain.gain);else{if(1<=t)throw new Error("Feedback value will force a positive feedback loop.");"number"==typeof t&&(this._leftGain.gain.value=t,this._rightGain.gain.value=t)}return this._leftGain.gain.value}},{key:"filter",value:function(t,e){this._leftFilter.set(t,e),this._rightFilter.set(t,e)}},{key:"setType",value:function(t){switch(1===t&&(t="pingPong"),this._split.disconnect(),this._leftFilter.disconnect(),this._rightFilter.disconnect(),this._split.connect(this.leftDelay,0),this._split.connect(this.rightDelay,1),t){case"pingPong":this._rightFilter.setType(this._leftFilter.biquad.type),this._leftFilter.output.connect(this._merge,0,0),this._rightFilter.output.connect(this._merge,0,1),this._leftFilter.output.connect(this.rightDelay),this._rightFilter.output.connect(this.leftDelay);break;default:this._leftFilter.output.connect(this._merge,0,0),this._rightFilter.output.connect(this._merge,0,1),this._leftFilter.output.connect(this.leftDelay),this._rightFilter.output.connect(this.rightDelay)}}},{key:"dispose",value:function(){de(ye(e.prototype),"dispose",this).call(this),this._split.disconnect(),this._leftFilter.dispose(),this._rightFilter.dispose(),this._merge.disconnect(),this._leftGain.disconnect(),this._rightGain.disconnect(),this.leftDelay.disconnect(),this.rightDelay.disconnect(),this._split=void 0,this._leftFilter=void 0,this._rightFilter=void 0,this._merge=void 0,this._leftGain=void 0,this._rightGain=void 0,this.leftDelay=void 0,this.rightDelay=void 0}}]),e}();function _e(t){return(_e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function ge(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function be(t,e){for(var n=0;nthis.length&&(this.length=i.sequence.length)}},{key:"removePhrase",value:function(t){for(var e in this.phrases)this.phrases[e].name===t&&this.phrases.splice(e,1)}},{key:"getPhrase",value:function(t){for(var e in this.phrases)if(this.phrases[e].name===t)return this.phrases[e]}},{key:"replaceSequence",value:function(t,e){for(var n in this.phrases)this.phrases[n].name===t&&(this.phrases[n].sequence=e)}},{key:"incrementStep",value:function(t){this.partStep=t.parts.length?(t.scoreStep=0,t.onended()):(t.scoreStep=0,t.parts[t.currentPart-1].stop(),t.parts[t.currentPart].start())}function Ue(t,e){for(var n=0;nthis.cutoff&&e>this.threshold&&0this.treshold){this.isDetected=!0,this.callback?this.callback(this.energy):e&&e(this.energy);var n=this;setTimeout(function(){n.isDetected=!1},this.sensitivity)}this.penergy=this.energy}}]),r}();function xn(t,e){for(var n=0;n
2 |
3 |
4 |
5 |
6 |
7 | Sketch
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/examples/patterns/sketch.js:
--------------------------------------------------------------------------------
1 | let imagePattern;
2 | let graphicsPattern;
3 |
4 | let img;
5 | let buffer;
6 |
7 | function preload() {
8 | img = loadImage("brick_small.jpg");
9 | }
10 |
11 | function setup() {
12 | createCanvas(500, 500);
13 | // pixelDensity(1);
14 |
15 | // create an image pattern based on the image we loaded
16 | imagePattern = createPattern(img);
17 |
18 | // create an empty graphics
19 | buffer = createGraphics(5, 5);
20 | // set the pixel density to 1 to make sure it looks as intended
21 | buffer.pixelDensity(1);
22 | // draw a diagonal black line
23 | buffer.background(255);
24 | buffer.stroke(0);
25 | buffer.strokeWeight(1);
26 | buffer.line(0, 0, 5, 5);
27 |
28 | // create a battern based on our graphics object
29 | graphicsPattern = createPattern(buffer);
30 | }
31 |
32 | function draw() {
33 | // fill the background with our image pattern;
34 | backgroundPattern(imagePattern);
35 |
36 | // set the fill style to our graphics pattern
37 | fillPattern(graphicsPattern);
38 |
39 | // use translate to move the shape around
40 | // if we DON'T do this, the pattern will remain fixed
41 | push();
42 | translate(mouseX, mouseY);
43 | rect(0, 0, 200, 200);
44 | pop();
45 |
46 | // we'll continue to fill with the pattern until we change the fill style again
47 | ellipse(100, 100, 100, 100);
48 | }
49 |
--------------------------------------------------------------------------------
/examples/patterns/style.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | margin: 0;
3 | padding: 0;
4 | }
5 |
6 | canvas {
7 | display: block;
8 | }
9 |
--------------------------------------------------------------------------------
/p5.patgrad.js:
--------------------------------------------------------------------------------
1 | p5.Gradient = class {
2 | constructor() {}
3 |
4 | setAngle(angle) {
5 | if (_angleMode === "degrees") {
6 | this.angle = radians(angle);
7 | } else {
8 | this.angle = angle;
9 | }
10 | }
11 |
12 | colors() {
13 | let stops;
14 |
15 | if (Array.isArray(arguments[0])) {
16 | stops = arguments[0];
17 | } else {
18 | stops = arguments;
19 | }
20 |
21 | for (let i = 0; i < stops.length; i += 2) {
22 | const pos = stops[i];
23 | const col = stops[i + 1].toString();
24 | this.gradient.addColorStop(pos, col);
25 | }
26 | }
27 | };
28 |
29 | p5.LinearGradient = class LinearGradient extends p5.Gradient {
30 | constructor(angle, width) {
31 | super();
32 | this.setAngle(angle || 0);
33 | this.width = width || 100;
34 |
35 | const x = cos(this.angle) * this.width;
36 | const y = sin(this.angle) * this.width;
37 |
38 | this.gradient = drawingContext.createLinearGradient(0, 0, x, y);
39 | }
40 | };
41 |
42 | p5.RadialGradient = class RadialGradient extends p5.Gradient {
43 | constructor(innerRadius, outerRadius, x, y) {
44 | super();
45 | this.innerRadius = innerRadius || 0;
46 | this.outerRadius = outerRadius || 100;
47 | this.x = x || 0;
48 | this.y = y || 0;
49 |
50 | this.gradient = drawingContext.createRadialGradient(
51 | this.x,
52 | this.y,
53 | this.innerRadius,
54 | this.x,
55 | this.y,
56 | this.outerRadius
57 | );
58 | }
59 | };
60 |
61 | p5.ConicGradient = class ConicGradient extends p5.Gradient {
62 | constructor(angle, x, y) {
63 | super();
64 | this.setAngle(angle || 0);
65 | this.x = x || 0;
66 | this.y = y || 0;
67 |
68 | this.gradient = drawingContext.createConicGradient(this.angle, this.x, this.y);
69 | }
70 | };
71 |
72 | p5.prototype.createLinearGradient = function (angle, width) {
73 | return new p5.LinearGradient(angle, width);
74 | };
75 |
76 | p5.prototype.createConicGradient = function (angle, x, y) {
77 | return new p5.ConicGradient(angle, x, y);
78 | };
79 |
80 | p5.prototype.createRadialGradient = function (innerRadius, outerRadius, x, y) {
81 | return new p5.RadialGradient(innerRadius, outerRadius, x, y);
82 | };
83 |
84 | p5.prototype.fillGradient = function (gradient) {
85 | this.drawingContext.fillStyle = gradient.gradient ? gradient.gradient : gradient;
86 | };
87 |
88 | p5.prototype.strokeGradient = function (gradient) {
89 | this.drawingContext.strokeStyle = gradient.gradient ? gradient.gradient : gradient;
90 | };
91 |
92 | p5.prototype.backgroundGradient = function (gradient) {
93 | this.drawingContext.fillStyle = gradient.gradient ? gradient.gradient : gradient;
94 | this.drawingContext.fillRect(0, 0, this.width, this.height);
95 | };
96 |
97 | p5.prototype.createPattern = function (patternElement, repeat) {
98 | if (patternElement.canvas) {
99 | patternElement = patternElement.canvas;
100 | } else if (patternElement.elt) {
101 | patternElement = patternElement.elt;
102 | }
103 | return this.drawingContext.createPattern(patternElement, repeat || "repeat");
104 | };
105 |
106 | p5.prototype.createSimplePattern = (func, w, h, repeat) => {
107 | let buffer = this.createGraphics(w || 5, h || 5);
108 | buffer.pixelDensity(1);
109 | buffer.background(255);
110 | func(buffer);
111 | return this.drawingContext.createPattern(buffer.canvas, repeat || "repeat");
112 | };
113 |
114 | p5.prototype.fillPattern = function (pattern) {
115 | this.drawingContext.fillStyle = pattern;
116 | };
117 |
118 | p5.prototype.strokePattern = function (pattern) {
119 | this.drawingContext.strokeStyle = pattern;
120 | };
121 |
122 | p5.prototype.backgroundPattern = function (pattern) {
123 | this.drawingContext.fillStyle = pattern;
124 | this.drawingContext.fillRect(0, 0, width, height);
125 | };
126 |
--------------------------------------------------------------------------------
/patterns.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiboredom/p5.patgrad/e043fcba9f100dee9b64e5a2944ece2af94c5e40/patterns.gif
--------------------------------------------------------------------------------