123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- 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;
- }
|