Skip to content

Commit c25eb19

Browse files
committed
1.1.0 Use easing lib and calculate colorstops based on distance on curve
1 parent aaadb10 commit c25eb19

File tree

2 files changed

+87
-53
lines changed

2 files changed

+87
-53
lines changed

index.js

+84-52
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1-
const postcss = require('postcss');
2-
const valueParser = require('postcss-value-parser');
3-
const tinyColor = require('tinycolor2');
1+
const postcss = require('postcss');
2+
const valueParser = require('postcss-value-parser');
3+
const tinyColor = require('tinycolor2');
4+
const easeInSine = require('eases/sine-in');
5+
const easeOutSine = require('eases/sine-out');
6+
const easeInOutSine = require('eases/sine-in-out');
7+
const easeInQuad = require('eases/quad-in');
8+
const easeOutQuad = require('eases/quad-out');
9+
const easeInOutQuad = require('eases/quad-in-out');
410

511
const supportedGradients = [
612
'ease-in-sine-gradient',
@@ -12,6 +18,22 @@ const supportedGradients = [
1218
'scrim-gradient'
1319
];
1420

21+
const scrimCoordinates = {
22+
0.00: '0%',
23+
0.14: '8.52%',
24+
0.28: '17.53%',
25+
0.42: '27.19%',
26+
0.54: '36.28%',
27+
0.64: '44.56%',
28+
0.72: '51.97%',
29+
0.79: '59.18%',
30+
0.85: '66.33%',
31+
0.90: '73.39%',
32+
0.94: '80.36%',
33+
0.97: '87.18%',
34+
0.99: '93.73%'
35+
}
36+
1537
/**
1638
* The easing gradient function is a postcss plugin which supports the above
1739
* mentioned gradient types.
@@ -100,23 +122,15 @@ function functionToWord(obj) {
100122
*/
101123
function getColorStops(colors, easingType) {
102124
colors = transparentFix(colors);
125+
let gradientCoordinates = getCoordinates(easingType);
103126
let colorStops = '';
104-
if (easingType === 'scrim-gradient') {
105-
for (let ammount in scrimMap) {
106-
let color = tinyColor
107-
.mix(colors[0], colors[1], ammount)
108-
.toHslString();
109-
colorStops += `, ${color} ${scrimMap[ammount]}`;
110-
}
111-
} else {
112-
for (let stopValue of stopsArray(15)) {
113-
let color = tinyColor
114-
.mix(colors[0], colors[1], 100 * ease(stopValue, easingType))
115-
.toHslString();
116-
let percent = getPercentage(stopValue);
117-
colorStops += `, ${color} ${percent}`;
118-
}
127+
for (let ammount in gradientCoordinates) {
128+
let color = tinyColor
129+
.mix(colors[0], colors[1], ammount * 100)
130+
.toHslString();
131+
colorStops += `, ${color} ${gradientCoordinates[ammount]}`;
119132
}
133+
colorStops += `, ${colors[1]} 100%`;
120134
return colorStops;
121135
};
122136

@@ -140,44 +154,72 @@ function transparentToAlpha(colors, color) {
140154
}
141155

142156
/**
143-
* Function to generate an array with values that are linear divisions of 1
144-
* E.g. [0, 0.25, 0.5, 0.75, 1]
157+
* Get coordinates based on easing function.
158+
* The delta checks ensures there's roughly the same distance between each
159+
* coordinate.
145160
*/
146-
function stopsArray(stopCount) {
147-
let array = [];
148-
let value = 0;
149-
let i = 0;
150-
while (i <= stopCount) {
151-
array.push(value);
152-
value += 1/stopCount;
153-
i += 1;
161+
function getCoordinates(easingFunction) {
162+
if (easingFunction === 'scrim-gradient') return scrimCoordinates;
163+
164+
const yIncrements = 0.001;
165+
const deltaTolerance = 0.01;
166+
const deltaAdjust = 0.001;
167+
168+
let delta = 0.1;
169+
let coordinates = {};
170+
let x = 0;
171+
let y = 0;
172+
let xOld = 0;
173+
let yOld = 0;
174+
let firstTime = true;
175+
176+
while (firstTime || !isDelta(1, 1, xOld, yOld, delta - deltaTolerance)) {
177+
if (firstTime) {
178+
firstTime = false;
179+
} else {
180+
x = 0;
181+
y = 0;
182+
xOld = 0;
183+
yOld = 0;
184+
delta = delta - deltaAdjust;
185+
coordinates = {};
186+
}
187+
while (y <= 1) {
188+
coordinates[0] = 0;
189+
x = ease(y, easingFunction);
190+
if (isDelta(x, y, xOld, yOld, delta)) {
191+
coordinates[x] = getPercentage(y);
192+
xOld = x;
193+
yOld = y;
194+
}
195+
y += yIncrements;
196+
}
154197
}
155-
return array;
198+
return coordinates;
156199
}
157200

158201
/**
159-
* Easing functions
160-
* https://gist.github.com/gre/1650294
202+
* Easing functions switcheroo
161203
*/
162204
function ease(x, type) {
163205
switch (type) {
164206
case 'ease-in-sine-gradient':
165-
return -1 * Math.cos(x * (Math.PI / 2)) + 1;
207+
return easeInSine(x);
166208
break;
167209
case 'ease-out-sine-gradient':
168-
return Math.sin(x * (Math.PI / 2));
210+
return easeOutSine(x);
169211
break;
170212
case 'ease-in-out-sine-gradient':
171-
return -0.5 * (Math.cos(Math.PI * x) - 1);
213+
return easeInOutSine(x);
172214
break;
173215
case 'ease-in-quad-gradient':
174-
return x * x;
216+
return easeInQuad(x);
175217
break;
176218
case 'ease-out-quad-gradient':
177-
return x * (2 - x);
219+
return easeOutQuad(x);
178220
break;
179221
case 'ease-in-out-quad-gradient':
180-
return x < .5 ? 2 * x * x : -1 + (4 - 2 * x) * x;
222+
return easeInOutQuad(x);
181223
break;
182224
default:
183225
console.log(`Sorry, easing gradient does not support ${type}.`);
@@ -191,19 +233,9 @@ function getPercentage (num) {
191233
return parseFloat((num * 100).toFixed(3)) + '%';
192234
}
193235

194-
const scrimMap = {
195-
0: '0%',
196-
14: '8.52%',
197-
28: '17.53%',
198-
42: '27.19%',
199-
54: '36.28%',
200-
64: '44.56%',
201-
72: '51.97%',
202-
79: '59.18%',
203-
85: '66.33%',
204-
90: '73.39%',
205-
94: '80.36%',
206-
97: '87.18%',
207-
99: '93.73%',
208-
100: '100%'
236+
/**
237+
* Test is new coordinate is far enough away from old coordinate
238+
*/
239+
function isDelta(x, y, xOld, yOld, delta) {
240+
return Math.sqrt((x - xOld) ** 2 + (y - yOld) ** 2) > delta;
209241
}

package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "postcss-easing-gradients",
3-
"version": "1.0.1",
3+
"version": "1.1.0",
44
"description": "PostCSS plugin to create smooth linear-gradients that approximate easing functions.",
55
"main": "index.js",
66
"scripts": {
@@ -23,6 +23,8 @@
2323
},
2424
"homepage": "https://github.com/larsenwork/postcss-easing-gradients#readme",
2525
"dependencies": {
26+
"color": "^1.0.3",
27+
"eases": "^1.0.8",
2628
"postcss": "^5.2.16",
2729
"postcss-value-parser": "^3.3.0",
2830
"tinycolor2": "^1.4.1"

0 commit comments

Comments
 (0)