Fix background-clip and background-origin rendering

This commit is contained in:
Niklas von Hertzen 2017-08-02 20:29:45 +08:00
parent 213f35f61c
commit 52a815a13f
4 changed files with 293 additions and 145 deletions

View File

@ -2,6 +2,10 @@
'use strict'; 'use strict';
import Vector from './Vector'; import Vector from './Vector';
const lerp = (a: Vector, b: Vector, t: number): Vector => {
return new Vector(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t);
};
export default class BezierCurve { export default class BezierCurve {
start: Vector; start: Vector;
startControl: Vector; startControl: Vector;
@ -15,21 +19,16 @@ export default class BezierCurve {
this.end = end; this.end = end;
} }
lerp(a: Vector, b: Vector, t: number): Vector { subdivide(t: number, firstHalf: boolean): BezierCurve {
return new Vector(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t); const ab = lerp(this.start, this.startControl, t);
} const bc = lerp(this.startControl, this.endControl, t);
const cd = lerp(this.endControl, this.end, t);
subdivide(t: number): [BezierCurve, BezierCurve] { const abbc = lerp(ab, bc, t);
const ab = this.lerp(this.start, this.startControl, t); const bccd = lerp(bc, cd, t);
const bc = this.lerp(this.startControl, this.endControl, t); const dest = lerp(abbc, bccd, t);
const cd = this.lerp(this.endControl, this.end, t); return firstHalf
const abbc = this.lerp(ab, bc, t); ? new BezierCurve(this.start, ab, abbc, dest)
const bccd = this.lerp(bc, cd, t); : new BezierCurve(dest, bccd, cd, this.end);
const dest = this.lerp(abbc, bccd, t);
return [
new BezierCurve(this.start, ab, abbc, dest),
new BezierCurve(dest, bccd, cd, this.end)
];
} }
reverse(): BezierCurve { reverse(): BezierCurve {

View File

@ -15,15 +15,18 @@ const RIGHT = 1;
const BOTTOM = 2; const BOTTOM = 2;
const LEFT = 3; const LEFT = 3;
const H = 0;
const V = 0;
export type BoundCurves = { export type BoundCurves = {
topLeftOuter: [BezierCurve, BezierCurve], topLeftOuter: BezierCurve | Vector,
topLeftInner: [BezierCurve, BezierCurve], topLeftInner: BezierCurve | Vector,
topRightOuter: [BezierCurve, BezierCurve], topRightOuter: BezierCurve | Vector,
topRightInner: [BezierCurve, BezierCurve], topRightInner: BezierCurve | Vector,
bottomRightOuter: [BezierCurve, BezierCurve], bottomRightOuter: BezierCurve | Vector,
bottomRightInner: [BezierCurve, BezierCurve], bottomRightInner: BezierCurve | Vector,
bottomLeftOuter: [BezierCurve, BezierCurve], bottomLeftOuter: BezierCurve | Vector,
bottomLeftInner: [BezierCurve, BezierCurve] bottomLeftInner: BezierCurve | Vector
}; };
export class Bounds { export class Bounds {
@ -123,6 +126,7 @@ export const parsePathForBorder = (curves: BoundCurves, borderSide: BorderSide):
curves.bottomLeftOuter, curves.bottomLeftOuter,
curves.bottomLeftInner curves.bottomLeftInner
); );
case LEFT:
default: default:
return createPathFromCurves( return createPathFromCurves(
curves.bottomLeftOuter, curves.bottomLeftOuter,
@ -134,16 +138,35 @@ export const parsePathForBorder = (curves: BoundCurves, borderSide: BorderSide):
}; };
const createPathFromCurves = ( const createPathFromCurves = (
outer1: [BezierCurve, BezierCurve], outer1: BezierCurve | Vector,
inner1: [BezierCurve, BezierCurve], inner1: BezierCurve | Vector,
outer2: [BezierCurve, BezierCurve], outer2: BezierCurve | Vector,
inner2: [BezierCurve, BezierCurve] inner2: BezierCurve | Vector
): Path => { ): Path => {
const path = []; const path = [];
path.push(outer1[1]); if (outer1 instanceof BezierCurve) {
path.push(outer2[0]); path.push(outer1.subdivide(0.5, false));
path.push(inner2[0].reverse()); } else {
path.push(inner1[1].reverse()); path.push(outer1);
}
if (outer2 instanceof BezierCurve) {
path.push(outer2.subdivide(0.5, true));
} else {
path.push(outer2);
}
if (inner2 instanceof BezierCurve) {
path.push(inner2.subdivide(0.5, true).reverse());
} else {
path.push(inner2);
}
if (inner1 instanceof BezierCurve) {
path.push(inner1.subdivide(0.5, false).reverse());
} else {
path.push(inner1);
}
return path; return path;
}; };
@ -154,22 +177,40 @@ export const parseBoundCurves = (
borderRadius: Array<BorderRadius> borderRadius: Array<BorderRadius>
): BoundCurves => { ): BoundCurves => {
// TODO support percentage borderRadius // TODO support percentage borderRadius
const HALF_WIDTH = bounds.width / 2;
const HALF_HEIGHT = bounds.height / 2;
const tlh = const tlh =
borderRadius[0][0].value < bounds.width / 2 ? borderRadius[0][0].value : bounds.width / 2; borderRadius[CORNER.TOP_LEFT][H].value < HALF_WIDTH
? borderRadius[CORNER.TOP_LEFT][H].value
: HALF_WIDTH;
const tlv = const tlv =
borderRadius[0][1].value < bounds.height / 2 ? borderRadius[0][1].value : bounds.height / 2; borderRadius[CORNER.TOP_LEFT][V].value < HALF_HEIGHT
? borderRadius[CORNER.TOP_LEFT][V].value
: HALF_HEIGHT;
const trh = const trh =
borderRadius[1][0].value < bounds.width / 2 ? borderRadius[1][0].value : bounds.width / 2; borderRadius[CORNER.TOP_RIGHT][H].value < HALF_WIDTH
? borderRadius[CORNER.TOP_RIGHT][H].value
: HALF_WIDTH;
const trv = const trv =
borderRadius[1][1].value < bounds.height / 2 ? borderRadius[1][1].value : bounds.height / 2; borderRadius[CORNER.TOP_RIGHT][V].value < HALF_HEIGHT
? borderRadius[CORNER.TOP_RIGHT][V].value
: HALF_HEIGHT;
const brh = const brh =
borderRadius[2][0].value < bounds.width / 2 ? borderRadius[2][0].value : bounds.width / 2; borderRadius[CORNER.BOTTOM_RIGHT][H].value < HALF_WIDTH
? borderRadius[CORNER.BOTTOM_RIGHT][H].value
: HALF_WIDTH;
const brv = const brv =
borderRadius[2][1].value < bounds.height / 2 ? borderRadius[2][1].value : bounds.height / 2; borderRadius[CORNER.BOTTOM_RIGHT][V].value < HALF_HEIGHT
? borderRadius[CORNER.BOTTOM_RIGHT][V].value
: HALF_HEIGHT;
const blh = const blh =
borderRadius[3][0].value < bounds.width / 2 ? borderRadius[3][0].value : bounds.width / 2; borderRadius[CORNER.BOTTOM_LEFT][H].value < HALF_WIDTH
? borderRadius[CORNER.BOTTOM_LEFT][H].value
: HALF_WIDTH;
const blv = const blv =
borderRadius[3][1].value < bounds.height / 2 ? borderRadius[3][1].value : bounds.height / 2; borderRadius[CORNER.BOTTOM_LEFT][V].value < HALF_HEIGHT
? borderRadius[CORNER.BOTTOM_LEFT][V].value
: HALF_HEIGHT;
const topWidth = bounds.width - trh; const topWidth = bounds.width - trh;
const rightHeight = bounds.height - brv; const rightHeight = bounds.height - brv;
@ -177,58 +218,82 @@ export const parseBoundCurves = (
const leftHeight = bounds.height - blv; const leftHeight = bounds.height - blv;
return { return {
topLeftOuter: getCurvePoints(bounds.left, bounds.top, tlh, tlv, CORNER.TOP_LEFT).subdivide( topLeftOuter:
0.5 tlh > 0 || tlv > 0
), ? getCurvePoints(bounds.left, bounds.top, tlh, tlv, CORNER.TOP_LEFT)
topLeftInner: getCurvePoints( : new Vector(bounds.left, bounds.top),
bounds.left + borders[3].borderWidth, topLeftInner:
bounds.top + borders[0].borderWidth, tlh > 0 || tlv > 0
Math.max(0, tlh - borders[3].borderWidth), ? getCurvePoints(
Math.max(0, tlv - borders[0].borderWidth), bounds.left + borders[LEFT].borderWidth,
CORNER.TOP_LEFT bounds.top + borders[TOP].borderWidth,
).subdivide(0.5), Math.max(0, tlh - borders[LEFT].borderWidth),
topRightOuter: getCurvePoints( Math.max(0, tlv - borders[TOP].borderWidth),
bounds.left + topWidth, CORNER.TOP_LEFT
bounds.top, )
trh, : new Vector(
trv, bounds.left + borders[LEFT].borderWidth,
CORNER.TOP_RIGHT bounds.top + borders[TOP].borderWidth
).subdivide(0.5), ),
topRightInner: getCurvePoints( topRightOuter:
bounds.left + Math.min(topWidth, bounds.width + borders[3].borderWidth), trh > 0 || trv > 0
bounds.top + borders[0].borderWidth, ? getCurvePoints(bounds.left + topWidth, bounds.top, trh, trv, CORNER.TOP_RIGHT)
topWidth > bounds.width + borders[3].borderWidth ? 0 : trh - borders[3].borderWidth, : new Vector(bounds.left + bounds.width, bounds.top),
trv - borders[0].borderWidth, topRightInner:
CORNER.TOP_RIGHT trh > 0 || trv > 0
).subdivide(0.5), ? getCurvePoints(
bottomRightOuter: getCurvePoints( bounds.left + Math.min(topWidth, bounds.width + borders[LEFT].borderWidth),
bounds.left + bottomWidth, bounds.top + borders[TOP].borderWidth,
bounds.top + rightHeight, topWidth > bounds.width + borders[LEFT].borderWidth
brh, ? 0
brv, : trh - borders[LEFT].borderWidth,
CORNER.BOTTOM_RIGHT trv - borders[TOP].borderWidth,
).subdivide(0.5), CORNER.TOP_RIGHT
bottomRightInner: getCurvePoints( )
bounds.left + Math.min(bottomWidth, bounds.width - borders[3].borderWidth), : new Vector(
bounds.top + Math.min(rightHeight, bounds.height + borders[0].borderWidth), bounds.left + bounds.width - borders[RIGHT].borderWidth,
Math.max(0, brh - borders[1].borderWidth), bounds.top + borders[TOP].borderWidth
brv - borders[2].borderWidth, ),
CORNER.BOTTOM_RIGHT bottomRightOuter:
).subdivide(0.5), brh > 0 || brv > 0
bottomLeftOuter: getCurvePoints( ? getCurvePoints(
bounds.left, bounds.left + bottomWidth,
bounds.top + leftHeight, bounds.top + rightHeight,
blh, brh,
blv, brv,
CORNER.BOTTOM_LEFT CORNER.BOTTOM_RIGHT
).subdivide(0.5), )
bottomLeftInner: getCurvePoints( : new Vector(bounds.left + bounds.width, bounds.top + bounds.height),
bounds.left + borders[3].borderWidth, bottomRightInner:
bounds.top + leftHeight, brh > 0 || brv > 0
Math.max(0, blh - borders[3].borderWidth), ? getCurvePoints(
blv - borders[2].borderWidth, bounds.left + Math.min(bottomWidth, bounds.width - borders[LEFT].borderWidth),
CORNER.BOTTOM_LEFT bounds.top + Math.min(rightHeight, bounds.height + borders[TOP].borderWidth),
).subdivide(0.5) Math.max(0, brh - borders[RIGHT].borderWidth),
brv - borders[BOTTOM].borderWidth,
CORNER.BOTTOM_RIGHT
)
: new Vector(
bounds.left + bounds.width - borders[RIGHT].borderWidth,
bounds.top + bounds.height - borders[BOTTOM].borderWidth
),
bottomLeftOuter:
blh > 0 || blv > 0
? getCurvePoints(bounds.left, bounds.top + leftHeight, blh, blv, CORNER.BOTTOM_LEFT)
: new Vector(bounds.left, bounds.top + bounds.height),
bottomLeftInner:
blh > 0 || blv > 0
? getCurvePoints(
bounds.left + borders[LEFT].borderWidth,
bounds.top + leftHeight,
Math.max(0, blh - borders[LEFT].borderWidth),
blv - borders[BOTTOM].borderWidth,
CORNER.BOTTOM_LEFT
)
: new Vector(
bounds.left + borders[LEFT].borderWidth,
bounds.top + bounds.height - borders[BOTTOM].borderWidth
)
}; };
}; };
@ -276,11 +341,13 @@ const getCurvePoints = (
new Vector(x + ox, ym), new Vector(x + ox, ym),
new Vector(x, ym) new Vector(x, ym)
); );
case CORNER.BOTTOM_LEFT:
default:
return new BezierCurve(
new Vector(xm, ym),
new Vector(xm - ox, ym),
new Vector(x, y + oy),
new Vector(x, y)
);
} }
return new BezierCurve(
new Vector(xm, ym),
new Vector(xm - ox, ym),
new Vector(x, y + oy),
new Vector(x, y)
);
}; };

View File

@ -16,9 +16,12 @@ import type {ImageStore} from './ImageLoader';
import type StackingContext from './StackingContext'; import type StackingContext from './StackingContext';
import { import {
calculateBackgroundSize, BACKGROUND_CLIP,
BACKGROUND_ORIGIN,
calculateBackgroungPaintingArea,
calculateBackgroundPosition, calculateBackgroundPosition,
calculateBackgroundRepeatPath calculateBackgroundRepeatPath,
calculateBackgroundSize
} from './parsing/background'; } from './parsing/background';
import {BORDER_STYLE} from './parsing/border'; import {BORDER_STYLE} from './parsing/border';
import { import {
@ -98,7 +101,20 @@ export default class CanvasRenderer {
container.style.borderRadius container.style.borderRadius
); );
this.renderBackground(container); const backgroungPaintingArea = calculateBackgroungPaintingArea(
curvePoints,
container.style.background.backgroundClip
);
this.path(backgroungPaintingArea);
if (!container.style.background.backgroundColor.isTransparent()) {
this.ctx.fillStyle = container.style.background.backgroundColor.toString();
this.ctx.fill();
}
this.ctx.save();
this.ctx.clip();
this.renderBackgroundImage(container);
this.ctx.restore();
container.style.border.forEach((border, side) => { container.style.border.forEach((border, side) => {
this.renderBorder(border, side, curvePoints); this.renderBorder(border, side, curvePoints);
}); });
@ -112,25 +128,6 @@ export default class CanvasRenderer {
this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height); this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height);
} }
renderBackground(container: NodeContainer) {
if (container.bounds.height > 0 && container.bounds.width > 0) {
this.renderBackgroundColor(container);
this.renderBackgroundImage(container);
}
}
renderBackgroundColor(container: NodeContainer) {
if (!container.style.background.backgroundColor.isTransparent()) {
this.rectangle(
container.bounds.left,
container.bounds.top,
container.bounds.width,
container.bounds.height,
container.style.background.backgroundColor
);
}
}
renderBackgroundImage(container: NodeContainer) { renderBackgroundImage(container: NodeContainer) {
container.style.background.backgroundImage.reverse().forEach(backgroundImage => { container.style.background.backgroundImage.reverse().forEach(backgroundImage => {
if (backgroundImage.source.method === 'url' && backgroundImage.source.args.length) { if (backgroundImage.source.method === 'url' && backgroundImage.source.args.length) {
@ -144,13 +141,33 @@ export default class CanvasRenderer {
if (image) { if (image) {
const bounds = container.bounds; const bounds = container.bounds;
const paddingBox = calculatePaddingBox(bounds, container.style.border); const paddingBox = calculatePaddingBox(bounds, container.style.border);
const size = calculateBackgroundSize(background, image, bounds); const backgroundImageSize = calculateBackgroundSize(background, image, bounds);
const position = calculateBackgroundPosition(background.position, size, bounds);
const path = calculateBackgroundRepeatPath(background, position, size, paddingBox); // TODO support CONTENT_BOX
const backgroundPositioningArea =
container.style.background.backgroundOrigin === BACKGROUND_ORIGIN.BORDER_BOX
? bounds
: paddingBox;
const position = calculateBackgroundPosition(
background.position,
backgroundImageSize,
backgroundPositioningArea
);
const path = calculateBackgroundRepeatPath(
background,
position,
backgroundImageSize,
backgroundPositioningArea,
bounds
);
this.path(path); this.path(path);
const offsetX = Math.round(paddingBox.left + position.x); const offsetX = Math.round(paddingBox.left + position.x);
const offsetY = Math.round(paddingBox.top + position.y); const offsetY = Math.round(paddingBox.top + position.y);
this.ctx.fillStyle = this.ctx.createPattern(this.resizeImage(image, size), 'repeat'); this.ctx.fillStyle = this.ctx.createPattern(
this.resizeImage(image, backgroundImageSize),
'repeat'
);
this.ctx.translate(offsetX, offsetY); this.ctx.translate(offsetX, offsetY);
this.ctx.fill(); this.ctx.fill();
this.ctx.translate(-offsetX, -offsetY); this.ctx.translate(-offsetX, -offsetY);

View File

@ -1,7 +1,7 @@
/* @flow */ /* @flow */
'use strict'; 'use strict';
import type {Bounds} from '../Bounds'; import type {Bounds, BoundCurves, Path} from '../Bounds';
import type ImageLoader from '../ImageLoader'; import type ImageLoader from '../ImageLoader';
import Color from '../Color'; import Color from '../Color';
@ -11,9 +11,13 @@ import Vector from '../Vector';
export type Background = { export type Background = {
backgroundImage: Array<BackgroundImage>, backgroundImage: Array<BackgroundImage>,
backgroundColor: Color backgroundClip: BackgroundClip,
backgroundColor: Color,
backgroundOrigin: BackgroundOrigin
}; };
export type BackgroundClip = $Values<typeof BACKGROUND_CLIP>;
export type BackgroundOrigin = $Values<typeof BACKGROUND_ORIGIN>;
export type BackgroundRepeat = $Values<typeof BACKGROUND_REPEAT>; export type BackgroundRepeat = $Values<typeof BACKGROUND_REPEAT>;
export type BackgroundSizeTypes = $Values<typeof BACKGROUND_SIZE>; export type BackgroundSizeTypes = $Values<typeof BACKGROUND_SIZE>;
@ -44,6 +48,14 @@ export const BACKGROUND_SIZE = {
LENGTH: 3 LENGTH: 3
}; };
export const BACKGROUND_CLIP = {
BORDER_BOX: 0,
PADDING_BOX: 1,
CONTENT_BOX: 2
};
export const BACKGROUND_ORIGIN = BACKGROUND_CLIP;
const AUTO = 'auto'; const AUTO = 'auto';
class BackgroundSize { class BackgroundSize {
@ -79,8 +91,8 @@ export const calculateBackgroundSize = (
const targetRatio = bounds.width / bounds.height; const targetRatio = bounds.width / bounds.height;
const currentRatio = image.width / image.height; const currentRatio = image.width / image.height;
return targetRatio < currentRatio !== (size[0].size === BACKGROUND_SIZE.COVER) return targetRatio < currentRatio !== (size[0].size === BACKGROUND_SIZE.COVER)
? new Size(bounds.height * currentRatio, bounds.height) ? new Size(bounds.width, bounds.width / currentRatio)
: new Size(bounds.width, bounds.width / currentRatio); : new Size(bounds.height * currentRatio, bounds.height);
} }
if (size[0].value) { if (size[0].value) {
@ -104,6 +116,30 @@ export const calculateBackgroundSize = (
const AUTO_SIZE = new BackgroundSize(AUTO); const AUTO_SIZE = new BackgroundSize(AUTO);
export const calculateBackgroungPaintingArea = (
curves: BoundCurves,
clip: BackgroundClip
): Path => {
// TODO support CONTENT_BOX
switch (clip) {
case BACKGROUND_CLIP.BORDER_BOX:
return [
curves.topLeftOuter,
curves.topRightOuter,
curves.bottomRightOuter,
curves.bottomLeftOuter
];
case BACKGROUND_CLIP.PADDING_BOX:
default:
return [
curves.topLeftInner,
curves.topRightInner,
curves.bottomRightInner,
curves.bottomLeftInner
];
}
};
export const calculateBackgroundPosition = ( export const calculateBackgroundPosition = (
position: [Length, Length], position: [Length, Length],
size: Size, size: Size,
@ -119,59 +155,66 @@ export const calculateBackgroundRepeatPath = (
background: BackgroundImage, background: BackgroundImage,
position: Vector, position: Vector,
size: Size, size: Size,
backgroundPositioningArea: Bounds,
bounds: Bounds bounds: Bounds
) => { ) => {
const repeat = background.repeat; const repeat = background.repeat;
switch (repeat) { switch (repeat) {
case BACKGROUND_REPEAT.REPEAT_X: case BACKGROUND_REPEAT.REPEAT_X:
return [ return [
new Vector(Math.round(bounds.left), Math.round(bounds.top + position.y)),
new Vector( new Vector(
Math.round(bounds.left + bounds.width), Math.round(bounds.left),
Math.round(bounds.top + position.y) Math.round(backgroundPositioningArea.top + position.y)
), ),
new Vector( new Vector(
Math.round(bounds.left + bounds.width), Math.round(bounds.left + bounds.width),
Math.round(size.height + bounds.top + position.y) Math.round(backgroundPositioningArea.top + position.y)
),
new Vector(
Math.round(bounds.left + bounds.width),
Math.round(size.height + backgroundPositioningArea.top + position.y)
), ),
new Vector( new Vector(
Math.round(bounds.left), Math.round(bounds.left),
Math.round(size.height + bounds.top + position.y) Math.round(size.height + backgroundPositioningArea.top + position.y)
) )
]; ];
case BACKGROUND_REPEAT.REPEAT_Y: case BACKGROUND_REPEAT.REPEAT_Y:
return [ return [
new Vector(Math.round(bounds.left + position.x), Math.round(bounds.top)),
new Vector( new Vector(
Math.round(bounds.left + position.x + size.width), Math.round(backgroundPositioningArea.left + position.x),
Math.round(bounds.top) Math.round(bounds.top)
), ),
new Vector( new Vector(
Math.round(bounds.left + position.x + size.width), Math.round(backgroundPositioningArea.left + position.x + size.width),
Math.round(bounds.top)
),
new Vector(
Math.round(backgroundPositioningArea.left + position.x + size.width),
Math.round(bounds.height + bounds.top) Math.round(bounds.height + bounds.top)
), ),
new Vector( new Vector(
Math.round(bounds.left + position.x), Math.round(backgroundPositioningArea.left + position.x),
Math.round(bounds.height + bounds.top) Math.round(bounds.height + bounds.top)
) )
]; ];
case BACKGROUND_REPEAT.NO_REPEAT: case BACKGROUND_REPEAT.NO_REPEAT:
return [ return [
new Vector( new Vector(
Math.round(bounds.left + position.x), Math.round(backgroundPositioningArea.left + position.x),
Math.round(bounds.top + position.y) Math.round(backgroundPositioningArea.top + position.y)
), ),
new Vector( new Vector(
Math.round(bounds.left + position.x + size.width), Math.round(backgroundPositioningArea.left + position.x + size.width),
Math.round(bounds.top + position.y) Math.round(backgroundPositioningArea.top + position.y)
), ),
new Vector( new Vector(
Math.round(bounds.left + position.x + size.width), Math.round(backgroundPositioningArea.left + position.x + size.width),
Math.round(bounds.top + position.y + size.height) Math.round(backgroundPositioningArea.top + position.y + size.height)
), ),
new Vector( new Vector(
Math.round(bounds.left + position.x), Math.round(backgroundPositioningArea.left + position.x),
Math.round(bounds.top + position.y + size.height) Math.round(backgroundPositioningArea.top + position.y + size.height)
) )
]; ];
default: default:
@ -192,11 +235,33 @@ export const parseBackground = (
imageLoader: ImageLoader imageLoader: ImageLoader
): Background => { ): Background => {
return { return {
backgroundColor: new Color(style.backgroundColor),
backgroundImage: parseBackgroundImages(style, imageLoader), backgroundImage: parseBackgroundImages(style, imageLoader),
backgroundColor: new Color(style.backgroundColor) backgroundClip: parseBackgroundClip(style.backgroundClip),
backgroundOrigin: parseBackgroundOrigin(style.backgroundOrigin)
}; };
}; };
const parseBackgroundClip = (backgroundClip: string): BackgroundClip => {
switch (backgroundClip) {
case 'padding-box':
return BACKGROUND_CLIP.PADDING_BOX;
case 'content-box':
return BACKGROUND_CLIP.CONTENT_BOX;
}
return BACKGROUND_CLIP.BORDER_BOX;
};
const parseBackgroundOrigin = (backgroundOrigin: string): BackgroundOrigin => {
switch (backgroundOrigin) {
case 'padding-box':
return BACKGROUND_ORIGIN.PADDING_BOX;
case 'content-box':
return BACKGROUND_ORIGIN.CONTENT_BOX;
}
return BACKGROUND_ORIGIN.BORDER_BOX;
};
const parseBackgroundRepeat = (backgroundRepeat: string): BackgroundRepeat => { const parseBackgroundRepeat = (backgroundRepeat: string): BackgroundRepeat => {
switch (backgroundRepeat.trim()) { switch (backgroundRepeat.trim()) {
case 'no-repeat': case 'no-repeat':