| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- // Shared methods of svg and svg-ssr
- import { MatrixArray } from '../core/matrix';
- import Transformable, { TransformProp } from '../core/Transformable';
- import { RADIAN_TO_DEGREE, retrieve2, logError, isFunction } from '../core/util';
- import Displayable from '../graphic/Displayable';
- import { GradientObject } from '../graphic/Gradient';
- import { LinearGradientObject } from '../graphic/LinearGradient';
- import Path from '../graphic/Path';
- import { ImagePatternObject, PatternObject, SVGPatternObject } from '../graphic/Pattern';
- import { RadialGradientObject } from '../graphic/RadialGradient';
- import { parse } from '../tool/color';
- import env from '../core/env';
- const mathRound = Math.round;
- export function normalizeColor(color: string): { color: string; opacity: number; } {
- let opacity;
- if (!color || color === 'transparent') {
- color = 'none';
- }
- else if (typeof color === 'string' && color.indexOf('rgba') > -1) {
- const arr = parse(color);
- if (arr) {
- // TODO use hex?
- color = 'rgb(' + arr[0] + ',' + arr[1] + ',' + arr[2] + ')';
- opacity = arr[3];
- }
- }
- return {
- color,
- opacity: opacity == null ? 1 : opacity
- };
- }
- const EPSILON = 1e-4;
- export function isAroundZero(transform: number) {
- return transform < EPSILON && transform > -EPSILON;
- }
- export function round3(transform: number) {
- return mathRound(transform * 1e3) / 1e3;
- }
- export function round4(transform: number) {
- return mathRound(transform * 1e4) / 1e4;
- }
- export function round1(transform: number) {
- return mathRound(transform * 10) / 10;
- }
- export function getMatrixStr(m: MatrixArray) {
- return 'matrix('
- // Avoid large string of matrix
- // PENDING If have precision issue when scaled
- + round3(m[0]) + ','
- + round3(m[1]) + ','
- + round3(m[2]) + ','
- + round3(m[3]) + ','
- + round4(m[4]) + ','
- + round4(m[5])
- + ')';
- }
- export const TEXT_ALIGN_TO_ANCHOR = {
- left: 'start',
- right: 'end',
- center: 'middle',
- middle: 'middle'
- };
- export function adjustTextY(y: number, lineHeight: number, textBaseline: CanvasTextBaseline): number {
- // TODO Other baselines.
- if (textBaseline === 'top') {
- y += lineHeight / 2;
- }
- else if (textBaseline === 'bottom') {
- y -= lineHeight / 2;
- }
- return y;
- }
- export function hasShadow(style: Displayable['style']) {
- // TODO: textBoxShadowBlur is not supported yet
- return style
- && (style.shadowBlur || style.shadowOffsetX || style.shadowOffsetY);
- }
- export function getShadowKey(displayable: Displayable) {
- const style = displayable.style;
- const globalScale = displayable.getGlobalScale();
- return [
- style.shadowColor,
- (style.shadowBlur || 0).toFixed(2), // Reduce the precision
- (style.shadowOffsetX || 0).toFixed(2),
- (style.shadowOffsetY || 0).toFixed(2),
- globalScale[0],
- globalScale[1]
- ].join(',');
- }
- export function getClipPathsKey(clipPaths: Path[]) {
- let key: number[] = [];
- if (clipPaths) {
- for (let i = 0; i < clipPaths.length; i++) {
- const clipPath = clipPaths[i];
- key.push(clipPath.id);
- }
- }
- return key.join(',');
- }
- export function isImagePattern(val: any): val is ImagePatternObject {
- return val && (!!(val as ImagePatternObject).image);
- }
- export function isSVGPattern(val: any): val is SVGPatternObject {
- return val && (!!(val as SVGPatternObject).svgElement);
- }
- export function isPattern(val: any): val is PatternObject {
- return isImagePattern(val) || isSVGPattern(val);
- }
- export function isLinearGradient(val: GradientObject): val is LinearGradientObject {
- return val.type === 'linear';
- }
- export function isRadialGradient(val: GradientObject): val is RadialGradientObject {
- return val.type === 'radial';
- }
- export function isGradient(val: any): val is GradientObject {
- return val && (
- (val as GradientObject).type === 'linear'
- || (val as GradientObject).type === 'radial'
- );
- }
- export function getIdURL(id: string) {
- return `url(#${id})`;
- }
- export function getPathPrecision(el: Path) {
- const scale = el.getGlobalScale();
- const size = Math.max(scale[0], scale[1]);
- return Math.max(Math.ceil(Math.log(size) / Math.log(10)), 1);
- }
- export function getSRTTransformString(
- transform: Partial<Pick<Transformable, TransformProp>>
- ) {
- const x = transform.x || 0;
- const y = transform.y || 0;
- const rotation = (transform.rotation || 0) * RADIAN_TO_DEGREE;
- const scaleX = retrieve2(transform.scaleX, 1);
- const scaleY = retrieve2(transform.scaleY, 1);
- const skewX = transform.skewX || 0;
- const skewY = transform.skewY || 0;
- const res = [];
- if (x || y) {
- // TODO not using px unit?
- res.push(`translate(${x}px,${y}px)`);
- }
- if (rotation) {
- res.push(`rotate(${rotation})`);
- }
- if (scaleX !== 1 || scaleY !== 1) {
- res.push(`scale(${scaleX},${scaleY})`);
- }
- if (skewX || skewY) {
- res.push(`skew(${mathRound(skewX * RADIAN_TO_DEGREE)}deg, ${mathRound(skewY * RADIAN_TO_DEGREE)}deg)`);
- }
- return res.join(' ');
- }
- export const encodeBase64 = (function () {
- if (env.hasGlobalWindow && isFunction(window.btoa)) {
- return function (str: string) {
- return window.btoa(unescape(str));
- };
- }
- if (typeof Buffer !== 'undefined') {
- return function (str: string) {
- return Buffer.from(str).toString('base64');
- };
- }
- return function (str: string): string {
- if (process.env.NODE_ENV !== 'production') {
- logError('Base64 isn\'t natively supported in the current environment.');
- }
- return null;
- };
- })();
|