Enforce minimum gradient size

This fixes the bug where percertly horizontal gradients on perfectly
vertical lines and vice versa would not be rendered at all
This commit is contained in:
adroitwhiz 2020-07-23 06:07:05 -04:00
parent f0b1881fb0
commit 689532f269

View file

@ -64,9 +64,10 @@ const getRotatedColor = function (firstColor) {
* @param {paper.Rectangle} bounds Bounds of the object * @param {paper.Rectangle} bounds Bounds of the object
* @param {?paper.Point} [radialCenter] Where the center of a radial gradient should be, if the gradient is radial. * @param {?paper.Point} [radialCenter] Where the center of a radial gradient should be, if the gradient is radial.
* Defaults to center of bounds. * Defaults to center of bounds.
* @param {number} [minSize] The minimum width/height of the gradient object.
* @return {paper.Color} Color object with gradient, may be null or color string if the gradient type is solid * @return {paper.Color} Color object with gradient, may be null or color string if the gradient type is solid
*/ */
const createGradientObject = function (color1, color2, gradientType, bounds, radialCenter) { const createGradientObject = function (color1, color2, gradientType, bounds, radialCenter, minSize) {
if (gradientType === GradientTypes.SOLID) return color1; if (gradientType === GradientTypes.SOLID) return color1;
if (color1 === null) { if (color1 === null) {
color1 = getColorStringForTransparent(color2); color1 = getColorStringForTransparent(color2);
@ -74,15 +75,50 @@ const createGradientObject = function (color1, color2, gradientType, bounds, rad
if (color2 === null) { if (color2 === null) {
color2 = getColorStringForTransparent(color1); color2 = getColorStringForTransparent(color1);
} }
const halfLongestDimension = Math.max(bounds.width, bounds.height) / 2;
const start = gradientType === GradientTypes.RADIAL ? (radialCenter || bounds.center) : // Force gradients to have a minimum length. If the gradient start and end points are the same or very close
gradientType === GradientTypes.VERTICAL ? bounds.topCenter : // (e.g. applying a vertical gradient to a perfectly horizontal line or vice versa), the gradient will not appear.
gradientType === GradientTypes.HORIZONTAL ? bounds.leftCenter : if (!minSize) minSize = 1e-2;
null;
const end = gradientType === GradientTypes.RADIAL ? start.add(new paper.Point(halfLongestDimension, 0)) : let start;
gradientType === GradientTypes.VERTICAL ? bounds.bottomCenter : let end;
gradientType === GradientTypes.HORIZONTAL ? bounds.rightCenter : switch (gradientType) {
null; case GradientTypes.HORIZONTAL: {
// clone these points so that adding/subtracting doesn't affect actual bounds
start = bounds.leftCenter.clone();
end = bounds.rightCenter.clone();
const gradientSize = Math.abs(end.x - start.x);
if (gradientSize < minSize) {
const sizeDiff = (minSize - gradientSize) / 2;
end.x += sizeDiff;
start.x -= sizeDiff;
}
break;
}
case GradientTypes.VERTICAL: {
// clone these points so that adding/subtracting doesn't affect actual bounds
start = bounds.topCenter.clone();
end = bounds.bottomCenter.clone();
const gradientSize = Math.abs(end.y - start.y);
if (gradientSize < minSize) {
const sizeDiff = (minSize - gradientSize) / 2;
end.y += sizeDiff;
start.y -= sizeDiff;
}
break;
}
case GradientTypes.RADIAL: {
const halfLongestDimension = Math.max(bounds.width, bounds.height) / 2;
start = radialCenter || bounds.center;
end = start.add(new paper.Point(
Math.max(halfLongestDimension, minSize / 2),
0));
break;
}
}
return { return {
gradient: { gradient: {
stops: [color1, color2], stops: [color1, color2],
@ -544,7 +580,14 @@ const styleShape = function (path, options) {
path[colorKey] = options[colorKey].primary; path[colorKey] = options[colorKey].primary;
} else { } else {
const {primary, secondary, gradientType} = options[colorKey]; const {primary, secondary, gradientType} = options[colorKey];
path[colorKey] = createGradientObject(primary, secondary, gradientType, path.bounds); path[colorKey] = createGradientObject(
primary,
secondary,
gradientType,
path.bounds,
null, // radialCenter
options.strokeWidth // minimum gradient size is stroke width
);
} }
} }