Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(pattern): remove non-required properties from PatternObject and fix some type issues. #759

Merged
merged 4 commits into from
May 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions src/canvas/Layer.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import * as util from '../core/util';
import {devicePixelRatio} from '../config';
import { PatternObject } from '../graphic/Pattern';
import { ImagePatternObject } from '../graphic/Pattern';
import CanvasPainter from './Painter';
import { GradientObject, InnerGradientObject } from '../graphic/Gradient';
import { ZRCanvasRenderingContext } from '../core/types';
import Eventful from '../core/Eventful';
import Element, { ElementEventCallback } from '../Element';
import { ElementEventCallback } from '../Element';
import { getCanvasGradient } from './helper';
import { createCanvasPattern } from './graphic';
import Displayable from '../graphic/Displayable';
Expand Down Expand Up @@ -40,7 +40,7 @@ function createDom(id: string, painter: CanvasPainter, dpr: number) {

export interface LayerConfig {
// 每次清空画布的颜色
clearColor?: string | GradientObject | PatternObject
clearColor?: string | GradientObject | ImagePatternObject
// 是否开启动态模糊
motionBlur?: boolean
// 在开启动态模糊的时候使用,与上一帧混合的alpha值,值越大尾迹越明显
Expand All @@ -63,7 +63,7 @@ export default class Layer extends Eventful {
/**
* 每次清空画布的颜色
*/
clearColor: string | GradientObject | PatternObject
clearColor: string | GradientObject | ImagePatternObject
/**
* 是否开启动态模糊
*/
Expand Down Expand Up @@ -353,7 +353,7 @@ export default class Layer extends Eventful {
}
i++;
}
} while (hasIntersections)
} while (hasIntersections);

this._paintRects = mergedRepaintRects;

Expand Down Expand Up @@ -397,7 +397,7 @@ export default class Layer extends Eventful {
*/
clear(
clearAll?: boolean,
clearColor?: string | GradientObject | PatternObject,
clearColor?: string | GradientObject | ImagePatternObject,
repaintRects?: BoundingRect[]
) {
const dom = this.dom;
Expand Down Expand Up @@ -488,7 +488,7 @@ export default class Layer extends Eventful {
}

// Iterface of refresh
refresh: (clearColor?: string | GradientObject | PatternObject) => void
refresh: (clearColor?: string | GradientObject | ImagePatternObject) => void

// Interface of renderToCanvas in getRenderedCanvas
renderToCanvas: (ctx: CanvasRenderingContext2D) => void
Expand Down
9 changes: 4 additions & 5 deletions src/canvas/Painter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@ import env from '../core/env';
import Displayable from '../graphic/Displayable';
import { WXCanvasRenderingContext, ZRCanvasRenderingContext } from '../core/types';
import { GradientObject } from '../graphic/Gradient';
import { PatternObject } from '../graphic/Pattern';
import { ImagePatternObject } from '../graphic/Pattern';
import Storage from '../Storage';
import { brush, BrushScope, brushSingle } from './graphic';
import { PainterBase } from '../PainterBase';
import BoundingRect from '../core/BoundingRect';
import Element from '../Element';
import IncrementalDisplayable from '../graphic/IncrementalDisplayable';
import Path from '../graphic/Path';
import { REDARAW_BIT } from '../graphic/constants';
Expand Down Expand Up @@ -111,7 +110,7 @@ export default class CanvasPainter implements PainterBase {

private _redrawId: number

private _backgroundColor: string | GradientObject | PatternObject
private _backgroundColor: string | GradientObject | ImagePatternObject


constructor(root: HTMLElement, storage: Storage, opts: CanvasPainterOption, id: number) {
Expand Down Expand Up @@ -790,7 +789,7 @@ export default class CanvasPainter implements PainterBase {
layer.clear();
}

setBackgroundColor(backgroundColor: string | GradientObject | PatternObject) {
setBackgroundColor(backgroundColor: string | GradientObject | ImagePatternObject) {
this._backgroundColor = backgroundColor;

util.each(this._layers, layer => {
Expand Down Expand Up @@ -920,7 +919,7 @@ export default class CanvasPainter implements PainterBase {
* Get canvas which has all thing rendered
*/
getRenderedCanvas(opts?: {
backgroundColor?: string | GradientObject | PatternObject
backgroundColor?: string | GradientObject | ImagePatternObject
pixelRatio?: number
}) {
opts = opts || {};
Expand Down
15 changes: 7 additions & 8 deletions src/canvas/graphic.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Displayable, { DEFAULT_COMMON_STYLE } from '../graphic/Displayable';
import PathProxy from '../core/PathProxy';
import { GradientObject } from '../graphic/Gradient';
import { PatternObject } from '../graphic/Pattern';
import { ImagePatternObject, InnerImagePatternObject } from '../graphic/Pattern';
import { LinearGradientObject } from '../graphic/LinearGradient';
import { RadialGradientObject } from '../graphic/RadialGradient';
import { ZRCanvasRenderingContext } from '../core/types';
Expand All @@ -14,7 +14,6 @@ import { DEFAULT_FONT } from '../contain/text';
import { MatrixArray } from '../core/matrix';
import { map } from '../core/util';
import { normalizeLineDash } from '../graphic/helper/dashStyle';
import Element from '../Element';
import IncrementalDisplayable from '../graphic/IncrementalDisplayable';
import { REDARAW_BIT, SHAPE_CHANGED_BIT } from '../graphic/constants';

Expand Down Expand Up @@ -59,10 +58,10 @@ function doStrokePath(ctx: CanvasRenderingContext2D, style: PathStyleProps) {
export function createCanvasPattern(
this: void,
ctx: CanvasRenderingContext2D,
pattern: PatternObject,
pattern: ImagePatternObject,
el: {dirty: () => void}
): CanvasPattern {
const image = createOrUpdateImage(pattern.image, pattern.__image, el);
const image = createOrUpdateImage(pattern.image, (pattern as InnerImagePatternObject).__image, el);
if (isImageReady(image)) {
const canvasPattern = ctx.createPattern(image, pattern.repeat || 'repeat');
if (
Expand Down Expand Up @@ -104,8 +103,8 @@ function brushPath(ctx: CanvasRenderingContext2D, el: Path, style: PathStyleProp

const hasFillGradient = hasFill && !!(fill as GradientObject).colorStops;
const hasStrokeGradient = hasStroke && !!(stroke as GradientObject).colorStops;
const hasFillPattern = hasFill && !!(fill as PatternObject).image;
const hasStrokePattern = hasStroke && !!(stroke as PatternObject).image;
const hasFillPattern = hasFill && !!(fill as ImagePatternObject).image;
const hasStrokePattern = hasStroke && !!(stroke as ImagePatternObject).image;

let fillGradient;
let strokeGradient;
Expand Down Expand Up @@ -133,14 +132,14 @@ function brushPath(ctx: CanvasRenderingContext2D, el: Path, style: PathStyleProp
if (hasFillPattern) {
// Pattern might be null if image not ready (even created from dataURI)
fillPattern = (el.__dirty || !el.__canvasFillPattern)
? createCanvasPattern(ctx, fill as PatternObject, el)
? createCanvasPattern(ctx, fill as ImagePatternObject, el)
: el.__canvasFillPattern;
el.__canvasFillPattern = fillPattern;
}
if (hasStrokePattern) {
// Pattern might be null if image not ready (even created from dataURI)
strokePattern = (el.__dirty || !el.__canvasStrokePattern)
? createCanvasPattern(ctx, stroke as PatternObject, el)
? createCanvasPattern(ctx, stroke as ImagePatternObject, el)
: el.__canvasStrokePattern;
el.__canvasStrokePattern = fillPattern;
}
Expand Down
8 changes: 7 additions & 1 deletion src/export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,13 @@ export {default as Trochoid, TrochoidProps, TrochoidShape} from './graphic/shape

export {default as LinearGradient, LinearGradientObject} from './graphic/LinearGradient';
export {default as RadialGradient, RadialGradientObject} from './graphic/RadialGradient';
export {default as Pattern, PatternObject} from './graphic/Pattern';
export {
default as Pattern,
PatternObjectBase,
PatternObject,
ImagePatternObject,
SVGPatternObject
} from './graphic/Pattern';
export {default as BoundingRect, RectLike} from './core/BoundingRect';
export {default as OrientedBoundingRect} from './core/OrientedBoundingRect';

Expand Down
2 changes: 1 addition & 1 deletion src/graphic/Path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Displayable, { DisplayableProps,
import Element, { ElementAnimateConfig } from '../Element';
import PathProxy from '../core/PathProxy';
import * as pathContain from '../contain/path';
import Pattern, { PatternObject } from './Pattern';
import { PatternObject } from './Pattern';
import { Dictionary, PropType, MapToType } from '../core/types';
import BoundingRect from '../core/BoundingRect';
import { LinearGradientObject } from './LinearGradient';
Expand Down
42 changes: 25 additions & 17 deletions src/graphic/Pattern.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,41 @@
import { ImageLike } from '../core/types';

type CanvasPatternRepeat = 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat'
type ImagePatternRepeat = 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat'

export interface PatternObject {
export interface PatternObjectBase {
id?: number

type: 'pattern'

image: ImageLike | string
/**
* svg element can only be used in svg renderer currently.
* svgWidth, svgHeight defines width and height used for pattern.
*/
svgElement: SVGElement
svgWidth: number
svgHeight: number

repeat: CanvasPatternRepeat
// type is now unused, so make it optional
type?: 'pattern'

x?: number
y?: number
rotation?: number
scaleX?: number
scaleY?: number
}

export interface ImagePatternObject extends PatternObjectBase {
image: ImageLike | string
repeat?: ImagePatternRepeat
}

export interface InnerImagePatternObject extends ImagePatternObject {
// Cached image. Which is created in the canvas painter.
__image?: ImageLike
}

export interface SVGPatternObject extends PatternObjectBase {
/**
* svg element can only be used in svg renderer currently.
* svgWidth, svgHeight defines width and height used for pattern.
*/
svgElement?: SVGElement
svgWidth?: number
svgHeight?: number
}

export type PatternObject = ImagePatternObject | SVGPatternObject

class Pattern {

type: 'pattern'
Expand All @@ -38,15 +46,15 @@ class Pattern {
*/
svgElement: SVGElement

repeat: CanvasPatternRepeat
repeat: ImagePatternRepeat

x: number
y: number
rotation: number
scaleX: number
scaleY: number

constructor(image: ImageLike | string, repeat: CanvasPatternRepeat) {
constructor(image: ImageLike | string, repeat: ImagePatternRepeat) {
// Should do nothing more in this constructor. Because gradient can be
// declard by `color: {image: ...}`, where this constructor will not be called.
this.image = image;
Expand Down
32 changes: 14 additions & 18 deletions src/svg/helper/PatternManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
import Definable from './Definable';
import * as zrUtil from '../../core/util';
import Displayable from '../../graphic/Displayable';
import {PatternObject} from '../../graphic/Pattern';
import {PatternObject, ImagePatternObject, SVGPatternObject} from '../../graphic/Pattern';
import {createOrUpdateImage} from '../../graphic/helper/image';
import WeakMap from '../../core/WeakMap';

function isPattern(value: PatternObject | string): value is PatternObject {
return value && (!!(value as PatternObject).image || !!(value as PatternObject).svgElement);
return value && (!!(value as ImagePatternObject).image || !!(value as SVGPatternObject).svgElement);
}

const patternDomMap = new WeakMap<PatternObject, SVGElement>();
Expand Down Expand Up @@ -123,22 +123,22 @@ export default class PatternManager extends Definable {
* @param patternDom DOM to update
*/
updateDom(pattern: PatternObject, patternDom: SVGElement) {
const svgElement = pattern.svgElement;
const svgElement = (pattern as SVGPatternObject).svgElement;

if (svgElement instanceof SVGElement) {
if (svgElement.parentNode !== patternDom) {
patternDom.innerHTML = '';
patternDom.appendChild(svgElement);

patternDom.setAttribute('width', pattern.svgWidth + '');
patternDom.setAttribute('height', pattern.svgHeight + '');
patternDom.setAttribute('width', (pattern as SVGPatternObject).svgWidth + '');
patternDom.setAttribute('height', (pattern as SVGPatternObject).svgHeight + '');
}
}
else {
let img: SVGElement;
const prevImage = patternDom.getElementsByTagName('image');
if (prevImage.length) {
if (pattern.image) {
if ((pattern as ImagePatternObject).image) {
// Update
img = prevImage[0];
}
Expand All @@ -148,21 +148,22 @@ export default class PatternManager extends Definable {
return;
}
}
else if (pattern.image) {
else if ((pattern as ImagePatternObject).image) {
// Create
img = this.createElement('image');
}

if (img) {
let imageSrc;
if (typeof pattern.image === 'string') {
imageSrc = pattern.image;
const patternImage = (pattern as ImagePatternObject).image;
if (typeof patternImage === 'string') {
imageSrc = patternImage;
}
else if (pattern.image instanceof HTMLImageElement) {
imageSrc = pattern.image.src;
else if (patternImage instanceof HTMLImageElement) {
imageSrc = patternImage.src;
}
else if (pattern.image instanceof HTMLCanvasElement) {
imageSrc = pattern.image.toDataURL();
else if (patternImage instanceof HTMLCanvasElement) {
imageSrc = patternImage.toDataURL();
}

if (imageSrc) {
Expand Down Expand Up @@ -216,8 +217,3 @@ export default class PatternManager extends Definable {
}

}

type CachedImageObj = {
width: number,
height: number
};