UNPKG

zrender

Version:

A lightweight graphic library providing 2d draw for Apache ECharts

127 lines (107 loc) 3.87 kB
import { LinearGradientObject } from '../graphic/LinearGradient'; import { RadialGradientObject } from '../graphic/RadialGradient'; import { GradientObject } from '../graphic/Gradient'; import { RectLike } from '../core/BoundingRect'; import Path from '../graphic/Path'; function isSafeNum(num: number) { // NaN、Infinity、undefined、'xx' return isFinite(num); } export function createLinearGradient( this: void, ctx: CanvasRenderingContext2D, obj: LinearGradientObject, rect: RectLike ) { let x = obj.x == null ? 0 : obj.x; let x2 = obj.x2 == null ? 1 : obj.x2; let y = obj.y == null ? 0 : obj.y; let y2 = obj.y2 == null ? 0 : obj.y2; if (!obj.global) { x = x * rect.width + rect.x; x2 = x2 * rect.width + rect.x; y = y * rect.height + rect.y; y2 = y2 * rect.height + rect.y; } // Fix NaN when rect is Infinity x = isSafeNum(x) ? x : 0; x2 = isSafeNum(x2) ? x2 : 1; y = isSafeNum(y) ? y : 0; y2 = isSafeNum(y2) ? y2 : 0; const canvasGradient = ctx.createLinearGradient(x, y, x2, y2); return canvasGradient; } export function createRadialGradient( this: void, ctx: CanvasRenderingContext2D, obj: RadialGradientObject, rect: RectLike ) { const width = rect.width; const height = rect.height; const min = Math.min(width, height); let x = obj.x == null ? 0.5 : obj.x; let y = obj.y == null ? 0.5 : obj.y; let r = obj.r == null ? 0.5 : obj.r; if (!obj.global) { x = x * width + rect.x; y = y * height + rect.y; r = r * min; } x = isSafeNum(x) ? x : 0.5; y = isSafeNum(y) ? y : 0.5; r = r >= 0 && isSafeNum(r) ? r : 0.5; const canvasGradient = ctx.createRadialGradient(x, y, 0, x, y, r); return canvasGradient; } export function getCanvasGradient(this: void, ctx: CanvasRenderingContext2D, obj: GradientObject, rect: RectLike) { // TODO Cache? const canvasGradient = obj.type === 'radial' ? createRadialGradient(ctx, obj as RadialGradientObject, rect) : createLinearGradient(ctx, obj as LinearGradientObject, rect); const colorStops = obj.colorStops; for (let i = 0; i < colorStops.length; i++) { canvasGradient.addColorStop( colorStops[i].offset, colorStops[i].color ); } return canvasGradient; } export function isClipPathChanged(clipPaths: Path[], prevClipPaths: Path[]): boolean { // displayable.__clipPaths can only be `null`/`undefined` or an non-empty array. if (clipPaths === prevClipPaths || (!clipPaths && !prevClipPaths)) { return false; } if (!clipPaths || !prevClipPaths || (clipPaths.length !== prevClipPaths.length)) { return true; } for (let i = 0; i < clipPaths.length; i++) { if (clipPaths[i] !== prevClipPaths[i]) { return true; } } return false; } function parseInt10(val: string) { return parseInt(val, 10); } export function getSize( root: HTMLElement, whIdx: number, opts: { width?: number | string, height?: number | string} ) { const wh = ['width', 'height'][whIdx] as 'width' | 'height'; const cwh = ['clientWidth', 'clientHeight'][whIdx] as 'clientWidth' | 'clientHeight'; const plt = ['paddingLeft', 'paddingTop'][whIdx] as 'paddingLeft' | 'paddingTop'; const prb = ['paddingRight', 'paddingBottom'][whIdx] as 'paddingRight' | 'paddingBottom'; if (opts[wh] != null && opts[wh] !== 'auto') { return parseFloat(opts[wh] as string); } // IE8 does not support getComputedStyle, but it use VML. const stl = document.defaultView.getComputedStyle(root); return ( (root[cwh] || parseInt10(stl[wh]) || parseInt10(root.style[wh])) - (parseInt10(stl[plt]) || 0) - (parseInt10(stl[prb]) || 0) ) | 0; }