Skip to content

Commit 6da4b97

Browse files
committed
Introduce memo + fix render issues #5
1 parent 2d6c1d8 commit 6da4b97

File tree

1 file changed

+40
-42
lines changed

1 file changed

+40
-42
lines changed

generator.js

+40-42
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
TODO: write tests (lazy) like always right? <3
33
*/
44
const parser = require("gradient-parser");
5+
const memoize = require("fast-memoize");
56

67
const getColor = color => {
78
switch (color.type) {
@@ -14,27 +15,23 @@ const getColor = color => {
1415
}
1516
};
1617

17-
const getColorsAndLocations = (colorStops, maxWidth) =>
18+
const getColorsAndLocations = memoize((colorStops, maxWidth) =>
1819
colorStops.reduce(
1920
(acc, color, index) => {
2021
acc.colors = [...acc.colors, getColor(color)];
2122

2223
// PX value for location will break!
2324
// TODO Make it happen for px + repeat?
24-
const locationValue = getPixelsForColor(
25-
color,
26-
colorStops.length,
27-
index,
28-
maxWidth
29-
);
25+
const locationValue = getPixelsForColor(color, colorStops.length, index, maxWidth);
3026
acc["locations"] = [...acc.locations, locationValue];
3127

3228
return acc;
3329
},
3430
{ colors: [], locations: [] }
35-
);
31+
)
32+
);
3633

37-
const getPixelsForColor = (color, colorsLength, index, maxWidth) => {
34+
const getPixelsForColor = memoize((color, colorsLength, index, maxWidth) => {
3835
const { length } = color;
3936
if (!length) {
4037
return (1 / (colorsLength - 1)) * index;
@@ -49,33 +46,30 @@ const getPixelsForColor = (color, colorsLength, index, maxWidth) => {
4946
return length.value / 100;
5047
}
5148
}
52-
};
49+
});
50+
5351
const getRepeatingColorsAndLocations = (colorStops, sizes) => {
5452
const { width: maxWidth, height: maxHeight } = sizes;
55-
56-
if (!maxWidth && !maxHeight) {
57-
throw new Error(
58-
"You have to define width and height for repeating gradient to work"
59-
);
60-
}
61-
62-
const {
63-
colors: initialColors,
64-
locations: initialLocations
65-
} = getColorsAndLocations(colorStops, maxWidth);
53+
const { colors: initialColors, locations: initialLocations } = getColorsAndLocations(colorStops, maxWidth);
6654
const maxValue = parseFloat(initialLocations.slice(-1)[0]);
6755
const increment = maxValue / maxWidth;
68-
const maxChunks = Math.round(maxWidth / maxValue) + 1;
56+
// we need to add +1 but this is breaking LinearGradient, maybe can't render
57+
// it outside the viewport.
58+
const maxChunks = Math.round(maxWidth / maxValue);
6959
const locations = [...Array(maxChunks).keys()].reduce((acc, i) => {
70-
return [...acc, ...initialLocations.map(j => j / maxWidth + increment * i)];
60+
return [
61+
...acc,
62+
...initialLocations.map(j => {
63+
return j / maxWidth + increment * i;
64+
})
65+
];
7166
}, []);
72-
const colors = locations.map(
73-
(_, i) => initialColors[i % initialColors.length]
74-
);
67+
const colors = locations.map((_, i) => initialColors[i % initialColors.length]);
7568

76-
return { locations, colors };
69+
return { colors, locations };
7770
};
78-
const getVectorsByDirection = direction => {
71+
72+
const getVectorsByDirection = memoize(direction => {
7973
switch (direction) {
8074
case "top":
8175
return getVectorsByAngle(0);
@@ -94,35 +88,39 @@ const getVectorsByDirection = direction => {
9488
case "right bottom":
9589
return getVectorsByAngle(90 + 45);
9690
}
97-
};
98-
const round = number => Math.round(number * 1000) / 1000;
99-
const degreesToRadians = function(degrees) {
100-
return (degrees * Math.PI) / 180;
101-
};
102-
const getVectorsByAngle = alfa => {
91+
});
92+
93+
const round = memoize(number => Math.round(number * 10000) / 10000);
94+
const degreesToRadians = memoize(degrees => (degrees * Math.PI) / 180);
95+
96+
const getVectorsByAngle = memoize(alfa => {
10397
const angle = degreesToRadians(alfa);
10498

105-
let gradientLineLength = round(
106-
Math.abs(Math.sin(angle)) + Math.abs(Math.cos(angle))
107-
);
99+
let gradientLineLength = round(Math.abs(Math.sin(angle)) + Math.abs(Math.cos(angle)));
108100
let center = { x: 0.5, y: 0.5 };
109101

110102
let yDiff = (Math.sin(angle - Math.PI / 2) * gradientLineLength) / 2;
111103
let xDiff = (Math.cos(angle - Math.PI / 2) * gradientLineLength) / 2;
112104

113105
return {
114-
start: [center.x - xDiff, center.y - yDiff],
115-
end: [center.x + xDiff, center.y + yDiff]
106+
start: {
107+
x: center.x - xDiff,
108+
y: center.y - yDiff
109+
},
110+
end: {
111+
x: center.x + xDiff,
112+
y: center.y + yDiff
113+
}
116114
};
117-
};
115+
});
118116

119117
const getVectorsByOrientation = orientation => {
120118
return orientation.type === "directional"
121119
? getVectorsByDirection(orientation.value)
122120
: getVectorsByAngle(orientation.value);
123121
};
124122

125-
const generateGradient = (gradient, sizes) => {
123+
const generateGradient = memoize((gradient, sizes) => {
126124
return parser.parse(gradient).map(({ type, colorStops, orientation }) => {
127125
// YOLO: Radial gradients <3
128126
if (type === "radial-gradient") {
@@ -138,6 +136,6 @@ const generateGradient = (gradient, sizes) => {
138136
...getVectorsByOrientation(orientation)
139137
};
140138
});
141-
};
139+
});
142140

143141
export default generateGradient;

0 commit comments

Comments
 (0)