Fix tests and refactor background calculations out from Renderer

This commit is contained in:
Niklas von Hertzen 2017-12-09 17:45:58 +08:00
parent 850338a76a
commit a6a3c1bd0f
4 changed files with 52 additions and 41 deletions

View File

@ -1,6 +1,8 @@
### Changelog ### ### Changelog ###
#### v1.0.0-alpha3 - TBD #### #### v1.0.0-alpha3 - TBD ####
* Fix background-size when using background-origin and background-size: cover/contain (#1299)
* Added support for background-origin: content-box (#1299)
#### v1.0.0-alpha2 - 7.12.2017 #### #### v1.0.0-alpha2 - 7.12.2017 ####
* Fix scroll positions for CanvasRenderer (#1259) * Fix scroll positions for CanvasRenderer (#1259)

View File

@ -20,20 +20,13 @@ import type NodeContainer from './NodeContainer';
import type StackingContext from './StackingContext'; import type StackingContext from './StackingContext';
import type {TextBounds} from './TextBounds'; import type {TextBounds} from './TextBounds';
import { import {Bounds, parsePathForBorder, calculateContentBox, calculatePaddingBoxPath} from './Bounds';
Bounds,
parsePathForBorder,
calculateContentBox,
calculatePaddingBox,
calculatePaddingBoxPath
} from './Bounds';
import {PADDING_SIDES} from './parsing/padding';
import {FontMetrics} from './Font'; import {FontMetrics} from './Font';
import {parseGradient} from './Gradient'; import {parseGradient} from './Gradient';
import TextContainer from './TextContainer'; import TextContainer from './TextContainer';
import { import {
BACKGROUND_ORIGIN, calculateBackgroungPositioningArea,
calculateBackgroungPaintingArea, calculateBackgroungPaintingArea,
calculateBackgroundPosition, calculateBackgroundPosition,
calculateBackgroundRepeatPath, calculateBackgroundRepeatPath,
@ -222,32 +215,12 @@ export default class Renderer {
renderBackgroundRepeat(container: NodeContainer, background: BackgroundImage) { renderBackgroundRepeat(container: NodeContainer, background: BackgroundImage) {
const image = this.options.imageStore.get(background.source.args[0]); const image = this.options.imageStore.get(background.source.args[0]);
if (image) { if (image) {
const bounds = container.bounds; const backgroundPositioningArea = calculateBackgroungPositioningArea(
const paddingBox = calculatePaddingBox(bounds, container.style.border); container.style.background.backgroundOrigin,
container.bounds,
let backgroundPositioningArea; container.style.padding,
switch (container.style.background.backgroundOrigin) { container.style.border
case BACKGROUND_ORIGIN.BORDER_BOX:
backgroundPositioningArea = bounds;
break;
case BACKGROUND_ORIGIN.CONTENT_BOX:
const paddingLeft = container.style.padding[PADDING_SIDES.LEFT].value;
const paddingRight = container.style.padding[PADDING_SIDES.RIGHT].value;
const paddingTop = container.style.padding[PADDING_SIDES.TOP].value;
const paddingBottom = container.style.padding[PADDING_SIDES.BOTTOM].value;
backgroundPositioningArea = new Bounds(
paddingBox.left + paddingLeft,
paddingBox.top + paddingTop,
paddingBox.width - paddingLeft - paddingRight,
paddingBox.height - paddingTop - paddingBottom
); );
break;
case BACKGROUND_ORIGIN.PADDING_BOX:
default:
backgroundPositioningArea = paddingBox;
break;
}
const backgroundImageSize = calculateBackgroundSize( const backgroundImageSize = calculateBackgroundSize(
background, background,
image, image,
@ -263,7 +236,7 @@ export default class Renderer {
position, position,
backgroundImageSize, backgroundImageSize,
backgroundPositioningArea, backgroundPositioningArea,
bounds container.bounds
); );
const offsetX = Math.round(backgroundPositioningArea.left + position.x); const offsetX = Math.round(backgroundPositioningArea.left + position.x);

View File

@ -1,14 +1,22 @@
/* @flow */ /* @flow */
'use strict'; 'use strict';
import type {Path} from '../drawing/Path'; import type {Path} from '../drawing/Path';
import type {Bounds, BoundCurves} from '../Bounds'; import type {BoundCurves} from '../Bounds';
import type ResourceLoader, {ImageElement} from '../ResourceLoader'; import type ResourceLoader, {ImageElement} from '../ResourceLoader';
import type {Border} from './border';
import type {Padding} from './padding';
import Color from '../Color'; import Color from '../Color';
import Length from '../Length'; import Length from '../Length';
import Size from '../drawing/Size'; import Size from '../drawing/Size';
import Vector from '../drawing/Vector'; import Vector from '../drawing/Vector';
import {calculateBorderBoxPath, calculatePaddingBoxPath} from '../Bounds'; import {
calculateBorderBoxPath,
calculatePaddingBoxPath,
calculatePaddingBox,
Bounds
} from '../Bounds';
import {PADDING_SIDES} from './padding';
export type Background = { export type Background = {
backgroundImage: Array<BackgroundImage>, backgroundImage: Array<BackgroundImage>,
@ -121,7 +129,6 @@ export const calculateBackgroungPaintingArea = (
curves: BoundCurves, curves: BoundCurves,
clip: BackgroundClip clip: BackgroundClip
): Path => { ): Path => {
// TODO support CONTENT_BOX
switch (clip) { switch (clip) {
case BACKGROUND_CLIP.BORDER_BOX: case BACKGROUND_CLIP.BORDER_BOX:
return calculateBorderBoxPath(curves); return calculateBorderBoxPath(curves);
@ -131,6 +138,34 @@ export const calculateBackgroungPaintingArea = (
} }
}; };
export const calculateBackgroungPositioningArea = (
backgroundOrigin: BackgroundOrigin,
bounds: Bounds,
padding: Padding,
border: Array<Border>
): Bounds => {
const paddingBox = calculatePaddingBox(bounds, border);
switch (backgroundOrigin) {
case BACKGROUND_ORIGIN.BORDER_BOX:
return bounds;
case BACKGROUND_ORIGIN.CONTENT_BOX:
const paddingLeft = padding[PADDING_SIDES.LEFT].getAbsoluteValue(bounds.width);
const paddingRight = padding[PADDING_SIDES.RIGHT].getAbsoluteValue(bounds.width);
const paddingTop = padding[PADDING_SIDES.TOP].getAbsoluteValue(bounds.width);
const paddingBottom = padding[PADDING_SIDES.BOTTOM].getAbsoluteValue(bounds.width);
return new Bounds(
paddingBox.left + paddingLeft,
paddingBox.top + paddingTop,
paddingBox.width - paddingLeft - paddingRight,
paddingBox.height - paddingTop - paddingBottom
);
case BACKGROUND_ORIGIN.PADDING_BOX:
default:
return paddingBox;
}
};
export const calculateBackgroundPosition = ( export const calculateBackgroundPosition = (
position: [Length, Length], position: [Length, Length],
size: Size, size: Size,

View File

@ -1,6 +1,7 @@
<!doctype html> <!doctype html>
<html> <html>
<head> <head>
<script type="text/javascript" src="../../test.js"></script>
<style> <style>
div { div {
display: inline-block; display: inline-block;
@ -9,7 +10,7 @@
border: 15px solid blue; border: 15px solid blue;
padding: 10px; padding: 10px;
margin: 5px; margin: 5px;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAqxQTFRFAAAAAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAADAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAACAAAA01YBTwAAAOJ0Uk5TAABuRlv++VX6/GY083kXJemLAZRLGN2MhdsMWeUpZ7IDArTsKAaKywommQm29TskpOCujfda8YDSL0ntQ7hPIPiPGT2p++8EUmt7fG0Shtifg3es6xxx9P0tvWq5Yxbf9mE4yGIe2soHLsVlIcZpU0K+MLqgGyfmVJfE1+LNnoh2QSsx0V3j0xOo5zdXCM8OOkwjosxFtRXyStxWvMmSaGDOX2ynIh01w+q/t1ixBVytQHAywZybXirku342mj7ZjpAacg3wnQuBENQ/wA/Wlcc8eh9NgoSr1aazeEcRf+FzUNOe+4wAAAABYktHRACIBR1IAAAACXBIWXMAAAmoAAAJqAHjvc2aAAAEtElEQVRYw71W+19URRSfBe/KKsZKoAaBrPJSUAIJY7HAByxQqIgEyq6YroBKG0UiZqyWaJiKb9FEwwIr6WGmhVr2UgsNsoe9n+cvaR73fefqbvbp/LA7c875fufMmTPnDkL/j4SE3hl+hGAdeSf40DAA26h/jx8dDliEMUED72J/EXZgMjYySIK7o8hv9DiQZHyQBBPuicG/sTL+3jimDziQeJiYgJBjkoifnEi1SckpqQESTAGYihnS0il+2nSqzEgBuC/AGCyZAFlpeM0ZAkA2K6X7cwjZzABDSMa+D+TigdOeN4soEh9kuxEeCowgHxcQFMzGe58zBydj7rxCKZ9F0eYoV2JxSenDj0SV4fF8tt6CheWLkisWg0rMTrTy0fQq0aU6awlKWAomUsNNmtNtUztle9CyWi58+WM8/IqVej/Bi1bVcfD1uRx4w3ib0dO6GkWv0Svtax0cfGMKN9bHLcgRkqPW1PnSuNl7wiRZTdgW43myiIzD6ipCnnIgvlia+QRPi+Z1cXGNrlsWTYuVS7BenabWDc9sfHZcm7/JwmPYJGHC0jc/9/wWbzubxcgxbrXLtOmVHIKYbdT2Qk0Hmydtp/NVotkxVR3Yizs4DDuxoTlUuam7OonrbnG2QVdK0zl5XNq8R6PYS5YSt+vRJ2fxPiPDLt2cEOxnw/wq1eK19FDXmB2oLK4D2O0gC+6QUodbGxDqij8MEH8bvIPsuo3t4IiMf0lM6lG8u4Zb4nO7iX8x42qX8EXSzi3HALhXcsbx0pc9PTWzT1B/NzuTV+QAjsqOr+JLySPoVWe6iNVL6jZJMVFx7MO3nVdOJerL7GS6cklx+KTiGImPwschOCkoF1esitfkVlqi9qyXz1grr0veb4htp3G9pDml+Z70A7TTQVmxhuBNOYLqt/a+jZLekZtxTp/G8TS+drSWVrRp9C51E7RmKhVoc2pDJbVF791cyNcYivmdRSjR4hHplS1k8C6c0VoqeHh7rA5vycPa0WT0HpzVmrrcFefez9ooIuu9Xu8HO/cYOmkfMdI8V4Kti3ccEayhVJXR9QzmRcQ4QEYNAB4eAbKwL2MpGY/S3920TGJbR8fn4QKXQLxDteT065fobBeJqYDRukFo4TOspSF8iOu24COt5VIBsXzMJp8AfMon+IwSfI7QZbBtURsGJlNLP5vh3nClg58F+sK8itAXeCfLFL3zCjuhL9l0sNA0BNr8cIYsywGuDUhx+avFI74uar7CNZvBww/Rq7kSj4bx/7SvD+7rWB17OlvurlJP8+HJjSQOQSv1O4B0fUaS7ZLfbtxi4bixViLZi+OUuIZBvpE96VfnnCGGb5lfLx7mC0Z8p7Lkd3Rbw99rgkiYKYJuklm3keCIynksUw2PGZCazuURciunfeC6Ad+rXm3wvKTOu+CfcHP+whtyqqGKfeCv6vDXhjTbbaoGM/Ezj9RjGu2wvqX/YIa3RkhRulXaHwcNR+Y3IbiouPT8xFSF/bM4RZPwMxf/i+ZllTHyzK81v/3Or/vIPzhnfZb/KDSRqD/1+O6hYPD41m4KV8MLy13B4Umq/+qUDjR8f1zQcCpDl1p9vp6/p9z2CfQfyT/GmLpixQvIqwAAAGJ0RVh0Y29tbWVudABib3JkZXIgYnM6MCBiYzojMDAwMDAwIHBzOjAgcGM6I2VlZWVlZSBlczowIGVjOiMwMDAwMDAgY2s6NTAwZDAyYTRmMWYxZDc0OTczNDBjYzU4Njg5NmJmMTGEn9AAAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTA0LTE4VDA5OjU0OjU4KzAwOjAwhlt+sgAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wNC0xOFQwOTo1NDo1OCswMDowMPcGxg4AAAAydEVYdExpY2Vuc2UAaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9QdWJsaWNfZG9tYWluP/3qzwAAAE10RVh0c29mdHdhcmUASW1hZ2VNYWdpY2sgNy4wLjEtNiBRMTYgeDg2XzY0IDIwMTYtMDktMTcgaHR0cDovL3d3dy5pbWFnZW1hZ2ljay5vcmfd2aVOAAAAGHRFWHRTb3VyY2UAV2lraW1lZGlhIENvbW1vbnPSwlOaAAAANnRFWHRTb3VyY2VfVVJMAGh0dHA6Ly9jb21tb25zLndpa2ltZWRpYS5vcmcvd2lraS9NYWluX1BhZ2US/BctAAAAGHRFWHRUaHVtYjo6RG9jdW1lbnQ6OlBhZ2VzADGn/7svAAAAGHRFWHRUaHVtYjo6SW1hZ2U6OkhlaWdodAAyNTbpw0QZAAAAF3RFWHRUaHVtYjo6SW1hZ2U6OldpZHRoADI1NnoyFEQAAAAZdEVYdFRodW1iOjpNaW1ldHlwZQBpbWFnZS9wbmc/slZOAAAAF3RFWHRUaHVtYjo6TVRpbWUAMTMwNDA2NDg0MNaK6HQAAAASdEVYdFRodW1iOjpTaXplADEwLjhLQr49AxAAAABddEVYdFRodW1iOjpVUkkAZmlsZTovLy9ob21lL3d3d3Jvb3Qvc2l0ZS93d3cuZWFzeWljb24ubmV0L2Nkbi1pbWcuZWFzeWljb24uY24vc3JjLzU0MzEvNTQzMTAxLnBuZ/nLz6kAAAAASUVORK5CYII='); background-image: url(../../assets/image.jpg);
} }
</style> </style>
</head> </head>