added download 2
This commit is contained in:
-6
@@ -1,6 +0,0 @@
|
||||
import { radiansToDegrees } from './radians-to-degrees.mjs';
|
||||
import { zeroPoint } from './inc.mjs';
|
||||
|
||||
const angle = (a, b = zeroPoint) => radiansToDegrees(Math.atan2(b.y - a.y, b.x - a.x));
|
||||
|
||||
export { angle };
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
const applyOffset = (from, to) => {
|
||||
let hasReceivedFrom = true;
|
||||
if (to === undefined) {
|
||||
to = from;
|
||||
hasReceivedFrom = false;
|
||||
}
|
||||
return (v) => {
|
||||
if (hasReceivedFrom) {
|
||||
return v - from + to;
|
||||
}
|
||||
else {
|
||||
from = v;
|
||||
hasReceivedFrom = true;
|
||||
return to;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export { applyOffset };
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
const identity = (v) => v;
|
||||
const createAttractor = (alterDisplacement = identity) => (constant, origin, v) => {
|
||||
const displacement = origin - v;
|
||||
const springModifiedDisplacement = -(0 - constant + 1) * (0 - alterDisplacement(Math.abs(displacement)));
|
||||
return displacement <= 0
|
||||
? origin + springModifiedDisplacement
|
||||
: origin - springModifiedDisplacement;
|
||||
};
|
||||
const attract = createAttractor();
|
||||
const attractExpo = createAttractor(Math.sqrt);
|
||||
|
||||
export { attract, attractExpo, createAttractor };
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
const clamp = (min, max, v) => Math.min(Math.max(v, min), max);
|
||||
|
||||
export { clamp };
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
const degreesToRadians = (degrees) => (degrees * Math.PI) / 180;
|
||||
|
||||
export { degreesToRadians };
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
import { isPoint } from './is-point.mjs';
|
||||
import { isPoint3D } from './is-point-3d.mjs';
|
||||
import { isNum } from './inc.mjs';
|
||||
|
||||
const distance1D = (a, b) => Math.abs(a - b);
|
||||
function distance(a, b) {
|
||||
if (isNum(a) && isNum(b)) {
|
||||
return distance1D(a, b);
|
||||
}
|
||||
else if (isPoint(a) && isPoint(b)) {
|
||||
const xDelta = distance1D(a.x, b.x);
|
||||
const yDelta = distance1D(a.y, b.y);
|
||||
const zDelta = isPoint3D(a) && isPoint3D(b) ? distance1D(a.z, b.z) : 0;
|
||||
return Math.sqrt(Math.pow(xDelta, 2) + Math.pow(yDelta, 2) + Math.pow(zDelta, 2));
|
||||
}
|
||||
}
|
||||
|
||||
export { distance };
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
function hueToRgb(p, q, t) {
|
||||
if (t < 0)
|
||||
t += 1;
|
||||
if (t > 1)
|
||||
t -= 1;
|
||||
if (t < 1 / 6)
|
||||
return p + (q - p) * 6 * t;
|
||||
if (t < 1 / 2)
|
||||
return q;
|
||||
if (t < 2 / 3)
|
||||
return p + (q - p) * (2 / 3 - t) * 6;
|
||||
return p;
|
||||
}
|
||||
function hslaToRgba({ hue, saturation, lightness, alpha }) {
|
||||
hue /= 360;
|
||||
saturation /= 100;
|
||||
lightness /= 100;
|
||||
let red = 0;
|
||||
let green = 0;
|
||||
let blue = 0;
|
||||
if (!saturation) {
|
||||
red = green = blue = lightness;
|
||||
}
|
||||
else {
|
||||
const q = lightness < 0.5
|
||||
? lightness * (1 + saturation)
|
||||
: lightness + saturation - lightness * saturation;
|
||||
const p = 2 * lightness - q;
|
||||
red = hueToRgb(p, q, hue + 1 / 3);
|
||||
green = hueToRgb(p, q, hue);
|
||||
blue = hueToRgb(p, q, hue - 1 / 3);
|
||||
}
|
||||
return {
|
||||
red: Math.round(red * 255),
|
||||
green: Math.round(green * 255),
|
||||
blue: Math.round(blue * 255),
|
||||
alpha,
|
||||
};
|
||||
}
|
||||
|
||||
export { hslaToRgba };
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
const zeroPoint = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0
|
||||
};
|
||||
const isNum = (v) => typeof v === 'number';
|
||||
|
||||
export { isNum, zeroPoint };
|
||||
-92
@@ -1,92 +0,0 @@
|
||||
import { progress } from './progress.mjs';
|
||||
import { mix } from './mix.mjs';
|
||||
import { mixColor } from './mix-color.mjs';
|
||||
import { mixComplex, mixArray, mixObject } from './mix-complex.mjs';
|
||||
import { color } from 'style-value-types';
|
||||
import { clamp } from './clamp.mjs';
|
||||
import { pipe } from './pipe.mjs';
|
||||
import { invariant } from 'hey-listen';
|
||||
|
||||
const mixNumber = (from, to) => (p) => mix(from, to, p);
|
||||
function detectMixerFactory(v) {
|
||||
if (typeof v === 'number') {
|
||||
return mixNumber;
|
||||
}
|
||||
else if (typeof v === 'string') {
|
||||
if (color.test(v)) {
|
||||
return mixColor;
|
||||
}
|
||||
else {
|
||||
return mixComplex;
|
||||
}
|
||||
}
|
||||
else if (Array.isArray(v)) {
|
||||
return mixArray;
|
||||
}
|
||||
else if (typeof v === 'object') {
|
||||
return mixObject;
|
||||
}
|
||||
}
|
||||
function createMixers(output, ease, customMixer) {
|
||||
const mixers = [];
|
||||
const mixerFactory = customMixer || detectMixerFactory(output[0]);
|
||||
const numMixers = output.length - 1;
|
||||
for (let i = 0; i < numMixers; i++) {
|
||||
let mixer = mixerFactory(output[i], output[i + 1]);
|
||||
if (ease) {
|
||||
const easingFunction = Array.isArray(ease) ? ease[i] : ease;
|
||||
mixer = pipe(easingFunction, mixer);
|
||||
}
|
||||
mixers.push(mixer);
|
||||
}
|
||||
return mixers;
|
||||
}
|
||||
function fastInterpolate([from, to], [mixer]) {
|
||||
return (v) => mixer(progress(from, to, v));
|
||||
}
|
||||
function slowInterpolate(input, mixers) {
|
||||
const inputLength = input.length;
|
||||
const lastInputIndex = inputLength - 1;
|
||||
return (v) => {
|
||||
let mixerIndex = 0;
|
||||
let foundMixerIndex = false;
|
||||
if (v <= input[0]) {
|
||||
foundMixerIndex = true;
|
||||
}
|
||||
else if (v >= input[lastInputIndex]) {
|
||||
mixerIndex = lastInputIndex - 1;
|
||||
foundMixerIndex = true;
|
||||
}
|
||||
if (!foundMixerIndex) {
|
||||
let i = 1;
|
||||
for (; i < inputLength; i++) {
|
||||
if (input[i] > v || i === lastInputIndex) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
mixerIndex = i - 1;
|
||||
}
|
||||
const progressInRange = progress(input[mixerIndex], input[mixerIndex + 1], v);
|
||||
return mixers[mixerIndex](progressInRange);
|
||||
};
|
||||
}
|
||||
function interpolate(input, output, { clamp: isClamp = true, ease, mixer } = {}) {
|
||||
const inputLength = input.length;
|
||||
invariant(inputLength === output.length, 'Both input and output ranges must be the same length');
|
||||
invariant(!ease || !Array.isArray(ease) || ease.length === inputLength - 1, 'Array of easing functions must be of length `input.length - 1`, as it applies to the transitions **between** the defined values.');
|
||||
if (input[0] > input[inputLength - 1]) {
|
||||
input = [].concat(input);
|
||||
output = [].concat(output);
|
||||
input.reverse();
|
||||
output.reverse();
|
||||
}
|
||||
const mixers = createMixers(output, ease, mixer);
|
||||
const interpolator = inputLength === 2
|
||||
? fastInterpolate(input, mixers)
|
||||
: slowInterpolate(input, mixers);
|
||||
return isClamp
|
||||
? (v) => interpolator(clamp(input[0], input[inputLength - 1], v))
|
||||
: interpolator;
|
||||
}
|
||||
|
||||
export { interpolate };
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
import { isPoint } from './is-point.mjs';
|
||||
|
||||
const isPoint3D = (point) => isPoint(point) && point.hasOwnProperty('z');
|
||||
|
||||
export { isPoint3D };
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
const isPoint = (point) => point.hasOwnProperty('x') && point.hasOwnProperty('y');
|
||||
|
||||
export { isPoint };
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
import { mix } from './mix.mjs';
|
||||
import { hsla, rgba, hex } from 'style-value-types';
|
||||
import { invariant } from 'hey-listen';
|
||||
import { hslaToRgba } from './hsla-to-rgba.mjs';
|
||||
|
||||
const mixLinearColor = (from, to, v) => {
|
||||
const fromExpo = from * from;
|
||||
const toExpo = to * to;
|
||||
return Math.sqrt(Math.max(0, v * (toExpo - fromExpo) + fromExpo));
|
||||
};
|
||||
const colorTypes = [hex, rgba, hsla];
|
||||
const getColorType = (v) => colorTypes.find((type) => type.test(v));
|
||||
const notAnimatable = (color) => `'${color}' is not an animatable color. Use the equivalent color code instead.`;
|
||||
const mixColor = (from, to) => {
|
||||
let fromColorType = getColorType(from);
|
||||
let toColorType = getColorType(to);
|
||||
invariant(!!fromColorType, notAnimatable(from));
|
||||
invariant(!!toColorType, notAnimatable(to));
|
||||
let fromColor = fromColorType.parse(from);
|
||||
let toColor = toColorType.parse(to);
|
||||
if (fromColorType === hsla) {
|
||||
fromColor = hslaToRgba(fromColor);
|
||||
fromColorType = rgba;
|
||||
}
|
||||
if (toColorType === hsla) {
|
||||
toColor = hslaToRgba(toColor);
|
||||
toColorType = rgba;
|
||||
}
|
||||
const blended = Object.assign({}, fromColor);
|
||||
return (v) => {
|
||||
for (const key in blended) {
|
||||
if (key !== "alpha") {
|
||||
blended[key] = mixLinearColor(fromColor[key], toColor[key], v);
|
||||
}
|
||||
}
|
||||
blended.alpha = mix(fromColor.alpha, toColor.alpha, v);
|
||||
return fromColorType.transform(blended);
|
||||
};
|
||||
};
|
||||
|
||||
export { mixColor, mixLinearColor };
|
||||
-82
@@ -1,82 +0,0 @@
|
||||
import { complex, color } from 'style-value-types';
|
||||
import { mix } from './mix.mjs';
|
||||
import { mixColor } from './mix-color.mjs';
|
||||
import { isNum } from './inc.mjs';
|
||||
import { pipe } from './pipe.mjs';
|
||||
import { warning } from 'hey-listen';
|
||||
|
||||
function getMixer(origin, target) {
|
||||
if (isNum(origin)) {
|
||||
return (v) => mix(origin, target, v);
|
||||
}
|
||||
else if (color.test(origin)) {
|
||||
return mixColor(origin, target);
|
||||
}
|
||||
else {
|
||||
return mixComplex(origin, target);
|
||||
}
|
||||
}
|
||||
const mixArray = (from, to) => {
|
||||
const output = [...from];
|
||||
const numValues = output.length;
|
||||
const blendValue = from.map((fromThis, i) => getMixer(fromThis, to[i]));
|
||||
return (v) => {
|
||||
for (let i = 0; i < numValues; i++) {
|
||||
output[i] = blendValue[i](v);
|
||||
}
|
||||
return output;
|
||||
};
|
||||
};
|
||||
const mixObject = (origin, target) => {
|
||||
const output = Object.assign(Object.assign({}, origin), target);
|
||||
const blendValue = {};
|
||||
for (const key in output) {
|
||||
if (origin[key] !== undefined && target[key] !== undefined) {
|
||||
blendValue[key] = getMixer(origin[key], target[key]);
|
||||
}
|
||||
}
|
||||
return (v) => {
|
||||
for (const key in blendValue) {
|
||||
output[key] = blendValue[key](v);
|
||||
}
|
||||
return output;
|
||||
};
|
||||
};
|
||||
function analyse(value) {
|
||||
const parsed = complex.parse(value);
|
||||
const numValues = parsed.length;
|
||||
let numNumbers = 0;
|
||||
let numRGB = 0;
|
||||
let numHSL = 0;
|
||||
for (let i = 0; i < numValues; i++) {
|
||||
if (numNumbers || typeof parsed[i] === "number") {
|
||||
numNumbers++;
|
||||
}
|
||||
else {
|
||||
if (parsed[i].hue !== undefined) {
|
||||
numHSL++;
|
||||
}
|
||||
else {
|
||||
numRGB++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return { parsed, numNumbers, numRGB, numHSL };
|
||||
}
|
||||
const mixComplex = (origin, target) => {
|
||||
const template = complex.createTransformer(target);
|
||||
const originStats = analyse(origin);
|
||||
const targetStats = analyse(target);
|
||||
const canInterpolate = originStats.numHSL === targetStats.numHSL &&
|
||||
originStats.numRGB === targetStats.numRGB &&
|
||||
originStats.numNumbers >= targetStats.numNumbers;
|
||||
if (canInterpolate) {
|
||||
return pipe(mixArray(originStats.parsed, targetStats.parsed), template);
|
||||
}
|
||||
else {
|
||||
warning(true, `Complex values '${origin}' and '${target}' too different to mix. Ensure all colors are of the same type, and that each contains the same quantity of number and color values. Falling back to instant transition.`);
|
||||
return (p) => `${p > 0 ? target : origin}`;
|
||||
}
|
||||
};
|
||||
|
||||
export { mixArray, mixComplex, mixObject };
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
const mix = (from, to, progress) => -progress * from + progress * to + from;
|
||||
|
||||
export { mix };
|
||||
-4
@@ -1,4 +0,0 @@
|
||||
const combineFunctions = (a, b) => (v) => b(a(v));
|
||||
const pipe = (...transformers) => transformers.reduce(combineFunctions);
|
||||
|
||||
export { pipe };
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
import { degreesToRadians } from './degrees-to-radians.mjs';
|
||||
|
||||
const pointFromVector = (origin, angle, distance) => {
|
||||
angle = degreesToRadians(angle);
|
||||
return {
|
||||
x: distance * Math.cos(angle) + origin.x,
|
||||
y: distance * Math.sin(angle) + origin.y
|
||||
};
|
||||
};
|
||||
|
||||
export { pointFromVector };
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
const progress = (from, to, value) => {
|
||||
const toFromDifference = to - from;
|
||||
return toFromDifference === 0 ? 1 : (value - from) / toFromDifference;
|
||||
};
|
||||
|
||||
export { progress };
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
const radiansToDegrees = (radians) => (radians * 180) / Math.PI;
|
||||
|
||||
export { radiansToDegrees };
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
import { toDecimal } from './to-decimal.mjs';
|
||||
|
||||
const smoothFrame = (prevValue, nextValue, duration, smoothing = 0) => toDecimal(prevValue +
|
||||
(duration * (nextValue - prevValue)) / Math.max(smoothing, duration));
|
||||
|
||||
export { smoothFrame };
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
import { smoothFrame } from './smooth-frame.mjs';
|
||||
import { getFrameData } from 'framesync';
|
||||
|
||||
const smooth = (strength = 50) => {
|
||||
let previousValue = 0;
|
||||
let lastUpdated = 0;
|
||||
return (v) => {
|
||||
const currentFramestamp = getFrameData().timestamp;
|
||||
const timeDelta = currentFramestamp !== lastUpdated ? currentFramestamp - lastUpdated : 0;
|
||||
const newValue = timeDelta
|
||||
? smoothFrame(previousValue, v, timeDelta, strength)
|
||||
: previousValue;
|
||||
lastUpdated = currentFramestamp;
|
||||
previousValue = newValue;
|
||||
return newValue;
|
||||
};
|
||||
};
|
||||
|
||||
export { smooth };
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
const snap = (points) => {
|
||||
if (typeof points === 'number') {
|
||||
return (v) => Math.round(v / points) * points;
|
||||
}
|
||||
else {
|
||||
let i = 0;
|
||||
const numPoints = points.length;
|
||||
return (v) => {
|
||||
let lastDistance = Math.abs(points[0] - v);
|
||||
for (i = 1; i < numPoints; i++) {
|
||||
const point = points[i];
|
||||
const distance = Math.abs(point - v);
|
||||
if (distance === 0)
|
||||
return point;
|
||||
if (distance > lastDistance)
|
||||
return points[i - 1];
|
||||
if (i === numPoints - 1)
|
||||
return point;
|
||||
lastDistance = distance;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export { snap };
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
const toDecimal = (num, precision = 2) => {
|
||||
precision = Math.pow(10, precision);
|
||||
return Math.round(num * precision) / precision;
|
||||
};
|
||||
|
||||
export { toDecimal };
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
function velocityPerFrame(xps, frameDuration) {
|
||||
return xps / (1000 / frameDuration);
|
||||
}
|
||||
|
||||
export { velocityPerFrame };
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
function velocityPerSecond(velocity, frameDuration) {
|
||||
return frameDuration ? velocity * (1000 / frameDuration) : 0;
|
||||
}
|
||||
|
||||
export { velocityPerSecond };
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
const wrap = (min, max, v) => {
|
||||
const rangeSize = max - min;
|
||||
return ((((v - min) % rangeSize) + rangeSize) % rangeSize) + min;
|
||||
};
|
||||
|
||||
export { wrap };
|
||||
Reference in New Issue
Block a user