From 75e149ced87fb8395c5a8fe41d77ccc3424dbfd3 Mon Sep 17 00:00:00 2001 From: zhouxinyu Date: Tue, 21 Nov 2023 18:11:45 +0800 Subject: [PATCH] feat: rect support x1 and y1 --- .../feat-rect-x1y1_2023-11-21-10-17.json | 10 +++++ .../feat-rect-x1y1_2023-11-21-10-17.json | 10 +++++ .../vrender-core/src/common/shape/rect.ts | 8 ++++ packages/vrender-core/src/core/stage.ts | 3 +- packages/vrender-core/src/graphic/config.ts | 4 ++ .../graphic-service/graphic-service.ts | 7 +++- packages/vrender-core/src/graphic/rect.ts | 31 +++++++------- .../src/interface/graphic/rect.ts | 2 + .../contributions/rect-contribution-render.ts | 11 +++-- .../contributions/render/rect-render.ts | 7 +++- .../src/render/contributions/render/utils.ts | 4 +- .../render/contributions/rough/rough-rect.ts | 10 ++++- .../__tests__/browser/src/pages/rect.ts | 40 +++++++++++++------ 13 files changed, 107 insertions(+), 40 deletions(-) create mode 100644 common/changes/@visactor/vrender-core/feat-rect-x1y1_2023-11-21-10-17.json create mode 100644 common/changes/@visactor/vrender-kits/feat-rect-x1y1_2023-11-21-10-17.json diff --git a/common/changes/@visactor/vrender-core/feat-rect-x1y1_2023-11-21-10-17.json b/common/changes/@visactor/vrender-core/feat-rect-x1y1_2023-11-21-10-17.json new file mode 100644 index 000000000..a3982abd4 --- /dev/null +++ b/common/changes/@visactor/vrender-core/feat-rect-x1y1_2023-11-21-10-17.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@visactor/vrender-core", + "comment": "feat: rect support x1 and y1", + "type": "none" + } + ], + "packageName": "@visactor/vrender-core" +} \ No newline at end of file diff --git a/common/changes/@visactor/vrender-kits/feat-rect-x1y1_2023-11-21-10-17.json b/common/changes/@visactor/vrender-kits/feat-rect-x1y1_2023-11-21-10-17.json new file mode 100644 index 000000000..b65bbff73 --- /dev/null +++ b/common/changes/@visactor/vrender-kits/feat-rect-x1y1_2023-11-21-10-17.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@visactor/vrender-kits", + "comment": "feat: rect support x1 and y1", + "type": "none" + } + ], + "packageName": "@visactor/vrender-kits" +} \ No newline at end of file diff --git a/packages/vrender-core/src/common/shape/rect.ts b/packages/vrender-core/src/common/shape/rect.ts index 696a22782..513996a5f 100644 --- a/packages/vrender-core/src/common/shape/rect.ts +++ b/packages/vrender-core/src/common/shape/rect.ts @@ -12,6 +12,14 @@ export function createRectPath( height: number, rectCornerRadius: number | number[] ) { + if (width < 0) { + x += width; + width = -width; + } + if (height < 0) { + y += height; + height = -height; + } // 匹配cornerRadius let cornerRadius: vec4; if (isNumber(rectCornerRadius, true)) { diff --git a/packages/vrender-core/src/core/stage.ts b/packages/vrender-core/src/core/stage.ts index 85a61afb8..bf39c7053 100644 --- a/packages/vrender-core/src/core/stage.ts +++ b/packages/vrender-core/src/core/stage.ts @@ -169,7 +169,6 @@ export class Stage extends Group implements IStage { readonly layerService: ILayerService; private _eventSystem?: EventSystem; private get eventSystem(): EventSystem { - this.tryInitEventSystem(); return this._eventSystem; } @@ -231,7 +230,7 @@ export class Stage extends Group implements IStage { this.state = 'normal'; this.renderCount = 0; - + this.tryInitEventSystem(); // // 没有传入xy就默认为0 // this._x = params.x ?? DefaultConfig.X; // this._y = params.y ?? DefaultConfig.Y; diff --git a/packages/vrender-core/src/graphic/config.ts b/packages/vrender-core/src/graphic/config.ts index d532beaf7..87c8ab832 100644 --- a/packages/vrender-core/src/graphic/config.ts +++ b/packages/vrender-core/src/graphic/config.ts @@ -263,6 +263,8 @@ export const DefaultRectAttribute: Required = { ...DefaultAttribute, width: 0, height: 0, + x1: 0, + y1: 0, strokeBoundsBuffer: 0, cornerRadius: 0 }; @@ -271,6 +273,8 @@ export const DefaultRect3dAttribute: Required = { ...DefaultAttribute, width: 0, height: 0, + x1: 0, + y1: 0, cornerRadius: 0, length: 0 }; diff --git a/packages/vrender-core/src/graphic/graphic-service/graphic-service.ts b/packages/vrender-core/src/graphic/graphic-service/graphic-service.ts index 45981d3ce..6aac55607 100644 --- a/packages/vrender-core/src/graphic/graphic-service/graphic-service.ts +++ b/packages/vrender-core/src/graphic/graphic-service/graphic-service.ts @@ -719,8 +719,11 @@ export class DefaultGraphicService implements IGraphicService { graphic?: IGraphic ) { if (!this.updatePathProxyAABBBounds(aabbBounds, graphic)) { - const { width = rectTheme.width, height = rectTheme.height } = attribute; - aabbBounds.set(0, 0, width, height); + let { width, height } = attribute; + const { x1, y1, x, y } = attribute; + width = width ?? x1 - x; + height = height ?? y1 - y; + aabbBounds.set(0, 0, width || 0, height || 0); } const tb1 = this.tempAABBBounds1; diff --git a/packages/vrender-core/src/graphic/rect.ts b/packages/vrender-core/src/graphic/rect.ts index a2f01e458..176323960 100644 --- a/packages/vrender-core/src/graphic/rect.ts +++ b/packages/vrender-core/src/graphic/rect.ts @@ -1,13 +1,13 @@ import type { AABBBounds, OBBBounds } from '@visactor/vutils'; import { Graphic, GRAPHIC_UPDATE_TAG_KEY, NOWORK_ANIMATE_ATTR } from './graphic'; -import type { GraphicType, IRect, IRectGraphicAttribute } from '../interface'; +import type { GraphicType, ICustomPath2D, IRect, IRectGraphicAttribute } from '../interface'; import { CustomPath2D } from '../common/custom-path2d'; import { parsePadding } from '../common/utils'; import { getTheme } from './theme'; import { application } from '../application'; import { RECT_NUMBER_TYPE } from './constants'; -const RECT_UPDATE_TAG_KEY = ['width', 'height', 'cornerRadius', ...GRAPHIC_UPDATE_TAG_KEY]; +const RECT_UPDATE_TAG_KEY = ['width', 'x1', 'y1', 'height', 'cornerRadius', ...GRAPHIC_UPDATE_TAG_KEY]; export class Rect extends Graphic implements IRect { type: GraphicType = 'rect'; @@ -23,8 +23,10 @@ export class Rect extends Graphic implements IRect { return super.isValid() && this._isValid(); } private _isValid(): boolean { - const { width, height } = this.attribute; - return this._validNumber(width) && this._validNumber(height); + return true; + // 暂时不判断,理论上认为都是合法的,节省性能耗时 + // const { width, x1, y1, height } = this.attribute; + // return (this._validNumber(width) || this._validNumber(x1)) && (this._validNumber(height) || this._validNumber(y1)); } protected doUpdateAABBBounds(): AABBBounds { @@ -64,18 +66,19 @@ export class Rect extends Graphic implements IRect { return super.needUpdateTag(key, RECT_UPDATE_TAG_KEY); } - toCustomPath() { - const attribute = this.attribute; - const width = attribute.width; - const height = attribute.height; - const x = 0; - const y = 0; + toCustomPath(): ICustomPath2D { + throw new Error('暂不支持'); + // const attribute = this.attribute; + // const width = attribute.width; + // const height = attribute.height; + // const x = 0; + // const y = 0; - const path = new CustomPath2D(); - path.moveTo(x, y); - path.rect(x, y, width, height); + // const path = new CustomPath2D(); + // path.moveTo(x, y); + // path.rect(x, y, width, height); - return path; + // return path; } clone() { diff --git a/packages/vrender-core/src/interface/graphic/rect.ts b/packages/vrender-core/src/interface/graphic/rect.ts index 58b9a5939..c6ed1a88a 100644 --- a/packages/vrender-core/src/interface/graphic/rect.ts +++ b/packages/vrender-core/src/interface/graphic/rect.ts @@ -4,6 +4,8 @@ import type { ICustomPath2D } from '../path'; export type IRectAttribute = { width: number; height: number; + x1: number; + y1: number; cornerRadius: number | number[]; }; diff --git a/packages/vrender-core/src/render/contributions/render/contributions/rect-contribution-render.ts b/packages/vrender-core/src/render/contributions/render/contributions/rect-contribution-render.ts index 22a198bf6..3ba1b7187 100644 --- a/packages/vrender-core/src/render/contributions/render/contributions/rect-contribution-render.ts +++ b/packages/vrender-core/src/render/contributions/render/contributions/rect-contribution-render.ts @@ -51,16 +51,21 @@ export class DefaultRectRenderContribution implements IRectRenderContribution { return; } const { - width = rectAttribute.width, - height = rectAttribute.height, cornerRadius = rectAttribute.cornerRadius, opacity = rectAttribute.opacity, x: originX = rectAttribute.x, y: originY = rectAttribute.y, scaleX = rectAttribute.scaleX, - scaleY = rectAttribute.scaleY + scaleY = rectAttribute.scaleY, + x1, + y1 } = rect.attribute; + let { width, height } = rect.attribute; + + width = (width ?? x1 - x) || 0; + height = (height ?? y1 - y) || 0; + const doStrokeOuter = !!(outerBorder && outerBorder.stroke); const doStrokeInner = !!(innerBorder && innerBorder.stroke); diff --git a/packages/vrender-core/src/render/contributions/render/rect-render.ts b/packages/vrender-core/src/render/contributions/render/rect-render.ts index 8cba6ce2b..3f8c6323a 100644 --- a/packages/vrender-core/src/render/contributions/render/rect-render.ts +++ b/packages/vrender-core/src/render/contributions/render/rect-render.ts @@ -75,17 +75,20 @@ export class DefaultCanvasRectRender extends BaseRender implements IGraph fill = rectAttribute.fill, background, stroke = rectAttribute.stroke, - width = rectAttribute.width, - height = rectAttribute.height, cornerRadius = rectAttribute.cornerRadius, opacity = rectAttribute.opacity, fillOpacity = rectAttribute.fillOpacity, lineWidth = rectAttribute.lineWidth, strokeOpacity = rectAttribute.strokeOpacity, visible = rectAttribute.visible, + x1, + y1, x: originX = rectAttribute.x, y: originY = rectAttribute.y } = rect.attribute; + let { width, height } = rect.attribute; + width = (width ?? x1 - originX) || 0; + height = (height ?? y1 - originY) || 0; // 不绘制或者透明 const fVisible = rectFillVisible(opacity, fillOpacity, width, height, fill); diff --git a/packages/vrender-core/src/render/contributions/render/utils.ts b/packages/vrender-core/src/render/contributions/render/utils.ts index 92f36314a..2f782f205 100644 --- a/packages/vrender-core/src/render/contributions/render/utils.ts +++ b/packages/vrender-core/src/render/contributions/render/utils.ts @@ -53,7 +53,7 @@ export function fillVisible(opacity: number, fillOpacity: number, fill: IFillTyp } export function rectFillVisible(opacity: number, fillOpacity: number, width: number, height: number, fill: IFillType) { - return fill && opacity * fillOpacity > 0 && width > 0 && height > 0; + return fill && opacity * fillOpacity > 0 && width !== 0 && height !== 0; } /** @@ -68,7 +68,7 @@ export function strokeVisible(opacity: number, strokeOpacity: number) { } export function rectStrokeVisible(opacity: number, strokeOpacity: number, width: number, height: number) { - return opacity * strokeOpacity > 0 && width > 0 && height > 0; + return opacity * strokeOpacity > 0 && width !== 0 && height !== 0; } export function drawPathProxy( diff --git a/packages/vrender-kits/src/render/contributions/rough/rough-rect.ts b/packages/vrender-kits/src/render/contributions/rough/rough-rect.ts index 974b7083b..2d2cf8e43 100644 --- a/packages/vrender-kits/src/render/contributions/rough/rough-rect.ts +++ b/packages/vrender-kits/src/render/contributions/rough/rough-rect.ts @@ -60,8 +60,8 @@ export class RoughCanvasRectRender implements IGraphicRender { stroke = rectAttribute.stroke, fillColor = rectAttribute.fill, strokeColor = rectAttribute.stroke, - width = rectAttribute.width, - height = rectAttribute.height, + x1, + y1, lineWidth = rectAttribute.lineWidth, maxRandomnessOffset = defaultRouthThemeSpec.maxRandomnessOffset, roughness = defaultRouthThemeSpec.roughness, @@ -85,6 +85,12 @@ export class RoughCanvasRectRender implements IGraphicRender { preserveVertices = defaultRouthThemeSpec.preserveVertices, fixedDecimalPlaceDigits = defaultRouthThemeSpec.fixedDecimalPlaceDigits } = rect.attribute as any; + + let { width = rectAttribute.width, height = rectAttribute.height } = rect.attribute; + + width = (width ?? x1 - x) || 0; + height = (height ?? y1 - y) || 0; + rc.rectangle(x, y, width, height, { fill: fill ? (fillColor as string) : undefined, stroke: stroke ? (strokeColor as string) : undefined, diff --git a/packages/vrender/__tests__/browser/src/pages/rect.ts b/packages/vrender/__tests__/browser/src/pages/rect.ts index 4649c8646..cdb14350f 100644 --- a/packages/vrender/__tests__/browser/src/pages/rect.ts +++ b/packages/vrender/__tests__/browser/src/pages/rect.ts @@ -5,18 +5,31 @@ import { addShapesToStage, colorPools } from '../utils'; // container.load(roughModule); export const page = () => { const graphics: IGraphic[] = []; - graphics.push( - createRect({ - x: 100, - y: 100, - width: 20, - height: 100, - fill: colorPools[10], - stroke: [colorPools[0], colorPools[0], colorPools[0], colorPools[0]], - cornerRadius: 10, - lineWidth: 5 - }) - ); + // graphics.push( + // createRect({ + // x: 100, + // y: 100, + // width: 20, + // height: 100, + // fill: colorPools[10], + // stroke: [colorPools[0], colorPools[0], colorPools[0], colorPools[0]], + // cornerRadius: 10, + // lineWidth: 5 + // }) + // ); + + const rect = createRect({ + x: 120, + y: 200, + x1: 100, + y1: 100, + fill: 'red', + // stroke: [colorPools[0], colorPools[0], colorPools[0], colorPools[0]], + _debug_bounds: true, + cornerRadius: 10, + lineWidth: 5 + }); + graphics.push(rect); const r = createRect({ x: 300, @@ -40,6 +53,7 @@ export const page = () => { cornerRadius: [5, 10, 15, 20], lineWidth: 5 }); + graphics.push(r); r.animate().to({ scaleX: 2, scaleY: 2 }, 1000, 'linear'); @@ -60,7 +74,7 @@ export const page = () => { canvas: 'main', autoRender: true }); - + rect.addEventListener('pointerenter', () => console.log('abc')); graphics.forEach(g => { stage.defaultLayer.add(g); });