UNPKG

fabric-pure-browser

Version:

Fabric.js package with no node-specific dependencies (node-canvas, jsdom). The project is published once a day (in case if a new version appears) from 'master' branch of https://github.com/fabricjs/fabric.js repository. You can keep original imports in

261 lines (244 loc) 9.5 kB
/* _TO_SVG_START_ */ (function() { function getSvgColorString(prop, value) { if (!value) { return prop + ': none; '; } else if (value.toLive) { return prop + ': url(#SVGID_' + value.id + '); '; } else { var color = new fabric.Color(value), str = prop + ': ' + color.toRgb() + '; ', opacity = color.getAlpha(); if (opacity !== 1) { //change the color in rgb + opacity str += prop + '-opacity: ' + opacity.toString() + '; '; } return str; } } var toFixed = fabric.util.toFixed; fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { /** * Returns styles-string for svg-export * @param {Boolean} skipShadow a boolean to skip shadow filter output * @return {String} */ getSvgStyles: function(skipShadow) { var fillRule = this.fillRule ? this.fillRule : 'nonzero', strokeWidth = this.strokeWidth ? this.strokeWidth : '0', strokeDashArray = this.strokeDashArray ? this.strokeDashArray.join(' ') : 'none', strokeDashOffset = this.strokeDashOffset ? this.strokeDashOffset : '0', strokeLineCap = this.strokeLineCap ? this.strokeLineCap : 'butt', strokeLineJoin = this.strokeLineJoin ? this.strokeLineJoin : 'miter', strokeMiterLimit = this.strokeMiterLimit ? this.strokeMiterLimit : '4', opacity = typeof this.opacity !== 'undefined' ? this.opacity : '1', visibility = this.visible ? '' : ' visibility: hidden;', filter = skipShadow ? '' : this.getSvgFilter(), fill = getSvgColorString('fill', this.fill), stroke = getSvgColorString('stroke', this.stroke); return [ stroke, 'stroke-width: ', strokeWidth, '; ', 'stroke-dasharray: ', strokeDashArray, '; ', 'stroke-linecap: ', strokeLineCap, '; ', 'stroke-dashoffset: ', strokeDashOffset, '; ', 'stroke-linejoin: ', strokeLineJoin, '; ', 'stroke-miterlimit: ', strokeMiterLimit, '; ', fill, 'fill-rule: ', fillRule, '; ', 'opacity: ', opacity, ';', filter, visibility ].join(''); }, /** * Returns styles-string for svg-export * @param {Object} style the object from which to retrieve style properties * @param {Boolean} useWhiteSpace a boolean to include an additional attribute in the style. * @return {String} */ getSvgSpanStyles: function(style, useWhiteSpace) { var term = '; '; var fontFamily = style.fontFamily ? 'font-family: ' + (((style.fontFamily.indexOf('\'') === -1 && style.fontFamily.indexOf('"') === -1) ? '\'' + style.fontFamily + '\'' : style.fontFamily)) + term : ''; var strokeWidth = style.strokeWidth ? 'stroke-width: ' + style.strokeWidth + term : '', fontFamily = fontFamily, fontSize = style.fontSize ? 'font-size: ' + style.fontSize + 'px' + term : '', fontStyle = style.fontStyle ? 'font-style: ' + style.fontStyle + term : '', fontWeight = style.fontWeight ? 'font-weight: ' + style.fontWeight + term : '', fill = style.fill ? getSvgColorString('fill', style.fill) : '', stroke = style.stroke ? getSvgColorString('stroke', style.stroke) : '', textDecoration = this.getSvgTextDecoration(style), deltaY = style.deltaY ? 'baseline-shift: ' + (-style.deltaY) + '; ' : ''; if (textDecoration) { textDecoration = 'text-decoration: ' + textDecoration + term; } return [ stroke, strokeWidth, fontFamily, fontSize, fontStyle, fontWeight, textDecoration, fill, deltaY, useWhiteSpace ? 'white-space: pre; ' : '' ].join(''); }, /** * Returns text-decoration property for svg-export * @param {Object} style the object from which to retrieve style properties * @return {String} */ getSvgTextDecoration: function(style) { if ('overline' in style || 'underline' in style || 'linethrough' in style) { return (style.overline ? 'overline ' : '') + (style.underline ? 'underline ' : '') + (style.linethrough ? 'line-through ' : ''); } return ''; }, /** * Returns filter for svg shadow * @return {String} */ getSvgFilter: function() { return this.shadow ? 'filter: url(#SVGID_' + this.shadow.id + ');' : ''; }, /** * Returns id attribute for svg output * @return {String} */ getSvgCommons: function() { return [ this.id ? 'id="' + this.id + '" ' : '', this.clipPath ? 'clip-path="url(#' + this.clipPath.clipPathId + ')" ' : '', ].join(''); }, /** * Returns transform-string for svg-export * @param {Boolean} use the full transform or the single object one. * @return {String} */ getSvgTransform: function(full, additionalTransform) { var transform = full ? this.calcTransformMatrix() : this.calcOwnMatrix(), svgTransform = 'transform="' + fabric.util.matrixToSVG(transform); return svgTransform + (additionalTransform || '') + '" '; }, _setSVGBg: function(textBgRects) { if (this.backgroundColor) { var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS; textBgRects.push( '\t\t<rect ', this._getFillAttributes(this.backgroundColor), ' x="', toFixed(-this.width / 2, NUM_FRACTION_DIGITS), '" y="', toFixed(-this.height / 2, NUM_FRACTION_DIGITS), '" width="', toFixed(this.width, NUM_FRACTION_DIGITS), '" height="', toFixed(this.height, NUM_FRACTION_DIGITS), '"></rect>\n'); } }, /** * Returns svg representation of an instance * @param {Function} [reviver] Method for further parsing of svg representation. * @return {String} svg representation of an instance */ toSVG: function(reviver) { return this._createBaseSVGMarkup(this._toSVG(reviver), { reviver: reviver }); }, /** * Returns svg clipPath representation of an instance * @param {Function} [reviver] Method for further parsing of svg representation. * @return {String} svg representation of an instance */ toClipPathSVG: function(reviver) { return '\t' + this._createBaseClipPathSVGMarkup(this._toSVG(reviver), { reviver: reviver }); }, /** * @private */ _createBaseClipPathSVGMarkup: function(objectMarkup, options) { options = options || {}; var reviver = options.reviver, additionalTransform = options.additionalTransform || '', commonPieces = [ this.getSvgTransform(true, additionalTransform), this.getSvgCommons(), ].join(''), // insert commons in the markup, style and svgCommons index = objectMarkup.indexOf('COMMON_PARTS'); objectMarkup[index] = commonPieces; return reviver ? reviver(objectMarkup.join('')) : objectMarkup.join(''); }, /** * @private */ _createBaseSVGMarkup: function(objectMarkup, options) { options = options || {}; var noStyle = options.noStyle, reviver = options.reviver, styleInfo = noStyle ? '' : 'style="' + this.getSvgStyles() + '" ', shadowInfo = options.withShadow ? 'style="' + this.getSvgFilter() + '" ' : '', clipPath = this.clipPath, vectorEffect = this.strokeUniform ? 'vector-effect="non-scaling-stroke" ' : '', absoluteClipPath = clipPath && clipPath.absolutePositioned, stroke = this.stroke, fill = this.fill, shadow = this.shadow, commonPieces, markup = [], clipPathMarkup, // insert commons in the markup, style and svgCommons index = objectMarkup.indexOf('COMMON_PARTS'), additionalTransform = options.additionalTransform; if (clipPath) { clipPath.clipPathId = 'CLIPPATH_' + fabric.Object.__uid++; clipPathMarkup = '<clipPath id="' + clipPath.clipPathId + '" >\n' + clipPath.toClipPathSVG(reviver) + '</clipPath>\n'; } if (absoluteClipPath) { markup.push( '<g ', shadowInfo, this.getSvgCommons(), ' >\n' ); } markup.push( '<g ', this.getSvgTransform(false), !absoluteClipPath ? shadowInfo + this.getSvgCommons() : '', ' >\n' ); commonPieces = [ styleInfo, vectorEffect, noStyle ? '' : this.addPaintOrder(), ' ', additionalTransform ? 'transform="' + additionalTransform + '" ' : '', ].join(''); objectMarkup[index] = commonPieces; if (fill && fill.toLive) { markup.push(fill.toSVG(this)); } if (stroke && stroke.toLive) { markup.push(stroke.toSVG(this)); } if (shadow) { markup.push(shadow.toSVG(this)); } if (clipPath) { markup.push(clipPathMarkup); } markup.push(objectMarkup.join('')); markup.push('</g>\n'); absoluteClipPath && markup.push('</g>\n'); return reviver ? reviver(markup.join('')) : markup.join(''); }, addPaintOrder: function() { return this.paintFirst !== 'fill' ? ' paint-order="' + this.paintFirst + '" ' : ''; } }); })(); /* _TO_SVG_END_ */