diff --git a/src/Gradient.js b/src/Gradient.js index b15c568..d542b84 100644 --- a/src/Gradient.js +++ b/src/Gradient.js @@ -34,7 +34,7 @@ export const parseGradient = ( bounds: Bounds ): ?Gradient => { if (method === 'linear-gradient') { - return parseLinearGradient(args, bounds); + return parseLinearGradient(args, bounds, !!prefix); } else if (method === 'gradient' && args[0] === 'linear') { // TODO handle correct angle return parseLinearGradient( @@ -46,18 +46,23 @@ export const parseGradient = ( // $FlowFixMe .map(v => v[2]) ), - bounds + bounds, + !!prefix ); } }; -const parseLinearGradient = (args: Array, bounds: Bounds): Gradient => { +const parseLinearGradient = (args: Array, bounds: Bounds, hasPrefix: boolean): Gradient => { const angle = parseAngle(args[0]); const HAS_SIDE_OR_CORNER = SIDE_OR_CORNER.test(args[0]); const HAS_DIRECTION = HAS_SIDE_OR_CORNER || angle !== null || PERCENTAGE_ANGLES.test(args[0]); const direction = HAS_DIRECTION ? angle !== null - ? calculateGradientDirection(angle, bounds) + ? calculateGradientDirection( + // if there is a prefix, the 0° angle points due East (instead of North per W3C) + hasPrefix ? angle - Math.PI * 0.5 : angle, + bounds + ) : HAS_SIDE_OR_CORNER ? parseSideOrCorner(args[0], bounds) : parsePercentageAngle(args[0], bounds) diff --git a/src/Renderer.js b/src/Renderer.js index ccc48f0..0cdfe7c 100644 --- a/src/Renderer.js +++ b/src/Renderer.js @@ -30,7 +30,8 @@ import { calculateBackgroungPaintingArea, calculateBackgroundPosition, calculateBackgroundRepeatPath, - calculateBackgroundSize + calculateBackgroundSize, + calculateGradientBackgroundSize } from './parsing/background'; import {BORDER_STYLE} from './parsing/border'; @@ -202,12 +203,8 @@ export default class Renderer { container.style.background.backgroundImage.slice(0).reverse().forEach(backgroundImage => { if (backgroundImage.source.method === 'url' && backgroundImage.source.args.length) { this.renderBackgroundRepeat(container, backgroundImage); - } else { - const gradient = parseGradient(backgroundImage.source, container.bounds); - if (gradient) { - const bounds = container.bounds; - this.target.renderLinearGradient(bounds, gradient); - } + } else if (/gradient/i.test(backgroundImage.source.method)) { + this.renderBackgroundGradient(container, backgroundImage); } }); } @@ -245,6 +242,35 @@ export default class Renderer { } } + renderBackgroundGradient(container: NodeContainer, background: BackgroundImage) { + const backgroundPositioningArea = calculateBackgroungPositioningArea( + container.style.background.backgroundOrigin, + container.bounds, + container.style.padding, + container.style.border + ); + const backgroundImageSize = calculateGradientBackgroundSize( + background, + backgroundPositioningArea + ); + const position = calculateBackgroundPosition( + background.position, + backgroundImageSize, + backgroundPositioningArea + ); + const gradientBounds = new Bounds( + Math.round(backgroundPositioningArea.left + position.x), + Math.round(backgroundPositioningArea.top + position.y), + backgroundImageSize.width, + backgroundImageSize.height + ); + + const gradient = parseGradient(background.source, gradientBounds); + if (gradient) { + this.target.renderLinearGradient(gradientBounds, gradient); + } + } + renderBorder(border: Border, side: BorderSide, curvePoints: BoundCurves) { this.target.drawShape(parsePathForBorder(curvePoints, side), border.borderColor); } diff --git a/src/parsing/background.js b/src/parsing/background.js index bc12be2..3214975 100644 --- a/src/parsing/background.js +++ b/src/parsing/background.js @@ -123,6 +123,19 @@ export const calculateBackgroundSize = ( return new Size(width, height); }; +export const calculateGradientBackgroundSize = ( + backgroundImage: BackgroundImage, + bounds: Bounds +): Size => { + const size = backgroundImage.size; + const width = size[0].value ? size[0].value.getAbsoluteValue(bounds.width) : bounds.width; + const height = size[1].value + ? size[1].value.getAbsoluteValue(bounds.height) + : size[0].value ? width : bounds.height; + + return new Size(width, height); +}; + const AUTO_SIZE = new BackgroundSize(AUTO); export const calculateBackgroungPaintingArea = ( diff --git a/tests/reftests/background/linear-gradient2.html b/tests/reftests/background/linear-gradient2.html new file mode 100644 index 0000000..badadc6 --- /dev/null +++ b/tests/reftests/background/linear-gradient2.html @@ -0,0 +1,42 @@ + + + + Background attribute tests + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + \ No newline at end of file