Skip to content

Commit 79f8e7d

Browse files
committed
feat: graphic support pathProxy config
1 parent 85292cb commit 79f8e7d

9 files changed

Lines changed: 305 additions & 13 deletions

File tree

packages/vrender-core/src/graphic/area.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export class Area extends Graphic<IAreaGraphicAttribute> implements IArea {
2929
return super.isValid() && this._isValid();
3030
}
3131
private _isValid(): boolean {
32-
if (this.pathProxy) {
32+
if (this.getPathProxy()) {
3333
return true;
3434
}
3535
const { points, segments } = this.attribute;

packages/vrender-core/src/graphic/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ export const DefaultAttribute: Required<IGraphicAttribute> = {
206206
shadowPickMode: 'graphic',
207207
keepStrokeScale: false,
208208
clipConfig: null,
209+
pathProxy: null,
209210
roughStyle: null,
210211
...DefaultDebugAttribute,
211212
...DefaultStyle,

packages/vrender-core/src/graphic/graphic-service/graphic-service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ export class DefaultGraphicService implements IGraphicService {
260260
}
261261
// TODO delete
262262
updatePathProxyAABBBounds(aabbBounds: IAABBBounds, graphic?: IGraphic): boolean {
263-
const path = typeof graphic.pathProxy === 'function' ? graphic.pathProxy(graphic.attribute) : graphic.pathProxy;
263+
const path = graphic?.getPathProxy?.();
264264
if (!path) {
265265
return false;
266266
}

packages/vrender-core/src/graphic/graphic.ts

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ export const PURE_STYLE_KEY = [
105105

106106
export const GRAPHIC_UPDATE_TAG_KEY = [
107107
'lineWidth',
108+
'pathProxy',
108109
// 'lineCap',
109110
// 'lineJoin',
110111
// 'miterLimit',
@@ -321,7 +322,7 @@ export abstract class Graphic<T extends Partial<IGraphicAttribute> = Partial<IGr
321322
// declare prevAttrs?: T;
322323
// declare finalAttrs?: T;
323324

324-
declare pathProxy?: ICustomPath2D;
325+
declare pathProxy?: string | ICustomPath2D | ((attrs: T) => string | ICustomPath2D);
325326
// 依附于某个theme,如果该节点不存在parent,那么这个Theme就作为节点的Theme,避免添加到节点前计算属性
326327
declare attachedThemeGraphic?: IGraphic;
327328
protected updateAABBBoundsStamp: number;
@@ -555,7 +556,7 @@ export abstract class Graphic<T extends Partial<IGraphicAttribute> = Partial<IGr
555556
}
556557

557558
updatePathProxyAABBBounds(aabbBounds: IAABBBounds): boolean {
558-
const path = typeof this.pathProxy === 'function' ? (this.pathProxy as any)(this.attribute) : this.pathProxy;
559+
const path = this.getPathProxy();
559560
if (!path) {
560561
return false;
561562
}
@@ -1492,13 +1493,35 @@ export abstract class Graphic<T extends Partial<IGraphicAttribute> = Partial<IGr
14921493
}
14931494

14941495
createPathProxy(path?: string) {
1495-
if (isString(path, true)) {
1496-
this.pathProxy = new CustomPath2D().fromString(path as string);
1497-
} else {
1498-
this.pathProxy = new CustomPath2D();
1496+
const proxy = isString(path, true) ? new CustomPath2D().fromString(path as string) : new CustomPath2D();
1497+
// 兼容:保留运行时字段,同时将能力下沉到attribute配置
1498+
this.pathProxy = proxy;
1499+
(this.attribute as any).pathProxy = proxy;
1500+
this.addUpdateShapeAndBoundsTag();
1501+
this.onAttributeUpdate();
1502+
return proxy;
1503+
}
1504+
1505+
getPathProxy(): ICustomPath2D | null {
1506+
const attributePathProxy = (this.attribute as any)?.pathProxy;
1507+
const rawPathProxy = attributePathProxy ?? this.pathProxy;
1508+
if (!rawPathProxy) {
1509+
return null;
1510+
}
1511+
1512+
const resolvedPathProxy =
1513+
typeof rawPathProxy === 'function'
1514+
? (rawPathProxy as (attrs: T) => string | ICustomPath2D)(this.attribute)
1515+
: rawPathProxy;
1516+
if (!resolvedPathProxy) {
1517+
return null;
1518+
}
1519+
1520+
if (isString(resolvedPathProxy, true)) {
1521+
return new CustomPath2D().fromString(resolvedPathProxy as string);
14991522
}
15001523

1501-
return this.pathProxy;
1524+
return resolvedPathProxy as ICustomPath2D;
15021525
}
15031526

15041527
loadImage(image: any, background: boolean = false) {
@@ -1632,6 +1655,10 @@ export abstract class Graphic<T extends Partial<IGraphicAttribute> = Partial<IGr
16321655
abstract clone(): IGraphic<any>;
16331656

16341657
toCustomPath(): ICustomPath2D {
1658+
const pathProxy = this.getPathProxy();
1659+
if (pathProxy) {
1660+
return pathProxy;
1661+
}
16351662
// throw new Error('暂不支持');
16361663
const renderer = (this.stage?.renderService || application.renderService)?.drawContribution?.getRenderContribution(
16371664
this

packages/vrender-core/src/graphic/line.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export class Line extends Graphic<ILineGraphicAttribute> implements ILine {
2727
return super.isValid() && this._isValid();
2828
}
2929
private _isValid(): boolean {
30-
if (this.pathProxy) {
30+
if (this.getPathProxy()) {
3131
return true;
3232
}
3333
const { points, segments } = this.attribute;

packages/vrender-core/src/interface/graphic.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,10 @@ export type IGraphicAttribute = IDebugType &
756756
clipConfig: {
757757
shape: string;
758758
} | null;
759+
/**
760+
* 自定义路径,可覆盖图元默认路径渲染(支持字符串、Path2D对象、以及动态函数)
761+
*/
762+
pathProxy?: string | ICustomPath2D | ((attrs: Partial<IGraphicAttribute>) => string | ICustomPath2D) | null;
759763
};
760764

761765
export interface IGraphicJson<T extends Partial<IGraphicAttribute> = Partial<IGraphicAttribute>> {
@@ -832,7 +836,7 @@ export interface IGraphic<T extends Partial<IGraphicAttribute> = Partial<IGraphi
832836
attribute: Partial<T>;
833837

834838
/** 用于实现morph动画场景,转换成bezier曲线渲染 */
835-
pathProxy?: ICustomPath2D | ((attrs: T) => ICustomPath2D);
839+
pathProxy?: string | ICustomPath2D | ((attrs: T) => string | ICustomPath2D);
836840
incremental?: number;
837841
incrementalAt?: number;
838842

@@ -929,6 +933,8 @@ export interface IGraphic<T extends Partial<IGraphicAttribute> = Partial<IGraphi
929933

930934
/** 创建pathProxy */
931935
createPathProxy: (path?: string) => void;
936+
/** 获取解析后的pathProxy(优先取attribute.pathProxy) */
937+
getPathProxy: () => ICustomPath2D | null;
932938
/** 将图形转换成CustomPath2D */
933939
toCustomPath?: () => ICustomPath2D;
934940

packages/vrender-core/src/render/contributions/render/base-render.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,8 @@ export abstract class BaseRender<T extends IGraphic> {
194194
themeAttribute: IThemeAttribute
195195
) => boolean
196196
) {
197-
if (!graphic.pathProxy) {
197+
const path = graphic.getPathProxy();
198+
if (!path) {
198199
return false;
199200
}
200201

@@ -231,7 +232,6 @@ export abstract class BaseRender<T extends IGraphic> {
231232
}
232233

233234
context.beginPath();
234-
const path = typeof graphic.pathProxy === 'function' ? graphic.pathProxy(graphic.attribute) : graphic.pathProxy;
235235
renderCommandList(path.commandList, context, x, y);
236236

237237
// shadow

packages/vrender/__tests__/browser/src/pages/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,10 @@ export const pages = [
179179
name: 'clip测试',
180180
path: 'clip'
181181
},
182+
{
183+
name: 'pathProxy挖洞',
184+
path: 'path-proxy-hole'
185+
},
182186
{
183187
name: 'wordcloud3d测试',
184188
path: 'wordcloud3d'

0 commit comments

Comments
 (0)