UNPKG

fabric

Version:

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

1 lines 13 kB
{"version":3,"file":"Shadow.mjs","sources":["../../src/Shadow.ts"],"sourcesContent":["import { classRegistry } from './ClassRegistry';\nimport { Color } from './color/Color';\nimport { config } from './config';\nimport { reNum } from './parser/constants';\nimport { Point } from './Point';\nimport type { FabricObject } from './shapes/Object/FabricObject';\nimport type { TClassProperties } from './typedefs';\nimport { uid } from './util/internals/uid';\nimport { pickBy } from './util/misc/pick';\nimport { degreesToRadians } from './util/misc/radiansDegreesConversion';\nimport { toFixed } from './util/misc/toFixed';\nimport { rotateVector } from './util/misc/vectors';\n\n/**\n * Regex matching shadow offsetX, offsetY and blur (ex: \"2px 2px 10px rgba(0,0,0,0.2)\", \"rgb(0,255,0) 2px 2px\")\n * - (?:\\s|^): This part captures either a whitespace character (\\s) or the beginning of a line (^). It's non-capturing (due to (?:...)), meaning it doesn't create a capturing group.\n * - (-?\\d+(?:\\.\\d*)?(?:px)?(?:\\s?|$))?: This captures the first component of the shadow, which is the horizontal offset. Breaking it down:\n * - (-?\\d+): Captures an optional minus sign followed by one or more digits (integer part of the number).\n * - (?:\\.\\d*)?: Optionally captures a decimal point followed by zero or more digits (decimal part of the number).\n * - (?:px)?: Optionally captures the \"px\" unit.\n * - (?:\\s?|$): Captures either an optional whitespace or the end of the line. This whole part is wrapped in a non-capturing group and marked as optional with ?.\n * - (-?\\d+(?:\\.\\d*)?(?:px)?(?:\\s?|$))?: Similar to the previous step, this captures the vertical offset.\n\n(\\d+(?:\\.\\d*)?(?:px)?)?: This captures the blur radius. It's similar to the horizontal offset but without the optional minus sign.\n\n(?:\\s+(-?\\d+(?:\\.\\d*)?(?:px)?(?:\\s?|$))?){0,1}: This captures an optional part for the color. It allows for whitespace followed by a component with an optional minus sign, digits, decimal point, and \"px\" unit.\n\n(?:$|\\s): This captures either the end of the line or a whitespace character. It ensures that the match ends either at the end of the string or with a whitespace character.\n */\n// eslint-disable-next-line max-len\n\nconst shadowOffsetRegex = '(-?\\\\d+(?:\\\\.\\\\d*)?(?:px)?(?:\\\\s?|$))?';\n\nconst reOffsetsAndBlur = new RegExp(\n '(?:\\\\s|^)' +\n shadowOffsetRegex +\n shadowOffsetRegex +\n '(' +\n reNum +\n '?(?:px)?)?(?:\\\\s?|$)(?:$|\\\\s)',\n);\n\nexport const shadowDefaultValues: Partial<TClassProperties<Shadow>> = {\n color: 'rgb(0,0,0)',\n blur: 0,\n offsetX: 0,\n offsetY: 0,\n affectStroke: false,\n includeDefaultValues: true,\n nonScaling: false,\n};\n\nexport type SerializedShadowOptions = {\n color: string;\n blur: number;\n offsetX: number;\n offsetY: number;\n affectStroke: boolean;\n nonScaling: boolean;\n type: string;\n};\n\nexport class Shadow {\n /**\n * Shadow color\n * @type String\n * @default\n */\n declare color: string;\n\n /**\n * Shadow blur\n * @type Number\n */\n declare blur: number;\n\n /**\n * Shadow horizontal offset\n * @type Number\n * @default\n */\n declare offsetX: number;\n\n /**\n * Shadow vertical offset\n * @type Number\n * @default\n */\n declare offsetY: number;\n\n /**\n * Whether the shadow should affect stroke operations\n * @type Boolean\n * @default\n */\n declare affectStroke: boolean;\n\n /**\n * Indicates whether toObject should include default values\n * @type Boolean\n * @default\n */\n declare includeDefaultValues: boolean;\n\n /**\n * When `false`, the shadow will scale with the object.\n * When `true`, the shadow's offsetX, offsetY, and blur will not be affected by the object's scale.\n * default to false\n * @type Boolean\n * @default\n */\n declare nonScaling: boolean;\n\n declare id: number;\n\n static ownDefaults = shadowDefaultValues;\n\n static type = 'shadow';\n\n /**\n * @see {@link http://fabricjs.com/shadows|Shadow demo}\n * @param {Object|String} [options] Options object with any of color, blur, offsetX, offsetY properties or string (e.g. \"rgba(0,0,0,0.2) 2px 2px 10px\")\n */\n constructor(options: Partial<TClassProperties<Shadow>>);\n constructor(svgAttribute: string);\n constructor(arg0: string | Partial<TClassProperties<Shadow>>) {\n const options: Partial<TClassProperties<Shadow>> =\n typeof arg0 === 'string' ? Shadow.parseShadow(arg0) : arg0;\n Object.assign(this, Shadow.ownDefaults, options);\n this.id = uid();\n }\n\n /**\n * @param {String} value Shadow value to parse\n * @return {Object} Shadow object with color, offsetX, offsetY and blur\n */\n static parseShadow(value: string) {\n const shadowStr = value.trim(),\n [, offsetX = 0, offsetY = 0, blur = 0] = (\n reOffsetsAndBlur.exec(shadowStr) || []\n ).map((value) => parseFloat(value) || 0),\n color = (shadowStr.replace(reOffsetsAndBlur, '') || 'rgb(0,0,0)').trim();\n\n return {\n color,\n offsetX,\n offsetY,\n blur,\n };\n }\n\n /**\n * Returns a string representation of an instance\n * @see http://www.w3.org/TR/css-text-decor-3/#text-shadow\n * @return {String} Returns CSS3 text-shadow declaration\n */\n toString() {\n return [this.offsetX, this.offsetY, this.blur, this.color].join('px ');\n }\n\n /**\n * Returns SVG representation of a shadow\n * @param {FabricObject} object\n * @return {String} SVG representation of a shadow\n */\n toSVG(object: FabricObject) {\n const offset = rotateVector(\n new Point(this.offsetX, this.offsetY),\n degreesToRadians(-object.angle),\n ),\n BLUR_BOX = 20,\n color = new Color(this.color);\n let fBoxX = 40,\n fBoxY = 40;\n\n if (object.width && object.height) {\n //http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion\n // we add some extra space to filter box to contain the blur ( 20 )\n fBoxX =\n toFixed(\n (Math.abs(offset.x) + this.blur) / object.width,\n config.NUM_FRACTION_DIGITS,\n ) *\n 100 +\n BLUR_BOX;\n fBoxY =\n toFixed(\n (Math.abs(offset.y) + this.blur) / object.height,\n config.NUM_FRACTION_DIGITS,\n ) *\n 100 +\n BLUR_BOX;\n }\n if (object.flipX) {\n offset.x *= -1;\n }\n if (object.flipY) {\n offset.y *= -1;\n }\n\n return `<filter id=\"SVGID_${this.id}\" y=\"-${fBoxY}%\" height=\"${\n 100 + 2 * fBoxY\n }%\" x=\"-${fBoxX}%\" width=\"${\n 100 + 2 * fBoxX\n }%\" >\\n\\t<feGaussianBlur in=\"SourceAlpha\" stdDeviation=\"${toFixed(\n this.blur ? this.blur / 2 : 0,\n config.NUM_FRACTION_DIGITS,\n )}\"></feGaussianBlur>\\n\\t<feOffset dx=\"${toFixed(\n offset.x,\n config.NUM_FRACTION_DIGITS,\n )}\" dy=\"${toFixed(\n offset.y,\n config.NUM_FRACTION_DIGITS,\n )}\" result=\"oBlur\" ></feOffset>\\n\\t<feFlood flood-color=\"${color.toRgb()}\" flood-opacity=\"${color.getAlpha()}\"/>\\n\\t<feComposite in2=\"oBlur\" operator=\"in\" />\\n\\t<feMerge>\\n\\t\\t<feMergeNode></feMergeNode>\\n\\t\\t<feMergeNode in=\"SourceGraphic\"></feMergeNode>\\n\\t</feMerge>\\n</filter>\\n`;\n }\n\n /**\n * Returns object representation of a shadow\n * @return {Object} Object representation of a shadow instance\n */\n toObject() {\n const data: SerializedShadowOptions = {\n color: this.color,\n blur: this.blur,\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n affectStroke: this.affectStroke,\n nonScaling: this.nonScaling,\n type: (this.constructor as typeof Shadow).type,\n };\n const defaults = Shadow.ownDefaults as SerializedShadowOptions;\n return !this.includeDefaultValues\n ? pickBy(data, (value, key) => value !== defaults[key])\n : data;\n }\n\n static async fromObject(options: Partial<TClassProperties<Shadow>>) {\n return new this(options);\n }\n}\n\nclassRegistry.setClass(Shadow, 'shadow');\n"],"names":["shadowOffsetRegex","reOffsetsAndBlur","RegExp","reNum","shadowDefaultValues","color","blur","offsetX","offsetY","affectStroke","includeDefaultValues","nonScaling","Shadow","constructor","arg0","options","parseShadow","Object","assign","ownDefaults","id","uid","value","shadowStr","trim","exec","map","parseFloat","replace","toString","join","toSVG","object","offset","rotateVector","Point","degreesToRadians","angle","BLUR_BOX","Color","fBoxX","fBoxY","width","height","toFixed","Math","abs","x","config","NUM_FRACTION_DIGITS","y","flipX","flipY","concat","toRgb","getAlpha","toObject","data","type","defaults","pickBy","key","fromObject","_defineProperty","classRegistry","setClass"],"mappings":"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"}