diff --git a/packages/math/package.json b/packages/math/package.json index 5d60b3a..776ff22 100644 --- a/packages/math/package.json +++ b/packages/math/package.json @@ -34,7 +34,8 @@ "@avocado/react": "^3.0.0", "@flecks/core": "^1.4.1", "@flecks/react": "^1.4.1", - "graham_scan": "^1.0.4" + "graham_scan": "^1.0.4", + "seedrandom": "^3.0.5" }, "devDependencies": { "@flecks/fleck": "^1.4.1" diff --git a/packages/math/src/index.js b/packages/math/src/index.js index 86b0155..a70b6a9 100644 --- a/packages/math/src/index.js +++ b/packages/math/src/index.js @@ -9,6 +9,7 @@ export * from './math'; export {default as floodwalk2D} from './floodwalk'; export {default as QuadTree} from './quadtree'; export {noise, noiseSeed} from './noise'; +export * from './random'; export {default as Range} from './range'; export {default as SimpleMovingAverage} from './sma'; export * as Vertice from './vertice'; diff --git a/packages/math/src/math.js b/packages/math/src/math.js index cd9d270..9ebc733 100644 --- a/packages/math/src/math.js +++ b/packages/math/src/math.js @@ -24,7 +24,6 @@ export const { log10, max, min, - random, round, sign, sin, @@ -79,22 +78,8 @@ export const normalizeAngleRange = (min, max) => { return [min, max]; /* eslint-enable no-param-reassign */ }; -export const randomNumber = (min, max) => { - if (min > max) { - // eslint-disable-next-line no-param-reassign - [max, min] = [min, max]; - } - return min + Math.random() * (max - min); -}; // smooth(er)?step assumes unit export const smoothstep = (x) => x * x * (3 - 2 * x); export const smootherstep = (x) => x * x * x * (x * (x * 6 - 15) + 10); -/** - * Probabilistic behavior. Every `period` seconds, return `true`. - * - * @param {Number} elapsed The time that's passed. - * @param {Number} period The frequency of probabilistic behavior. - */ -export const spontaneous = (elapsed, period) => Math.random() < 1 / (period / elapsed); export const sub = (l, r) => l - r; export const toRad = (a) => a * PI_180; diff --git a/packages/math/src/random.js b/packages/math/src/random.js new file mode 100644 index 0000000..b6c48e0 --- /dev/null +++ b/packages/math/src/random.js @@ -0,0 +1,27 @@ +const {alea: Alea} = require('seedrandom'); + +let generator = new Alea(0); + +export function setSeed(seed) { + generator = new Alea(seed); +} + +export function random() { + return generator(); +} + +export const randomNumber = (min, max) => { + if (min > max) { + // eslint-disable-next-line no-param-reassign + [max, min] = [min, max]; + } + return min + random() * (max - min); +}; + +/** + * Probabilistic behavior. Every `period` seconds, return `true`. + * + * @param {Number} elapsed The time that's passed. + * @param {Number} period The frequency of probabilistic behavior. + */ +export const spontaneous = (elapsed, period) => random() < 1 / (period / elapsed); diff --git a/packages/math/src/range.js b/packages/math/src/range.js index 861ad53..9a7e204 100644 --- a/packages/math/src/range.js +++ b/packages/math/src/range.js @@ -1,4 +1,4 @@ -import {randomNumber} from './math'; +import {randomNumber} from './random'; export default class Range { diff --git a/packages/math/src/vector/range.js b/packages/math/src/vector/range.js index 4575064..7b86247 100644 --- a/packages/math/src/vector/range.js +++ b/packages/math/src/vector/range.js @@ -1,5 +1,5 @@ import Range from '../range'; -import {randomNumber} from '../math'; +import {randomNumber} from '../random'; export default class VectorRange extends Range { diff --git a/packages/sound/package.json b/packages/sound/package.json index 82e6a78..4a13a81 100644 --- a/packages/sound/package.json +++ b/packages/sound/package.json @@ -30,6 +30,7 @@ "test.js.map" ], "dependencies": { + "@avocado/math": "^3.0.0", "@avocado/react": "^3.0.0", "@avocado/resource": "^3.0.0", "@avocado/traits": "^3.0.0", diff --git a/packages/sound/src/sound.js b/packages/sound/src/sound.js index a73d02a..4308072 100644 --- a/packages/sound/src/sound.js +++ b/packages/sound/src/sound.js @@ -1,3 +1,4 @@ +import {random} from '@avocado/math'; import {JsonResource, Resource} from '@avocado/resource'; import LRU from 'lru-cache'; @@ -37,7 +38,7 @@ const pull = () => { } } const hmi = MAX_INTERVAL / 2; - setTimeout(pull, Math.max(20, hmi + hmi * (Math.random() - 0.5))); + setTimeout(pull, Math.max(20, hmi + hmi * (random() - 0.5))); }; if ('web' === process.env.FLECKS_CORE_BUILD_TARGET) { diff --git a/packages/timing/src/lfo/modulated-property.js b/packages/timing/src/lfo/modulated-property.js index f83443e..68ba37c 100644 --- a/packages/timing/src/lfo/modulated-property.js +++ b/packages/timing/src/lfo/modulated-property.js @@ -1,4 +1,5 @@ import {Property} from '@avocado/core'; +import {random} from '@avocado/math'; import {Class, compose, EventEmitter} from '@flecks/core'; import Transition from '../transition'; @@ -10,7 +11,7 @@ const Modulator = { }, Random() { - return () => Math.random(); + return () => random(); }, Sawtooth() { diff --git a/packages/timing/src/traits/animated.js b/packages/timing/src/traits/animated.js index f2eb9e6..a9005e7 100644 --- a/packages/timing/src/traits/animated.js +++ b/packages/timing/src/traits/animated.js @@ -1,6 +1,6 @@ import {mapValuesAsync} from '@avocado/core'; import {StateProperty, Trait} from '@avocado/traits'; -import {Rectangle, Vector} from '@avocado/math'; +import {random, Rectangle, Vector} from '@avocado/math'; import {compose} from '@flecks/core'; import mapValues from 'lodash.mapvalues'; @@ -282,7 +282,7 @@ export default (flecks) => class Animated extends decorate(Trait) { const animation = this.$$animations[currentAnimation]; const jitterAmount = this.jitterFor(currentAnimation); if (jitterAmount > 0) { - const jitter = Math.random() * jitterAmount; + const jitter = random() * jitterAmount; const halfJitter = jitter / 2; // eslint-disable-next-line no-param-reassign elapsed += jitter - halfJitter;