Skip to content

Commit 3cc4741

Browse files
committed
Add precision and alphadecimals option
1 parent a56a72f commit 3cc4741

File tree

5 files changed

+58
-40
lines changed

5 files changed

+58
-40
lines changed

README.md

+26-22
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,49 @@
1-
# Postcss Easing Gradients
1+
# PostCSS Easing Gradients
22
PostCSS plugin to create smooth linear-gradients that approximate easing functions.
33

4-
The syntax is `<type>-gradient([ <direction>,]? <start-color>, <stop-color>)` where
5-
* `type` is one of the supported gradient types
4+
The syntax is `<gradient-type>([ <direction>,]? <start-color>, <stop-color>)` where
5+
* `gradient-type` is one of the supported gradient types
66
* `direction` shares syntax with `linear-gradient` and is optional
77
* `start-color` and `stop-color` are css colors in any format
88

9-
## Supported gradient types
9+
*Note that it's exactly two colors and it doesn't support custom color stop locations.*
10+
11+
## Supported Gradient Types
1012
```
11-
ease-in-sine
12-
ease-out-sine
13-
ease-in-out-sine
14-
ease-in-quad
15-
ease-out-quad
16-
ease-in-out-quad
17-
scrim
13+
ease-in-sine-gradient
14+
ease-out-sine-gradient
15+
ease-in-out-sine-gradient
16+
ease-in-quad-gradient
17+
ease-out-quad-gradient
18+
ease-in-out-quad-gradient
19+
scrim-gradient
1820
```
19-
Note: Scrim is a custom easing inspired by Material Design text protection scrims
21+
*Scrim is a custom easing inspired by Material Design text protection scrims*
22+
23+
## Options
24+
* `precision: 0.1` is the default value and creates ~17 color stops. The demo uses 0.15 which creates ~11 color stops. I wouldn't recommending using anything above 0.2 as banding becomes very obvious.
25+
* `alphaDecimals: 3` is the default number of decimals for alpha values and I wouldn't recommend changing it. Increase it for greater precision.
2026

2127
## Examples
2228
```
23-
#pcss
24-
scrim-gradient(black, transparent)
29+
scrim-gradient(black, transparent);
2530
26-
ease-in-out-quad-gradient(to bottom left, #bada55, olive)
31+
ease-in-out-quad-gradient(to bottom left, #bada55, olive);
2732
28-
ease-in-sine-gradient(23deg, hsla(300, 80%, 50%, .7), rgb(120, 140, 255))
33+
ease-in-sine-gradient(23deg, hsla(300, 80%, 50%, .7), rgb(120, 140, 255));
2934
```
3035
becomes
3136
```
32-
#css
33-
linear-gradient(hsl(0, 0%, 0%) 0%, hsla(0, 0%, 0%, 0.86) 8.52%, hsla(0, 0%, 0%, 0.72) 17.53%, hsla(0, 0%, 0%, 0.58) 27.19%, hsla(0, 0%, 0%, 0.46) 36.28%, hsla(0, 0%, 0%, 0.36) 44.56%, hsla(0, 0%, 0%, 0.28) 51.97%, hsla(0, 0%, 0%, 0.21) 59.18%, hsla(0, 0%, 0%, 0.15) 66.33%, hsla(0, 0%, 0%, 0.1) 73.39%, hsla(0, 0%, 0%, 0.06) 80.36%, hsla(0, 0%, 0%, 0.03) 87.18%, hsla(0, 0%, 0%, 0.01) 93.73%, hsla(0, 0%, 0%, 0) 100%)
37+
linear-gradient(hsl(0, 0%, 0%) 0%, hsla(0, 0%, 0%, 0.86) 8.52%, hsla(0, 0%, 0%, 0.72) 17.53%, hsla(0, 0%, 0%, 0.58) 27.19%, hsla(0, 0%, 0%, 0.46) 36.28%, hsla(0, 0%, 0%, 0.36) 44.56%, hsla(0, 0%, 0%, 0.28) 51.97%, hsla(0, 0%, 0%, 0.21) 59.18%, hsla(0, 0%, 0%, 0.15) 66.33%, hsla(0, 0%, 0%, 0.1) 73.39%, hsla(0, 0%, 0%, 0.06) 80.36%, hsla(0, 0%, 0%, 0.03) 87.18%, hsla(0, 0%, 0%, 0.01) 93.73%, hsla(0, 0%, 0%, 0) 100%);
3438
35-
linear-gradient(to bottom left, hsl(74, 64%, 59%) 0%, hsl(74, 64%, 59%) 6.667%, hsl(74, 62%, 58%) 13.333%, hsl(73, 60%, 57%) 20%, hsl(72, 57%, 55%) 26.667%, hsl(71, 54%, 52%) 33.333%, hsl(70, 53%, 48%) 40%, hsl(68, 58%, 44%) 46.667%, hsl(66, 64%, 40%) 53.333%, hsl(65, 70%, 36%) 60%, hsl(63, 77%, 33%) 66.667%, hsl(62, 84%, 30%) 73.333%, hsl(61, 90%, 28%) 80%, hsl(61, 95%, 26%) 86.667%, hsl(60, 98%, 25%) 93.333%, hsl(60, 100%, 25%) 100%)
39+
linear-gradient(to bottom left, hsl(74.4, 64.3%, 59.4%) 0, hsl(74.2, 63.2%, 58.8%) 9.7%, hsl(73.5, 60.7%, 57.1%) 18.3%, hsl(72.6, 57.5%, 54.9%) 25.7%, hsl(71.5, 54.2%, 52.3%) 32.2%, hsl(70.4, 52.1%, 49.6%) 37.9%, hsl(69.2, 55.1%, 46.7%) 43.1%, hsl(67.9, 58.7%, 43.7%) 47.9%, hsl(66.7, 62.8%, 40.6%) 52.4%, hsl(65.4, 67.6%, 37.7%) 57.2%, hsl(64.2, 72.9%, 34.8%) 62.4%, hsl(63, 79%, 32%) 68.2%, hsl(61.9, 85.5%, 29.5%) 74.7%, hsl(60.9, 92.3%, 27.3%) 82.2%, hsl(60.2, 97.8%, 25.7%) 90.9%, olive 100%);
3640
37-
linear-gradient(23deg, hsla(300, 80%, 50%, 0.7) 0%, hsla(300, 80%, 50%, 0.7) 6.667%, hsla(299, 80%, 50%, 0.71) 13.333%, hsla(298, 80%, 51%, 0.71) 20%, hsla(297, 81%, 52%, 0.73) 26.667%, hsla(295, 81%, 54%, 0.74) 33.333%, hsla(292, 82%, 55%, 0.76) 40%, hsla(289, 82%, 57%, 0.78) 46.667%, hsla(285, 83%, 59%, 0.8) 53.333%, hsla(280, 85%, 61%, 0.82) 60%, hsla(275, 86%, 64%, 0.85) 66.667%, hsla(268, 88%, 66%, 0.88) 73.333%, hsla(261, 90%, 69%, 0.91) 80%, hsla(252, 93%, 72%, 0.94) 86.667%, hsla(242, 96%, 75%, 0.97) 93.333%, hsla(231, 100%, 74%, 1) 100%)
41+
linear-gradient(23deg, hsla(300, 80%, 50%, 0.7) 0, hsla(299.1, 80.2%, 50.6%, 0.703) 9.7%, hsla(296.8, 80.7%, 52.1%, 0.713) 18.9%, hsla(293.3, 81.6%, 54.3%, 0.727) 27.4%, hsla(289.1, 82.6%, 56.7%, 0.745) 35.2%, hsla(284.3, 83.7%, 59.2%, 0.764) 42.5%, hsla(279.2, 85%, 61.7%, 0.786) 49.3%, hsla(274, 86.4%, 64%, 0.808) 55.7%, hsla(268.5, 87.8%, 66.2%, 0.831) 61.8%, hsla(263, 89.4%, 68.2%, 0.854) 67.7%, hsla(257.4, 91%, 70.1%, 0.878) 73.4%, hsla(251.8, 92.7%, 71.8%, 0.902) 78.9%, hsla(246.2, 94.4%, 73.4%, 0.927) 84.3%, hsla(240.6, 96.2%, 74.9%, 0.951) 89.6%, hsla(235.4, 98.3%, 74.3%, 0.976) 94.9%, rgb(120,140,255) 100%);
3842
```
3943

4044
## Demo
41-
You can try it out by running `npm install` and `gulp` in the demo folder.
45+
You can try it out by running `npm install` and `gulp` in the demo folder.
4246

43-
This is how the scrim-gradient looks:
47+
This is how the scrim-gradient looks:
4448

4549
![compare](https://github.com/larsenwork/postcss-easing-gradients/blob/master/demo/compare.png?raw=true)

demo/gulpfile.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,12 @@ function watch() {
3636
function css() {
3737
return gulp
3838
.src(paths.styles.src)
39-
.pipe(gulpPostcss([easingGradient]))
39+
.pipe(gulpPostcss([
40+
easingGradient({
41+
precision: 0.15,
42+
alphaDecimals: 3
43+
})
44+
]))
4045
.pipe(gulpRename({extname: '.css'}))
4146
.pipe(gulp.dest(paths.styles.dest));
4247
};

helpers.js

+9-11
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ const easeInOutQuad = require('eases/quad-in-out');
1313
/**
1414
* Other constants
1515
*/
16-
const decimalPrecision = 3;
1716
const scrimCoordinates = {
1817
0.00: '0%',
1918
0.14: '8.52%',
@@ -33,13 +32,13 @@ const scrimCoordinates = {
3332
/**
3433
* Calculate the color stops based on start+stopColor in an array and easingType
3534
*/
36-
exports.getColorStops = function(colors, easingType) {
35+
exports.getColorStops = function(colors, easingType, delta, alphaDecimals) {
3736
colors = transparentFix(colors);
38-
let gradientCoordinates = getCoordinates(easingType);
37+
let gradientCoordinates = getCoordinates(easingType, delta);
3938
let colorStops = '';
4039
for (let ammount in gradientCoordinates) {
4140
let color = Color(colors[1]).mix(Color(colors[0]), ammount);
42-
color = roundHslHueAlpha(color.hsl().string());
41+
color = roundHslAlpha(color.hsl().string(), alphaDecimals);
4342
colorStops += `, ${color} ${gradientCoordinates[ammount]}`;
4443
}
4544
colorStops += `, ${colors[1]} 100%`;
@@ -60,14 +59,13 @@ function transparentFix(colors) {
6059
* Get coordinates based on easing function.
6160
* Delta checks ensures there's roughly the same distance between coordinates.
6261
*/
63-
function getCoordinates(easingFunction) {
62+
function getCoordinates(easingFunction, delta) {
6463
if (easingFunction === 'scrim-gradient') return scrimCoordinates;
6564

6665
const yIncrements = 0.001;
6766
const deltaTolerance = 0.01;
6867
const deltaAdjust = 0.001;
6968

70-
let delta = 0.1;
7169
let coordinates = {};
7270
let x = 0;
7371
let y = 0;
@@ -131,8 +129,8 @@ function ease(x, type) {
131129
/**
132130
* Convert decimal number to percentage string
133131
*/
134-
function getPercentage (num) {
135-
return parseFloat((num * 100).toFixed(decimalPrecision)) + '%';
132+
function getPercentage(number) {
133+
return round10(number * 100, -1) + '%';
136134
};
137135

138136
/**
@@ -143,15 +141,15 @@ function isFarEnough(x, y, xOld, yOld, delta) {
143141
};
144142

145143
/**
146-
* Round hue and alpha in hsl colors to decimalPrecision
144+
* Round alpha in hsl colors to alphaDecimals
147145
*/
148-
function roundHslHueAlpha(color) {
146+
function roundHslAlpha(color, alphaDecimals) {
149147
let prefix = color.substring(0, color.indexOf('('));
150148
let values = color
151149
.substring(color.indexOf('(') + 1, color.indexOf(')'))
152150
.split(',')
153151
.map(string => string.indexOf('%') === -1
154-
? round10(Number(string), -decimalPrecision)
152+
? round10(Number(string), -alphaDecimals)
155153
: string.trim()
156154
);
157155
return `${prefix}(${values.join(', ')})`;

index.js

+16-5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ const valueParser = require('postcss-value-parser');
99
/**
1010
* Other constants
1111
*/
12+
const defaultPrecision = 0.1;
13+
const defaultAlphaDecimals = 3;
1214
const errorPrefix = 'Error[postcss-easing-gradients]:';
1315
const supportedGradients = [
1416
'ease-in-sine-gradient',
@@ -24,8 +26,11 @@ const supportedGradients = [
2426
* The easing gradient function is a postcss plugin which supports the above
2527
* mentioned gradient types.
2628
*/
27-
module.exports = postcss.plugin('easing-gradient', function easingGradient() {
29+
module.exports =
30+
postcss.plugin('easing-gradient', function easingGradient(options) {
2831
return function (css) {
32+
options = options || {};
33+
2934
css.walkRules(function (rule) {
3035
rule.walkDecls(function (decl, i) {
3136

@@ -59,13 +64,14 @@ module.exports = postcss.plugin('easing-gradient', function easingGradient() {
5964
// If param isn't a color
6065
catch(error) {
6166

62-
// Test if it's a word or space and assume that's part of the
63-
// direction anotation — e.g. 'to'+' '+'top' or '45deg'
67+
// Test if it's a word or space and before the first color
68+
// and assume that's part of the direction anotation e.g.
69+
// 'to'+' '+'top' or '45deg'
6470
if (param.type === 'word' || param.type === 'space') {
6571
if (colors.length < 1) {
6672
direction += param.value;
6773

68-
// But if it happens after the first color then it's maybe
74+
// But if it happens after the first color then it's prolly
6975
// a color stop and not something we support
7076
} else if (param.type !== 'space') {
7177
let errorMsg = `${errorPrefix} Sorry, I don't support `;
@@ -96,7 +102,12 @@ module.exports = postcss.plugin('easing-gradient', function easingGradient() {
96102
}
97103

98104
// Get the color stops using our new
99-
const colorStops = helpers.getColorStops(colors, node.value);
105+
const colorStops = helpers.getColorStops(
106+
colors,
107+
node.value,
108+
options.precision || defaultPrecision,
109+
options.alphaDecimals || defaultAlphaDecimals
110+
);
100111

101112
// Update node
102113
node.type = 'word';

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "postcss-easing-gradients",
3-
"version": "1.1.2",
3+
"version": "1.2.0",
44
"description": "PostCSS plugin to create smooth linear-gradients that approximate easing functions.",
55
"main": "index.js",
66
"scripts": {

0 commit comments

Comments
 (0)