UNPKG

fabric

Version:

Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.

77 lines (71 loc) 2.29 kB
import { isPercent } from '../../parser/percent'; import type { TSize } from '../../typedefs'; import type { GradientCoords, GradientType, GradientUnits } from '../typedefs'; import { parseGradientUnits, parseType } from './misc'; function convertPercentUnitsToValues< T extends GradientType, K extends keyof GradientCoords<T>, >( valuesToConvert: Record<K, string | number>, { width, height, gradientUnits }: TSize & { gradientUnits: GradientUnits }, ) { let finalValue; return (Object.keys(valuesToConvert) as K[]).reduce( (acc, prop) => { const propValue = valuesToConvert[prop]; if (propValue === 'Infinity') { finalValue = 1; } else if (propValue === '-Infinity') { finalValue = 0; } else { finalValue = typeof propValue === 'string' ? parseFloat(propValue) : propValue; if (typeof propValue === 'string' && isPercent(propValue)) { finalValue *= 0.01; if (gradientUnits === 'pixels') { // then we need to fix those percentages here in svg parsing if (prop === 'x1' || prop === 'x2' || prop === 'r2') { finalValue *= width; } if (prop === 'y1' || prop === 'y2') { finalValue *= height; } } } } acc[prop] = finalValue; return acc; }, {} as Record<K, number>, ); } function getValue(el: SVGGradientElement, key: string) { return el.getAttribute(key); } export function parseLinearCoords(el: SVGGradientElement) { return { x1: getValue(el, 'x1') || 0, y1: getValue(el, 'y1') || 0, x2: getValue(el, 'x2') || '100%', y2: getValue(el, 'y2') || 0, }; } export function parseRadialCoords(el: SVGGradientElement) { return { x1: getValue(el, 'fx') || getValue(el, 'cx') || '50%', y1: getValue(el, 'fy') || getValue(el, 'cy') || '50%', r1: 0, x2: getValue(el, 'cx') || '50%', y2: getValue(el, 'cy') || '50%', r2: getValue(el, 'r') || '50%', }; } export function parseCoords(el: SVGGradientElement, size: TSize) { return convertPercentUnitsToValues( parseType(el) === 'linear' ? parseLinearCoords(el) : parseRadialCoords(el), { ...size, gradientUnits: parseGradientUnits(el), }, ); }