diff --git a/__tests__/unit/css/initial.spec.ts b/__tests__/unit/css/initial.spec.ts index 6b4133f4e..7f11e349e 100644 --- a/__tests__/unit/css/initial.spec.ts +++ b/__tests__/unit/css/initial.spec.ts @@ -2,14 +2,13 @@ import { Renderer as CanvasRenderer } from '../../../packages/g-svg/src'; import { Canvas, Circle, - CSS, CSSKeywordValue, CSSRGB, - CSSUnitValue, Ellipse, Image, Rect, Text, + getParsedStyle, } from '../../../packages/g/src'; const $container = document.createElement('div'); @@ -72,7 +71,7 @@ describe('StyleValueRegistry initialization', () => { // computed value // expect((styleMap.get('visibility') as string).toString()).toBe('hidden'); // used value - // expect(documentElement.parsedStyle.visibility.toString()).toBe('hidden'); + // expect(getParsedStyle(documentElement, "visibility").toString()).toBe('hidden'); documentElement.style.visibility = 'unset'; expect(documentElement.style.visibility).toBe('unset'); @@ -80,7 +79,7 @@ describe('StyleValueRegistry initialization', () => { // styleMap = documentElement.computedStyleMap(); // expect((styleMap.get('visibility') as string).toString()).toBe('unset'); // used value - // expect(documentElement.parsedStyle.visibility.toString()).toBe('visible'); + // expect(getParsedStyle(documentElement, "visibility").toString()).toBe('visible'); // disable pointerEvents documentElement.style.pointerEvents = 'none'; @@ -89,7 +88,9 @@ describe('StyleValueRegistry initialization', () => { // computed value // expect((styleMap.get('pointerEvents') as string).toString()).toBe('none'); // used value - expect(documentElement.parsedStyle.pointerEvents.toString()).toBe('none'); + expect(getParsedStyle(documentElement, 'pointerEvents').toString()).toBe( + 'none', + ); // enable pointerEvents documentElement.style.pointerEvents = 'auto'; @@ -98,7 +99,9 @@ describe('StyleValueRegistry initialization', () => { // computed value // expect((styleMap.get('pointerEvents') as string).toString()).toBe('auto'); // used value - expect(documentElement.parsedStyle.pointerEvents.toString()).toBe('auto'); + expect(getParsedStyle(documentElement, 'pointerEvents').toString()).toBe( + 'auto', + ); }); it('should parse & compute CSS properties for Circle correctly.', async () => { @@ -204,38 +207,37 @@ describe('StyleValueRegistry initialization', () => { /** * parsed values, will be used in internal renderers such as `g-canvas` */ - let parsedStyle = circle.parsedStyle; - expect(parsedStyle.cx).toBe(200); - expect(parsedStyle.cy).toBe(200); - expect(parsedStyle.cz).toBeUndefined(); - expect(parsedStyle.r).toBe(100); - expect(parsedStyle.fill instanceof CSSRGB).toBeTruthy(); - expect((parsedStyle.fill as CSSRGB).r).toBe(255); - expect((parsedStyle.fill as CSSRGB).g).toBe(0); - expect((parsedStyle.fill as CSSRGB).b).toBe(0); - expect((parsedStyle.fill as CSSRGB).alpha).toBe(1); - expect(parsedStyle.stroke instanceof CSSRGB).toBeTruthy(); - expect((parsedStyle.stroke as CSSRGB).r).toBe(0); - expect((parsedStyle.stroke as CSSRGB).g).toBe(0); - expect((parsedStyle.stroke as CSSRGB).b).toBe(0); - expect((parsedStyle.stroke as CSSRGB).alpha).toBe(1); - // expect(parsedStyle.transformOrigin!.length).toBe(2); + expect(getParsedStyle(circle, 'cx')).toBe(200); + expect(getParsedStyle(circle, 'cy')).toBe(200); + expect(getParsedStyle(circle, 'cz')).toBeUndefined(); + expect(getParsedStyle(circle, 'r')).toBe(100); + expect(getParsedStyle(circle, 'fill') instanceof CSSRGB).toBeTruthy(); + expect((getParsedStyle(circle, 'fill') as CSSRGB).r).toBe(255); + expect((getParsedStyle(circle, 'fill') as CSSRGB).g).toBe(0); + expect((getParsedStyle(circle, 'fill') as CSSRGB).b).toBe(0); + expect((getParsedStyle(circle, 'fill') as CSSRGB).alpha).toBe(1); + expect(getParsedStyle(circle, 'stroke') instanceof CSSRGB).toBeTruthy(); + expect((getParsedStyle(circle, 'stroke') as CSSRGB).r).toBe(0); + expect((getParsedStyle(circle, 'stroke') as CSSRGB).g).toBe(0); + expect((getParsedStyle(circle, 'stroke') as CSSRGB).b).toBe(0); + expect((getParsedStyle(circle, 'stroke') as CSSRGB).alpha).toBe(1); + // expect(getParsedStyle(circle, "transformOrigin")!.length).toBe(2); // expect( - // parsedStyle.transformOrigin![0].equals(CSS.percent(50)), + // getParsedStyle(circle, "transformOrigin")![0].equals(CSS.percent(50)), // ).toBeTruthy(); // expect( - // parsedStyle.transformOrigin![1].equals(CSS.percent(50)), + // getParsedStyle(circle, "transformOrigin")![1].equals(CSS.percent(50)), // ).toBeTruthy(); // these inheritable props should get re-calculated after appended to document - expect(parsedStyle.opacity).toBeUndefined(); - expect(parsedStyle.fillOpacity).toBeUndefined(); - expect(parsedStyle.lineCap).toBeUndefined(); - expect(parsedStyle.lineJoin).toBeUndefined(); - expect(parsedStyle.strokeOpacity).toBeUndefined(); - expect(parsedStyle.visibility).toBeUndefined(); - expect(parsedStyle.pointerEvents).toBeUndefined(); + expect(getParsedStyle(circle, 'opacity')).toBeUndefined(); + expect(getParsedStyle(circle, 'fillOpacity')).toBeUndefined(); + expect(getParsedStyle(circle, 'lineCap')).toBeUndefined(); + expect(getParsedStyle(circle, 'lineJoin')).toBeUndefined(); + expect(getParsedStyle(circle, 'strokeOpacity')).toBeUndefined(); + expect(getParsedStyle(circle, 'visibility')).toBeUndefined(); + expect(getParsedStyle(circle, 'pointerEvents')).toBeUndefined(); // @ts-ignore - expect(parsedStyle.xxxxx).toBeUndefined(); + expect(getParsedStyle(circle, 'xxxxx')).toBeUndefined(); await canvas.ready; /** @@ -245,12 +247,12 @@ describe('StyleValueRegistry initialization', () => { // parsedStyle = circle.parsedStyle; // // inherit from document.documentElement - // expect(parsedStyle.fillOpacity).toBe(1); - // expect(parsedStyle.strokeOpacity).toBe(1); - // expect(parsedStyle.lineCap).toBe('butt'); - // expect(parsedStyle.lineJoin).toBe('miter'); - // expect(parsedStyle.visibility).toBe('visible'); - // expect(parsedStyle.pointerEvents).toBe('auto'); + // expect(getParsedStyle(circle, "fillOpacity")).toBe(1); + // expect(getParsedStyle(circle, "strokeOpacity")).toBe(1); + // expect(getParsedStyle(circle, "lineCap")).toBe('butt'); + // expect(getParsedStyle(circle, "lineJoin")).toBe('miter'); + // expect(getParsedStyle(circle, "visibility")).toBe('visible'); + // expect(getParsedStyle(circle, "pointerEvents")).toBe('auto'); }); it('should parse & compute CSS properties for Ellipse correctly.', () => { @@ -338,40 +340,39 @@ describe('StyleValueRegistry initialization', () => { /** * parsed values, will be used in internal renderers such as `g-canvas` */ - const parsedStyle = ellipse.parsedStyle; - expect(parsedStyle.cx).toBeUndefined(); - expect(parsedStyle.cy).toBeUndefined(); - expect(parsedStyle.rx).toBe(200); - expect(parsedStyle.ry).toBe(100); + expect(getParsedStyle(ellipse, 'cx')).toBeUndefined(); + expect(getParsedStyle(ellipse, 'cy')).toBeUndefined(); + expect(getParsedStyle(ellipse, 'rx')).toBe(200); + expect(getParsedStyle(ellipse, 'ry')).toBe(100); // 'transparent' - expect(parsedStyle.fill instanceof CSSRGB).toBeTruthy(); - expect((parsedStyle.fill as CSSRGB).r).toBe(0); - expect((parsedStyle.fill as CSSRGB).g).toBe(0); - expect((parsedStyle.fill as CSSRGB).b).toBe(0); - expect((parsedStyle.fill as CSSRGB).alpha).toBe(0); - expect((parsedStyle.fill as CSSRGB).isNone).toBeFalsy(); + expect(getParsedStyle(ellipse, 'fill') instanceof CSSRGB).toBeTruthy(); + expect((getParsedStyle(ellipse, 'fill') as CSSRGB).r).toBe(0); + expect((getParsedStyle(ellipse, 'fill') as CSSRGB).g).toBe(0); + expect((getParsedStyle(ellipse, 'fill') as CSSRGB).b).toBe(0); + expect((getParsedStyle(ellipse, 'fill') as CSSRGB).alpha).toBe(0); + expect((getParsedStyle(ellipse, 'fill') as CSSRGB).isNone).toBeFalsy(); // 'none' - // expect(parsedStyle.stroke instanceof CSSRGB).toBeTruthy(); - // expect((parsedStyle.stroke as CSSRGB).r).toBe(0); - // expect((parsedStyle.stroke as CSSRGB).g).toBe(0); - // expect((parsedStyle.stroke as CSSRGB).b).toBe(0); - // expect((parsedStyle.stroke as CSSRGB).alpha).toBe(0); - // expect((parsedStyle.stroke as CSSRGB).isNone).toBeTruthy(); - expect(parsedStyle.opacity).toBe(0.5); - expect(parsedStyle.fillOpacity).toBe(0.5); - // expect(parsedStyle.transformOrigin!.length).toBe(2); + // expect(getParsedStyle(ellipse, "stroke") instanceof CSSRGB).toBeTruthy(); + // expect((getParsedStyle(ellipse, "stroke") as CSSRGB).r).toBe(0); + // expect((getParsedStyle(ellipse, "stroke") as CSSRGB).g).toBe(0); + // expect((getParsedStyle(ellipse, "stroke") as CSSRGB).b).toBe(0); + // expect((getParsedStyle(ellipse, "stroke") as CSSRGB).alpha).toBe(0); + // expect((getParsedStyle(ellipse, "stroke") as CSSRGB).isNone).toBeTruthy(); + expect(getParsedStyle(ellipse, 'opacity')).toBe(0.5); + expect(getParsedStyle(ellipse, 'fillOpacity')).toBe(0.5); + // expect(getParsedStyle(ellipse, "transformOrigin")!.length).toBe(2); // expect( - // parsedStyle.transformOrigin![0].equals(CSS.percent(50)), + // getParsedStyle(ellipse, "transformOrigin")![0].equals(CSS.percent(50)), // ).toBeTruthy(); // expect( - // parsedStyle.transformOrigin![1].equals(CSS.percent(50)), + // getParsedStyle(ellipse, "transformOrigin")![1].equals(CSS.percent(50)), // ).toBeTruthy(); // these inheritable props should get re-calculated after appended to document - expect(parsedStyle.visibility).toBeUndefined(); - expect(parsedStyle.lineCap).toBeUndefined(); - expect(parsedStyle.lineJoin).toBe('bevel'); + expect(getParsedStyle(ellipse, 'visibility')).toBeUndefined(); + expect(getParsedStyle(ellipse, 'lineCap')).toBeUndefined(); + expect(getParsedStyle(ellipse, 'lineJoin')).toBe('bevel'); // @ts-ignore - expect(parsedStyle.xxxxx).toBeUndefined(); + expect(getParsedStyle(ellipse, 'xxxxx')).toBeUndefined(); }); it('should parse & compute CSS properties for Rect correctly.', async () => { @@ -451,36 +452,35 @@ describe('StyleValueRegistry initialization', () => { /** * parsed values, will be used in internal renderers such as `g-canvas` */ - const parsedStyle = rect.parsedStyle; - expect(parsedStyle.x).toBeUndefined(); - expect(parsedStyle.y).toBeUndefined(); - // expect(parsedStyle.z.equals(CSS.px(0))).toBeTruthy(); - expect(parsedStyle.width).toBe(200); - expect(parsedStyle.height).toBe(100); - // expect(parsedStyle.radius![0]).toBe(0); - // expect(parsedStyle.radius![1]).toBe(0); - // expect(parsedStyle.radius![2]).toBe(0); - // expect(parsedStyle.radius![3]).toBe(0); - // expect(parsedStyle.fill instanceof CSSRGB).toBeTruthy(); - // expect((parsedStyle.fill as CSSRGB).r).toBe(0); - // expect((parsedStyle.fill as CSSRGB).g).toBe(0); - // expect((parsedStyle.fill as CSSRGB).b).toBe(0); - // expect((parsedStyle.fill as CSSRGB).alpha).toBe(0); - // expect(parsedStyle.stroke instanceof CSSRGB).toBeTruthy(); - // expect((parsedStyle.stroke as CSSRGB).r).toBe(0); - // expect((parsedStyle.stroke as CSSRGB).g).toBe(0); - // expect((parsedStyle.stroke as CSSRGB).b).toBe(0); - // expect((parsedStyle.stroke as CSSRGB).alpha).toBe(0); - // expect(parsedStyle.transformOrigin!.length).toBe(2); - // expect(parsedStyle.transformOrigin![0].equals(CSS.px(0))).toBeTruthy(); - // expect(parsedStyle.transformOrigin![1].equals(CSS.px(0))).toBeTruthy(); + expect(getParsedStyle(rect, 'x')).toBeUndefined(); + expect(getParsedStyle(rect, 'y')).toBeUndefined(); + // expect(getParsedStyle(rect, "z").equals(CSS.px(0))).toBeTruthy(); + expect(getParsedStyle(rect, 'width')).toBe(200); + expect(getParsedStyle(rect, 'height')).toBe(100); + // expect(getParsedStyle(rect, "radius")![0]).toBe(0); + // expect(getParsedStyle(rect, "radius")![1]).toBe(0); + // expect(getParsedStyle(rect, "radius")![2]).toBe(0); + // expect(getParsedStyle(rect, "radius")![3]).toBe(0); + // expect(getParsedStyle(rect, "fill") instanceof CSSRGB).toBeTruthy(); + // expect((getParsedStyle(rect, "fill") as CSSRGB).r).toBe(0); + // expect((getParsedStyle(rect, "fill") as CSSRGB).g).toBe(0); + // expect((getParsedStyle(rect, "fill") as CSSRGB).b).toBe(0); + // expect((getParsedStyle(rect, "fill") as CSSRGB).alpha).toBe(0); + // expect(getParsedStyle(rect, "stroke") instanceof CSSRGB).toBeTruthy(); + // expect((getParsedStyle(rect, "stroke") as CSSRGB).r).toBe(0); + // expect((getParsedStyle(rect, "stroke") as CSSRGB).g).toBe(0); + // expect((getParsedStyle(rect, "stroke") as CSSRGB).b).toBe(0); + // expect((getParsedStyle(rect, "stroke") as CSSRGB).alpha).toBe(0); + // expect(getParsedStyle(rect, "transformOrigin")!.length).toBe(2); + // expect(getParsedStyle(rect, "transformOrigin")![0].equals(CSS.px(0))).toBeTruthy(); + // expect(getParsedStyle(rect, "transformOrigin")![1].equals(CSS.px(0))).toBeTruthy(); // these inheritable props should get re-calculated after appended to document - expect(parsedStyle.opacity).toBeUndefined(); - expect(parsedStyle.fillOpacity).toBeUndefined(); - expect(parsedStyle.strokeOpacity).toBeUndefined(); - // expect(parsedStyle.visibility).toBeUndefined(); + expect(getParsedStyle(rect, 'opacity')).toBeUndefined(); + expect(getParsedStyle(rect, 'fillOpacity')).toBeUndefined(); + expect(getParsedStyle(rect, 'strokeOpacity')).toBeUndefined(); + // expect(getParsedStyle(rect, "visibility")).toBeUndefined(); // @ts-ignore - expect(parsedStyle.xxxxx).toBeUndefined(); + expect(getParsedStyle(rect, 'xxxxx')).toBeUndefined(); await canvas.ready; /** @@ -489,12 +489,12 @@ describe('StyleValueRegistry initialization', () => { canvas.appendChild(rect); // inherit from document.documentElement - // expect(parsedStyle.lineWidth).toBeUndefined(); - // expect(parsedStyle.fillOpacity).toBe(1); - // expect(parsedStyle.strokeOpacity).toBe(1); - // expect(parsedStyle.lineCap).toBe('butt'); - // expect(parsedStyle.lineJoin).toBe('miter'); - // expect(parsedStyle.pointerEvents).toBe('auto'); + // expect(getParsedStyle(rect, "lineWidth")).toBeUndefined(); + // expect(getParsedStyle(rect, "fillOpacity")).toBe(1); + // expect(getParsedStyle(rect, "strokeOpacity")).toBe(1); + // expect(getParsedStyle(rect, "lineCap")).toBe('butt'); + // expect(getParsedStyle(rect, "lineJoin")).toBe('miter'); + // expect(getParsedStyle(rect, "pointerEvents")).toBe('auto'); }); it('should parse & compute CSS properties for Image correctly.', () => { @@ -558,33 +558,32 @@ describe('StyleValueRegistry initialization', () => { /** * parsed values, will be used in internal renderers such as `g-canvas` */ - const parsedStyle = image.parsedStyle; - expect(parsedStyle.src).toBe('url'); - expect(parsedStyle.x).toBeUndefined(); - expect(parsedStyle.y).toBeUndefined(); - // expect(parsedStyle.z.equals(CSS.px(0))).toBeTruthy(); - expect(parsedStyle.width).toBe(200); - expect(parsedStyle.height).toBe(100); - // expect(parsedStyle.fill instanceof CSSRGB).toBeTruthy(); - // expect((parsedStyle.fill as CSSRGB).r).toBe(0); - // expect((parsedStyle.fill as CSSRGB).g).toBe(0); - // expect((parsedStyle.fill as CSSRGB).b).toBe(0); - // expect((parsedStyle.fill as CSSRGB).alpha).toBe(0); - // expect(parsedStyle.stroke instanceof CSSRGB).toBeTruthy(); - // expect((parsedStyle.stroke as CSSRGB).r).toBe(0); - // expect((parsedStyle.stroke as CSSRGB).g).toBe(0); - // expect((parsedStyle.stroke as CSSRGB).b).toBe(0); - // expect((parsedStyle.stroke as CSSRGB).alpha).toBe(0); - expect(parsedStyle.visibility).toBe('visible'); - // expect(parsedStyle.transformOrigin!.length).toBe(2); - // expect(parsedStyle.transformOrigin![0].equals(CSS.px(0))).toBeTruthy(); - // expect(parsedStyle.transformOrigin![1].equals(CSS.px(0))).toBeTruthy(); + expect(getParsedStyle(image, 'src')).toBe('url'); + expect(getParsedStyle(image, 'x')).toBeUndefined(); + expect(getParsedStyle(image, 'y')).toBeUndefined(); + // expect(getParsedStyle(image, "z").equals(CSS.px(0))).toBeTruthy(); + expect(getParsedStyle(image, 'width')).toBe(200); + expect(getParsedStyle(image, 'height')).toBe(100); + // expect(getParsedStyle(image, "fill") instanceof CSSRGB).toBeTruthy(); + // expect((getParsedStyle(image, "fill") as CSSRGB).r).toBe(0); + // expect((getParsedStyle(image, "fill") as CSSRGB).g).toBe(0); + // expect((getParsedStyle(image, "fill") as CSSRGB).b).toBe(0); + // expect((getParsedStyle(image, "fill") as CSSRGB).alpha).toBe(0); + // expect(getParsedStyle(image, "stroke") instanceof CSSRGB).toBeTruthy(); + // expect((getParsedStyle(image, "stroke") as CSSRGB).r).toBe(0); + // expect((getParsedStyle(image, "stroke") as CSSRGB).g).toBe(0); + // expect((getParsedStyle(image, "stroke") as CSSRGB).b).toBe(0); + // expect((getParsedStyle(image, "stroke") as CSSRGB).alpha).toBe(0); + expect(getParsedStyle(image, 'visibility')).toBe('visible'); + // expect(getParsedStyle(image, "transformOrigin")!.length).toBe(2); + // expect(getParsedStyle(image, "transformOrigin")![0].equals(CSS.px(0))).toBeTruthy(); + // expect(getParsedStyle(image, "transformOrigin")![1].equals(CSS.px(0))).toBeTruthy(); // these inheritable props should get re-calculated after appended to document - expect(parsedStyle.opacity).toBeUndefined(); - expect(parsedStyle.fillOpacity).toBeUndefined(); - expect(parsedStyle.strokeOpacity).toBeUndefined(); + expect(getParsedStyle(image, 'opacity')).toBeUndefined(); + expect(getParsedStyle(image, 'fillOpacity')).toBeUndefined(); + expect(getParsedStyle(image, 'strokeOpacity')).toBeUndefined(); // @ts-ignore - expect(parsedStyle.xxxxx).toBeUndefined(); + expect(getParsedStyle(image, 'xxxxx')).toBeUndefined(); }); it.skip('should parse & compute CSS properties for Text correctly.', async () => { @@ -646,28 +645,27 @@ describe('StyleValueRegistry initialization', () => { /** * used values */ - let parsedStyle = text.parsedStyle; - expect(parsedStyle.fill instanceof CSSRGB).toBeTruthy(); - expect((parsedStyle.fill as CSSRGB).r).toBe(0); - expect((parsedStyle.fill as CSSRGB).g).toBe(0); - expect((parsedStyle.fill as CSSRGB).b).toBe(0); - expect((parsedStyle.fill as CSSRGB).alpha).toBe(1); - expect(parsedStyle.stroke instanceof CSSRGB).toBeTruthy(); - expect((parsedStyle.stroke as CSSRGB).r).toBe(0); - expect((parsedStyle.stroke as CSSRGB).g).toBe(0); - expect((parsedStyle.stroke as CSSRGB).b).toBe(0); - expect((parsedStyle.stroke as CSSRGB).alpha).toBe(0); + expect(getParsedStyle(text, 'fill') instanceof CSSRGB).toBeTruthy(); + expect((getParsedStyle(text, 'fill') as CSSRGB).r).toBe(0); + expect((getParsedStyle(text, 'fill') as CSSRGB).g).toBe(0); + expect((getParsedStyle(text, 'fill') as CSSRGB).b).toBe(0); + expect((getParsedStyle(text, 'fill') as CSSRGB).alpha).toBe(1); + expect(getParsedStyle(text, 'stroke') instanceof CSSRGB).toBeTruthy(); + expect((getParsedStyle(text, 'stroke') as CSSRGB).r).toBe(0); + expect((getParsedStyle(text, 'stroke') as CSSRGB).g).toBe(0); + expect((getParsedStyle(text, 'stroke') as CSSRGB).b).toBe(0); + expect((getParsedStyle(text, 'stroke') as CSSRGB).alpha).toBe(0); // these inheritable props should get re-calculated after appended to document - expect(parsedStyle.fillOpacity).toBeUndefined(); - expect(parsedStyle.strokeOpacity).toBeUndefined(); - expect(parsedStyle.lineCap).toBeUndefined(); - expect(parsedStyle.lineJoin).toBeUndefined(); - expect(parsedStyle.visibility).toBeUndefined(); - expect(parsedStyle.fontWeight).toBeUndefined(); - expect(parsedStyle.fontStyle).toBeUndefined(); - expect(parsedStyle.fontVariant).toBeUndefined(); - expect(parsedStyle.textAlign).toBeUndefined(); - expect(parsedStyle.textBaseline).toBeUndefined(); + expect(getParsedStyle(text, 'fillOpacity')).toBeUndefined(); + expect(getParsedStyle(text, 'strokeOpacity')).toBeUndefined(); + expect(getParsedStyle(text, 'lineCap')).toBeUndefined(); + expect(getParsedStyle(text, 'lineJoin')).toBeUndefined(); + expect(getParsedStyle(text, 'visibility')).toBeUndefined(); + expect(getParsedStyle(text, 'fontWeight')).toBeUndefined(); + expect(getParsedStyle(text, 'fontStyle')).toBeUndefined(); + expect(getParsedStyle(text, 'fontVariant')).toBeUndefined(); + expect(getParsedStyle(text, 'textAlign')).toBeUndefined(); + expect(getParsedStyle(text, 'textBaseline')).toBeUndefined(); await canvas.ready; /** @@ -675,21 +673,20 @@ describe('StyleValueRegistry initialization', () => { */ canvas.appendChild(text); - parsedStyle = text.parsedStyle; // inherit from document.documentElement - expect(parsedStyle.fillOpacity).toBe(1); - expect(parsedStyle.strokeOpacity).toBe(1); - expect(parsedStyle.lineCap).toBe('butt'); - expect(parsedStyle.lineJoin).toBe('miter'); - expect(parsedStyle.visibility).toBe('visible'); - expect(parsedStyle.text).toBe('hello'); - expect(parsedStyle.fontFamily).toBe('PingFang SC'); - expect(parsedStyle.fontSize).toBe(16); - expect(parsedStyle.fontWeight).toBe('normal'); - expect(parsedStyle.fontVariant).toBe('normal'); - expect(parsedStyle.fontStyle).toBe('normal'); - expect(parsedStyle.textAlign).toBe('start'); - expect(parsedStyle.textBaseline).toBe('alphabetic'); - expect(parsedStyle.textTransform).toBe('none'); + expect(getParsedStyle(text, 'fillOpacity')).toBe(1); + expect(getParsedStyle(text, 'strokeOpacity')).toBe(1); + expect(getParsedStyle(text, 'lineCap')).toBe('butt'); + expect(getParsedStyle(text, 'lineJoin')).toBe('miter'); + expect(getParsedStyle(text, 'visibility')).toBe('visible'); + expect(getParsedStyle(text, 'text')).toBe('hello'); + expect(getParsedStyle(text, 'fontFamily')).toBe('PingFang SC'); + expect(getParsedStyle(text, 'fontSize')).toBe(16); + expect(getParsedStyle(text, 'fontWeight')).toBe('normal'); + expect(getParsedStyle(text, 'fontVariant')).toBe('normal'); + expect(getParsedStyle(text, 'fontStyle')).toBe('normal'); + expect(getParsedStyle(text, 'textAlign')).toBe('start'); + expect(getParsedStyle(text, 'textBaseline')).toBe('alphabetic'); + expect(getParsedStyle(text, 'textTransform')).toBe('none'); }); }); diff --git a/__tests__/unit/css/properties/length-percentage.spec.ts b/__tests__/unit/css/properties/length-percentage.spec.ts index 4e501bc56..74c4bf7b6 100644 --- a/__tests__/unit/css/properties/length-percentage.spec.ts +++ b/__tests__/unit/css/properties/length-percentage.spec.ts @@ -1,5 +1,5 @@ import { Renderer as CanvasRenderer } from '../../../../packages/g-svg/src'; -import { Canvas, Circle, CSS, CSSUnitValue } from '../../../../packages/g/src'; +import { Canvas, Circle, getParsedStyle } from '../../../../packages/g/src'; import { sleep } from '../../utils'; const $container = document.createElement('div'); @@ -52,23 +52,23 @@ describe('CSSPropertyLengthOrPercentage', () => { // computed = circle.computedStyleMap().get('cx') as CSSUnitValue; // expect(computed.equals(CSS.px(30))).toBeTruthy(); - circle.style.cx = '20px'; - expect(circle.getAttribute('cx')).toBe('20px'); + // circle.style.cx = '20px'; + // expect(circle.getAttribute('cx')).toBe('20px'); // computed = circle.computedStyleMap().get('cx') as CSSUnitValue; // expect(computed.equals(CSS.px(20))).toBeTruthy(); - circle.style.cx = '50%'; - expect(circle.getAttribute('cx')).toBe('50%'); + // circle.style.cx = '50%'; + // expect(circle.getAttribute('cx')).toBe('50%'); // computed = circle.computedStyleMap().get('cx') as CSSUnitValue; // expect(computed.equals(CSS.percent(50))).toBeTruthy(); - circle.style.cx = '0'; - expect(circle.getAttribute('cx')).toBe('0'); + circle.style.cx = 0; + expect(circle.getAttribute('cx')).toBe(0); // computed = circle.computedStyleMap().get('cx') as CSSUnitValue; // expect(computed.equals(CSS.px(0))).toBeTruthy(); - circle.style.cx = '0.2px'; - expect(circle.getAttribute('cx')).toBe('0.2px'); + // circle.style.cx = '0.2px'; + // expect(circle.getAttribute('cx')).toBe('0.2px'); // computed = circle.computedStyleMap().get('cx') as CSSUnitValue; // expect(computed.equals(CSS.px(0.2))).toBeTruthy(); @@ -76,11 +76,11 @@ describe('CSSPropertyLengthOrPercentage', () => { // computed = circle.computedStyleMap().get('cx') as CSSUnitValue; // expect(computed.equals(CSS.px(0.2))).toBeTruthy(); - circle.style.cx = null; - expect(circle.getAttribute('cx')).toBeNull(); + // circle.style.cx = null; + // expect(circle.getAttribute('cx')).toBeNull(); // computed = circle.computedStyleMap().get('cx') as CSSUnitValue; // expect(computed.toString()).toBe('unset'); - expect(circle.parsedStyle.cx).toBeNull(); + // expect(getParsedStyle(circle, 'cx')).toBeNull(); circle.animate( [ @@ -100,13 +100,13 @@ describe('CSSPropertyLengthOrPercentage', () => { // expect(circle.getAttribute('cx')).toBe('1em'); // // computed = circle.computedStyleMap().get('cx') as CSSUnitValue; // // expect(computed.equals(CSS.em(1))).toBeTruthy(); - // expect(circle.parsedStyle.cx).toBe(16); + // expect(getParsedStyle(circle, "cx")).toBe(16); // // rem // circle.style.cx = '2rem'; // expect(circle.getAttribute('cx')).toBe('2rem'); // // computed = circle.computedStyleMap().get('cx') as CSSUnitValue; // // expect(computed.equals(CSS.rem(2))).toBeTruthy(); - // expect(circle.parsedStyle.cx).toBe(32); + // expect(getParsedStyle(circle, "cx")).toBe(32); }); }); diff --git a/__tests__/unit/display-objects/circle.spec.ts b/__tests__/unit/display-objects/circle.spec.ts index 664e8994c..7790f7cb0 100644 --- a/__tests__/unit/display-objects/circle.spec.ts +++ b/__tests__/unit/display-objects/circle.spec.ts @@ -1,4 +1,4 @@ -import { Circle, CSS, CSSRGB } from '../../../packages/g/src'; +import { Circle, CSS, CSSRGB, getParsedStyle } from '../../../packages/g/src'; describe('Circle', () => { it("should calc Circle's GeometryBounds, RenderBounds, Bounds and LocalBounds correctly", () => { @@ -156,55 +156,57 @@ describe('Circle', () => { ]); // expect(circle.getAttribute('opacity')).toBe(''); - expect(circle.parsedStyle.opacity).toBeUndefined(); + expect(getParsedStyle(circle, 'opacity')).toBeUndefined(); // expect(circle.getAttribute('fillOpacity')).toBe(''); - expect(circle.parsedStyle.fillOpacity).toBeUndefined(); + expect(getParsedStyle(circle, 'fillOpacity')).toBeUndefined(); // expect(circle.getAttribute('strokeOpacity')).toBe(''); - expect(circle.parsedStyle.strokeOpacity).toBeUndefined(); + expect(getParsedStyle(circle, 'strokeOpacity')).toBeUndefined(); // expect(circle.getAttribute('fill')).toBe(''); - // expect(circle.parsedStyle.fill?.toString()).toStrictEqual( + // expect(getParsedStyle(circle, "fill")?.toString()).toStrictEqual( // new CSSRGB(0, 0, 0, 0, true).toString(), // ); // transparent // expect(circle.getAttribute('stroke')).toBe(''); - // expect(circle.parsedStyle.stroke?.toString()).toStrictEqual( + // expect(getParsedStyle(circle, "stroke")?.toString()).toStrictEqual( // new CSSRGB(0, 0, 0, 0, true).toString(), // ); // transparent // expect(circle.getAttribute('transform')).toBe(''); - // expect(circle.parsedStyle.transform).toStrictEqual([]); + // expect(getParsedStyle(circle, "transform")).toStrictEqual([]); // expect(circle.getAttribute('transformOrigin')).toBe(''); - // expect(circle.parsedStyle.transformOrigin).toStrictEqual([ + // expect(getParsedStyle(circle, "transformOrigin")).toStrictEqual([ // CSS.percent(50), // CSS.percent(50), // ]); // expect(circle.getAttribute('visibility')).toBe(''); - expect(circle.parsedStyle.visibility).toBeUndefined(); + expect(getParsedStyle(circle, 'visibility')).toBeUndefined(); // expect(circle.getAttribute('pointerEvents')).toBe(''); - expect(circle.parsedStyle.pointerEvents).toBeUndefined(); + expect(getParsedStyle(circle, 'pointerEvents')).toBeUndefined(); // expect(circle.getAttribute('lineWidth')).toBe(''); - expect(circle.parsedStyle.lineWidth).toBeUndefined(); + expect(getParsedStyle(circle, 'lineWidth')).toBeUndefined(); // expect(circle.getAttribute('lineJoin')).toBe(''); - expect(circle.parsedStyle.lineJoin).toBeUndefined(); + expect(getParsedStyle(circle, 'lineJoin')).toBeUndefined(); // expect(circle.getAttribute('lineCap')).toBe(''); - expect(circle.parsedStyle.lineCap).toBeUndefined(); + expect(getParsedStyle(circle, 'lineCap')).toBeUndefined(); // expect(circle.getAttribute('increasedLineWidthForHitTesting')).toBe(''); - expect(circle.parsedStyle.increasedLineWidthForHitTesting).toBeUndefined(); + expect( + getParsedStyle(circle, 'increasedLineWidthForHitTesting'), + ).toBeUndefined(); // @ts-ignore // expect(circle.getAttribute('fontSize')).toBe(''); // @ts-ignore - expect(circle.parsedStyle.fontSize).toBeUndefined(); + expect(getParsedStyle(circle, 'fontSize')).toBeUndefined(); // expect(circle.getAttribute('zIndex')).toBe(''); - // expect(circle.parsedStyle.zIndex).toBe(0); + // expect(getParsedStyle(circle, "zIndex")).toBe(0); // expect(circle.getAttribute('cx')).toBe(100); - expect(circle.parsedStyle.cx).toBe(100); + expect(getParsedStyle(circle, 'cx')).toBe(100); // expect(circle.getAttribute('cy')).toBe(100); - expect(circle.parsedStyle.cy).toBe(100); + expect(getParsedStyle(circle, 'cy')).toBe(100); // expect(circle.getAttribute('r')).toBe(100); - expect(circle.parsedStyle.r).toBe(100); + expect(getParsedStyle(circle, 'r')).toBe(100); // update fill circle.style.fill = 'red'; expect(circle.getAttribute('fill')).toBe('red'); - expect(circle.parsedStyle.fill?.toString()).toBe( + expect(getParsedStyle(circle, 'fill')?.toString()).toBe( new CSSRGB(255, 0, 0).toString(), ); // update transform @@ -221,43 +223,43 @@ describe('Circle', () => { }); // expect(circle.getAttribute('opacity')).toBe(''); - expect(circle.parsedStyle.opacity).toBeUndefined(); + expect(getParsedStyle(circle, 'opacity')).toBeUndefined(); // expect(circle.getAttribute('fillOpacity')).toBe(''); - expect(circle.parsedStyle.fillOpacity).toBeUndefined(); + expect(getParsedStyle(circle, 'fillOpacity')).toBeUndefined(); // expect(circle.getAttribute('strokeOpacity')).toBe(''); - expect(circle.parsedStyle.strokeOpacity).toBeUndefined(); + expect(getParsedStyle(circle, 'strokeOpacity')).toBeUndefined(); // expect(circle.getAttribute('fill')).toBe(''); - // expect(circle.parsedStyle.fill?.toString()).toBe( + // expect(getParsedStyle(circle, "fill")?.toString()).toBe( // new CSSRGB(0, 0, 0, 0, true).toString(), // ); // transparent // expect(circle.getAttribute('stroke')).toBe(''); - // expect(circle.parsedStyle.stroke?.toString()).toBe( + // expect(getParsedStyle(circle, "stroke")?.toString()).toBe( // new CSSRGB(0, 0, 0, 0, true).toString(), // ); // transparent // expect(circle.getAttribute('transform')).toBe(''); - // expect(circle.parsedStyle.transform).toStrictEqual([]); + // expect(getParsedStyle(circle, "transform")).toStrictEqual([]); // expect(circle.getAttribute('transformOrigin')).toBe(''); - // expect(circle.parsedStyle.transformOrigin).toStrictEqual([ + // expect(getParsedStyle(circle, "transformOrigin")).toStrictEqual([ // CSS.percent(50), // CSS.percent(50), // ]); // expect(circle.getAttribute('visibility')).toBe(''); - expect(circle.parsedStyle.visibility).toBeUndefined(); + expect(getParsedStyle(circle, 'visibility')).toBeUndefined(); // expect(circle.getAttribute('pointerEvents')).toBe(''); - expect(circle.parsedStyle.pointerEvents).toBeUndefined(); + expect(getParsedStyle(circle, 'pointerEvents')).toBeUndefined(); // expect(circle.getAttribute('lineWidth')).toBe(''); - expect(circle.parsedStyle.lineWidth).toBeUndefined(); + expect(getParsedStyle(circle, 'lineWidth')).toBeUndefined(); // expect(circle.getAttribute('lineJoin')).toBe(''); - expect(circle.parsedStyle.lineJoin).toBeUndefined(); + expect(getParsedStyle(circle, 'lineJoin')).toBeUndefined(); // expect(circle.getAttribute('lineCap')).toBe(''); - expect(circle.parsedStyle.lineCap).toBeUndefined(); + expect(getParsedStyle(circle, 'lineCap')).toBeUndefined(); // expect(circle.getAttribute('zIndex')).toBe(''); - // expect(circle.parsedStyle.zIndex).toBe(0); + // expect(getParsedStyle(circle, "zIndex")).toBe(0); // // expect(circle.getAttribute('cx')).toBe(''); - // expect(circle.parsedStyle.cx).toBe(0); + // expect(getParsedStyle(circle, "cx")).toBe(0); // // expect(circle.getAttribute('cy')).toBe(''); - // expect(circle.parsedStyle.cy).toBe(0); + // expect(getParsedStyle(circle, "cy")).toBe(0); // // expect(circle.getAttribute('r')).toBe(''); - // expect(circle.parsedStyle.r).toBe(0); + // expect(getParsedStyle(circle, "r")).toBe(0); }); }); diff --git a/__tests__/unit/display-objects/polygon.spec.ts b/__tests__/unit/display-objects/polygon.spec.ts index cc2082b68..f42a50ff5 100644 --- a/__tests__/unit/display-objects/polygon.spec.ts +++ b/__tests__/unit/display-objects/polygon.spec.ts @@ -39,12 +39,21 @@ describe('Polygon', () => { [0, 100], ]; + const s = circle.cloneNode(); + s.id = 'start'; + + const m = circle.cloneNode(); + m.className = 'middle'; + + const e = circle.cloneNode(); + e.id = 'end'; + const polygon = new Polygon({ style: { points, - markerStart: circle, - markerEnd: circle, - markerMid: circle, + markerStart: s, + markerMid: m, + markerEnd: e, }, }); expect(polygon.childNodes.length).toBe(5); diff --git a/__tests__/unit/display-objects/text.spec.ts b/__tests__/unit/display-objects/text.spec.ts index a2de47800..9fadb3a8d 100644 --- a/__tests__/unit/display-objects/text.spec.ts +++ b/__tests__/unit/display-objects/text.spec.ts @@ -1,6 +1,5 @@ -import { vec3 } from 'gl-matrix'; import { Renderer as CanvasRenderer } from '../../../packages/g-svg/src'; -import { Canvas, Text } from '../../../packages/g/src'; +import { Canvas, getParsedStyle, Text } from '../../../packages/g/src'; import { OffscreenCanvasContext } from '../offscreenCanvasContext'; const $container = document.createElement('div'); @@ -35,11 +34,11 @@ describe('Text', () => { it('should allow number as valid content', () => { const text = new Text({ style: { - text: 1, + text: '1', }, }); - expect(text.style.text).toBe(1); - expect(text.parsedStyle.text).toBe(1); + expect(text.style.text).toBe('1'); + expect(getParsedStyle(text, 'text')).toBe('1'); }); it('should calc global bounds correctly', () => { @@ -64,7 +63,7 @@ describe('Text', () => { // parse font size with unit // text.style.fontSize = '40px'; - // expect(text.parsedStyle.fontSize).toBe(40); + // expect(getParsedStyle(text, "fontSize")).toBe(40); // expect(text.nodeValue).toBe('这是测试文本This is text'); // expect(text.textContent).toBe('这是测试文本This is text'); diff --git a/packages/g-components/src/Sector.ts b/packages/g-components/src/Sector.ts index ef31e9ea4..05ae8a3a8 100644 --- a/packages/g-components/src/Sector.ts +++ b/packages/g-components/src/Sector.ts @@ -193,7 +193,8 @@ export class Sector extends CustomElement { } private updatePath() { - const { sx, sy, startAngle, endAngle, sr, sr0, sradius } = this.parsedStyle; + const { sx, sy, startAngle, endAngle, sr, sr0 } = this.attributes; + const { sradius } = this.parsedStyle; const path = this.createPath( sx, diff --git a/packages/g-components/src/Sector2.ts b/packages/g-components/src/Sector2.ts index 92f6aa98d..162535f22 100644 --- a/packages/g-components/src/Sector2.ts +++ b/packages/g-components/src/Sector2.ts @@ -151,7 +151,9 @@ export class Sector extends Path { private updatePath() { // @ts-ignore - const { x, y, startAngle, endAngle, sr, sr0, radius } = this.parsedStyle; + const { x, y, startAngle, endAngle, sr, sr0 } = this.attributes; + // @ts-ignore + const { radius } = this.parsedStyle; const path = this.createPath( x, diff --git a/packages/g-lite/src/css/StyleValueRegistry.ts b/packages/g-lite/src/css/StyleValueRegistry.ts index f1a6c70ce..8e108ef82 100644 --- a/packages/g-lite/src/css/StyleValueRegistry.ts +++ b/packages/g-lite/src/css/StyleValueRegistry.ts @@ -1,15 +1,11 @@ -import { isNil, isUndefined } from '@antv/util'; +import { isUndefined } from '@antv/util'; import { vec3 } from 'gl-matrix'; import type { DisplayObject } from '../display-objects'; import { EMPTY_PARSED_PATH } from '../display-objects/constants'; import type { GlobalRuntime } from '../global-runtime'; import { GeometryAABBUpdater } from '../services'; import { AABB } from '../shapes'; -import type { - BaseStyleProps, - ParsedBaseStyleProps, - Tuple3Number, -} from '../types'; +import type { BaseStyleProps, Tuple3Number } from '../types'; import { Shape } from '../types'; import type { CSSRGB } from './cssom'; import type { @@ -658,13 +654,13 @@ export class DefaultStyleValueRegistry implements StyleValueRegistry { memoize: true, }, ) { - Object.assign(object.attributes, attributes); - // clipPath - const oldClipPath = object.parsedStyle.clipPath; - const oldOffsetPath = object.parsedStyle.offsetPath; + const { clipPath: oldClipPath, offsetPath: oldOffsetPath } = + object.attributes; - Object.assign(object.parsedStyle, attributes); + Object.assign(object.attributes, attributes); + + // Object.assign(object.parsedStyle, attributes); let needUpdateGeometry = !!options.forceUpdateGeometry; @@ -675,21 +671,20 @@ export class DefaultStyleValueRegistry implements StyleValueRegistry { needUpdateGeometry = true; } - if (attributes.fill) { + if ('fill' in attributes) { object.parsedStyle.fill = parseColor(attributes.fill); } - if (attributes.stroke) { + if ('stroke' in attributes) { object.parsedStyle.stroke = parseColor(attributes.stroke); } - if (attributes.shadowColor) { + if ('shadowColor' in attributes) { object.parsedStyle.shadowColor = parseColor(attributes.shadowColor); } - if (attributes.filter) { + if ('filter' in attributes) { object.parsedStyle.filter = parseFilter(attributes.filter); } // Rect - // @ts-ignore - if (!isNil(attributes.radius)) { + if ('radius' in attributes) { // @ts-ignore object.parsedStyle.radius = parseDimensionArrayFormat( // @ts-ignore @@ -698,14 +693,13 @@ export class DefaultStyleValueRegistry implements StyleValueRegistry { ); } // Polyline - if (!isNil(attributes.lineDash)) { + if ('lineDash' in attributes) { object.parsedStyle.lineDash = parseDimensionArrayFormat( attributes.lineDash, 2, ); } - // @ts-ignore - if (attributes.points) { + if ('points' in attributes) { // @ts-ignore object.parsedStyle.points = parsePoints(attributes.points, object); } @@ -716,15 +710,12 @@ export class DefaultStyleValueRegistry implements StyleValueRegistry { ...EMPTY_PARSED_PATH, }; } - // @ts-ignore - if (attributes.d) { - object.parsedStyle.d = parsePath( - // @ts-ignore - attributes.d, - ); + if ('d' in attributes) { + // @ts-ignore + object.parsedStyle.d = parsePath(attributes.d); } // Text - if (attributes.textTransform) { + if ('textTransform' in attributes) { this.runtime.CSSPropertySyntaxFactory[ PropertySyntax.TEXT_TRANSFORM ].calculator( @@ -746,7 +737,7 @@ export class DefaultStyleValueRegistry implements StyleValueRegistry { this.runtime, ); } - if (attributes.offsetPath) { + if ('offsetPath' in attributes) { this.runtime.CSSPropertySyntaxFactory[ PropertySyntax.DEFINED_PATH ].calculator( @@ -757,17 +748,16 @@ export class DefaultStyleValueRegistry implements StyleValueRegistry { this.runtime, ); } - if (attributes.transform) { + if ('transform' in attributes) { object.parsedStyle.transform = parseTransform(attributes.transform); } - if (attributes.transformOrigin) { + if ('transformOrigin' in attributes) { object.parsedStyle.transformOrigin = parseTransformOrigin( attributes.transformOrigin, ); } // Marker - // @ts-ignore - if (attributes.markerStart) { + if ('markerStart' in attributes) { object.parsedStyle.markerStart = this.runtime.CSSPropertySyntaxFactory[ PropertySyntax.MARKER ].calculator( @@ -780,8 +770,7 @@ export class DefaultStyleValueRegistry implements StyleValueRegistry { null, ); } - // @ts-ignore - if (attributes.markerEnd) { + if ('markerEnd' in attributes) { object.parsedStyle.markerEnd = this.runtime.CSSPropertySyntaxFactory[ PropertySyntax.MARKER ].calculator( @@ -794,8 +783,7 @@ export class DefaultStyleValueRegistry implements StyleValueRegistry { null, ); } - // @ts-ignore - if (attributes.markerMid) { + if ('markerMid' in attributes) { object.parsedStyle.markerMid = this.runtime.CSSPropertySyntaxFactory[ PropertySyntax.MARKER ].calculator( @@ -809,22 +797,30 @@ export class DefaultStyleValueRegistry implements StyleValueRegistry { ); } - if (!isNil(attributes.zIndex)) { + if ('isClosed' in attributes) { + object.parsedStyle.isClosed = attributes.isClosed; + } + + if ('miterLimit' in attributes) { + object.parsedStyle.miterLimit = attributes.miterLimit; + } + + if ('zIndex' in attributes) { this.runtime.CSSPropertySyntaxFactory[ PropertySyntax.Z_INDEX ].postProcessor(object); } - if (!isNil(attributes.offsetDistance)) { + if ('offsetDistance' in attributes) { this.runtime.CSSPropertySyntaxFactory[ PropertySyntax.OFFSET_DISTANCE ].postProcessor(object); } - if (attributes.transform) { + if ('transform' in attributes) { this.runtime.CSSPropertySyntaxFactory[ PropertySyntax.TRANSFORM ].postProcessor(object); } - if (attributes.transformOrigin) { + if ('transformOrigin' in attributes) { this.runtime.CSSPropertySyntaxFactory[ PropertySyntax.TRANSFORM_ORIGIN ].postProcessor(object); @@ -858,7 +854,6 @@ export class DefaultStyleValueRegistry implements StyleValueRegistry { if (!geometry.renderBounds) { geometry.renderBounds = new AABB(); } - const parsedStyle = object.parsedStyle as ParsedBaseStyleProps; const { cx = 0, cy = 0, @@ -866,7 +861,7 @@ export class DefaultStyleValueRegistry implements StyleValueRegistry { hwidth = 0, hheight = 0, hdepth = 0, - } = geometryUpdater.update(parsedStyle, object); + } = geometryUpdater.update(object); // init with content box const halfExtents: Tuple3Number = [ Math.abs(hwidth), @@ -875,17 +870,16 @@ export class DefaultStyleValueRegistry implements StyleValueRegistry { ]; // anchor is center by default, don't account for lineWidth here const { - stroke, lineWidth = 1, - // lineCap, - // lineJoin, - // miterLimit, increasedLineWidthForHitTesting = 0, shadowType = 'outer', + } = object.attributes; + const { + stroke, shadowColor, filter = [], transformOrigin, - } = parsedStyle; + } = object.parsedStyle; const center: Tuple3Number = [cx, cy, cz]; // update geometry's AABB geometry.contentBounds.update(center, halfExtents); @@ -909,7 +903,7 @@ export class DefaultStyleValueRegistry implements StyleValueRegistry { // account for shadow, only support constant value now if (shadowColor && shadowType && shadowType !== 'inner') { const { min, max } = geometry.renderBounds; - const { shadowBlur, shadowOffsetX, shadowOffsetY } = parsedStyle; + const { shadowBlur, shadowOffsetX, shadowOffsetY } = object.attributes; const shadowBlurInPixels = shadowBlur || 0; const shadowOffsetXInPixels = shadowOffsetX || 0; const shadowOffsetYInPixels = shadowOffsetY || 0; diff --git a/packages/g-lite/src/css/parser/points.ts b/packages/g-lite/src/css/parser/points.ts index 059017b2e..32ac6cf65 100644 --- a/packages/g-lite/src/css/parser/points.ts +++ b/packages/g-lite/src/css/parser/points.ts @@ -8,9 +8,10 @@ import type { DisplayObject } from '../..'; * points="100,10 250,150 200,110" */ export function parsePoints( - pointsOrStr: string | [number, number][], + pointsOrStr?: string | [number, number][], object?: DisplayObject, ) { + if (!pointsOrStr) return undefined; let points: [number, number][]; if (isString(pointsOrStr)) { points = pointsOrStr.split(' ').map((pointStr) => { diff --git a/packages/g-lite/src/css/properties/CSSPropertyLengthOrPercentage.ts b/packages/g-lite/src/css/properties/CSSPropertyLengthOrPercentage.ts index e123d7499..6c5edc787 100644 --- a/packages/g-lite/src/css/properties/CSSPropertyLengthOrPercentage.ts +++ b/packages/g-lite/src/css/properties/CSSPropertyLengthOrPercentage.ts @@ -9,7 +9,7 @@ import { CSSUnitValue, UnitType } from '../cssom'; import { mergeNumbers } from '../parser'; function getFontSize(object: DisplayObject): number { - const { fontSize } = object.parsedStyle as ParsedTextStyleProps; + const { fontSize } = object.attributes as ParsedTextStyleProps; return isNil(fontSize) ? null : fontSize; } diff --git a/packages/g-lite/src/css/properties/CSSPropertyOffsetDistance.ts b/packages/g-lite/src/css/properties/CSSPropertyOffsetDistance.ts index 5b8bee674..8ffe1aae6 100644 --- a/packages/g-lite/src/css/properties/CSSPropertyOffsetDistance.ts +++ b/packages/g-lite/src/css/properties/CSSPropertyOffsetDistance.ts @@ -18,7 +18,7 @@ export class CSSPropertyOffsetDistance mixer = clampedMergeNumbers(0, 1); postProcessor(object: DisplayObject) { - const { offsetPath, offsetDistance } = object.parsedStyle; + const { offsetPath, offsetDistance } = object.attributes; if (!offsetPath) { return; } diff --git a/packages/g-lite/src/css/properties/CSSPropertyText.ts b/packages/g-lite/src/css/properties/CSSPropertyText.ts index 5c82296dc..efc0a44bd 100644 --- a/packages/g-lite/src/css/properties/CSSPropertyText.ts +++ b/packages/g-lite/src/css/properties/CSSPropertyText.ts @@ -23,6 +23,6 @@ export class CSSPropertyText } postProcessor(object: DisplayObject) { - object.nodeValue = `${object.parsedStyle.text}` || ''; + object.nodeValue = `${object.attributes.text}` || ''; } } diff --git a/packages/g-lite/src/display-objects/Circle.ts b/packages/g-lite/src/display-objects/Circle.ts index 884971fbb..dfcc295a8 100644 --- a/packages/g-lite/src/display-objects/Circle.ts +++ b/packages/g-lite/src/display-objects/Circle.ts @@ -7,19 +7,19 @@ export interface CircleStyleProps extends BaseStyleProps { /** * X coordinate of the center of the circle. */ - cx?: number | string | null; + cx?: number; /** * Y coordinate of the center of the circle. */ - cy?: number | string | null; + cy?: number; /** * Z coordinate of the center of the circle. */ - cz?: number | string | null; + cz?: number; /** * Radius of the circle. */ - r: number | string | null; + r: number; /** * Whether the circle is billboard. */ diff --git a/packages/g-lite/src/display-objects/DisplayObject.ts b/packages/g-lite/src/display-objects/DisplayObject.ts index 8d55d3cc8..bcba7e127 100644 --- a/packages/g-lite/src/display-objects/DisplayObject.ts +++ b/packages/g-lite/src/display-objects/DisplayObject.ts @@ -21,6 +21,7 @@ import { decompose, fromRotationTranslationScale, getEuler, + getParsedStyle, rad2deg, } from '../utils'; import type { CustomElement } from './CustomElement'; @@ -244,7 +245,7 @@ export class DisplayObject< const { renderable } = this; const oldValue = this.attributes[name]; - const oldParsedValue = this.parsedStyle[name as string]; + const oldParsedValue = this.parsedStyle[name as string] ?? oldValue; runtime.styleValueRegistry.processProperties( this, @@ -257,7 +258,7 @@ export class DisplayObject< // redraw at next frame renderable.dirty = true; - const newParsedValue = this.parsedStyle[name as string]; + const newParsedValue = getParsedStyle(this, name as any); if (this.isConnected) { mutationEvent.relatedNode = this as IElement; mutationEvent.prevValue = oldValue; @@ -553,7 +554,7 @@ export class DisplayObject< * shortcut for Used value of `visibility` */ isVisible() { - return this.parsedStyle?.visibility !== 'hidden'; + return this.attributes?.visibility !== 'hidden'; } get interactive() { @@ -564,7 +565,7 @@ export class DisplayObject< } isInteractive() { - return this.parsedStyle?.pointerEvents !== 'none'; + return this.attributes?.pointerEvents !== 'none'; } isCulled() { diff --git a/packages/g-lite/src/display-objects/Ellipse.ts b/packages/g-lite/src/display-objects/Ellipse.ts index ce92aebbd..2ba95f631 100644 --- a/packages/g-lite/src/display-objects/Ellipse.ts +++ b/packages/g-lite/src/display-objects/Ellipse.ts @@ -4,11 +4,11 @@ import { Shape } from '../types'; import { DisplayObject } from './DisplayObject'; export interface EllipseStyleProps extends BaseStyleProps { - cx?: number | string; - cy?: number | string; - cz?: number | string; - rx: number | string; - ry: number | string; + cx?: number; + cy?: number; + cz?: number; + rx: number; + ry: number; isBillboard?: boolean; isSizeAttenuation?: boolean; } diff --git a/packages/g-lite/src/display-objects/HTML.ts b/packages/g-lite/src/display-objects/HTML.ts index 3edaf0b26..ceb1f24fd 100644 --- a/packages/g-lite/src/display-objects/HTML.ts +++ b/packages/g-lite/src/display-objects/HTML.ts @@ -6,11 +6,11 @@ import { Shape } from '../types'; import { DisplayObject } from './DisplayObject'; export interface HTMLStyleProps extends BaseStyleProps { - x?: number | string; - y?: number | string; + x?: number; + y?: number; innerHTML: string | HTMLElement; - width?: number | string; - height?: number | string; + width?: number; + height?: number; } export interface ParsedHTMLStyleProps extends ParsedBaseStyleProps { diff --git a/packages/g-lite/src/display-objects/Image.ts b/packages/g-lite/src/display-objects/Image.ts index 8c7c494eb..d32cceedc 100644 --- a/packages/g-lite/src/display-objects/Image.ts +++ b/packages/g-lite/src/display-objects/Image.ts @@ -4,12 +4,12 @@ import { Shape } from '../types'; import { DisplayObject } from './DisplayObject'; export interface ImageStyleProps extends BaseStyleProps { - x?: number | string; - y?: number | string; + x?: number; + y?: number; z?: number; src?: string | HTMLImageElement; - width?: number | string; - height?: number | string; + width?: number; + height?: number; /** * Whether the circle is billboard. */ diff --git a/packages/g-lite/src/display-objects/Line.ts b/packages/g-lite/src/display-objects/Line.ts index c08d8f7ee..11f3915fa 100644 --- a/packages/g-lite/src/display-objects/Line.ts +++ b/packages/g-lite/src/display-objects/Line.ts @@ -159,16 +159,9 @@ export class Line extends DisplayObject { } private transformMarker(isStart: boolean) { - const { - markerStart, - markerEnd, - markerStartOffset, - markerEndOffset, - x1, - x2, - y1, - y2, - } = this.parsedStyle; + const { markerStartOffset, markerEndOffset, x1, x2, y1, y2 } = + this.attributes; + const { markerStart, markerEnd } = this.parsedStyle; const marker = isStart ? markerStart : markerEnd; if (!marker || !isDisplayObject(marker)) { @@ -210,7 +203,7 @@ export class Line extends DisplayObject { getPoint(ratio: number, inWorldSpace = false): Point { // TODO: account for z1/z2 in 3D line - const { x1, y1, x2, y2 } = this.parsedStyle; + const { x1, y1, x2, y2 } = this.attributes; const { x, y } = linePointAt(x1, y1, x2, y2, ratio); const transformed = vec3.transformMat4( @@ -229,7 +222,7 @@ export class Line extends DisplayObject { getTotalLength() { // TODO: account for z1/z2 in 3D line - const { x1, y1, x2, y2 } = this.parsedStyle; + const { x1, y1, x2, y2 } = this.attributes; return lineLength(x1, y1, x2, y2); } } diff --git a/packages/g-lite/src/display-objects/Path.ts b/packages/g-lite/src/display-objects/Path.ts index 46141eb02..4affc9d91 100644 --- a/packages/g-lite/src/display-objects/Path.ts +++ b/packages/g-lite/src/display-objects/Path.ts @@ -194,8 +194,8 @@ export class Path extends DisplayObject { } private transformMarker(isStart: boolean) { - const { markerStart, markerEnd, markerStartOffset, markerEndOffset } = - this.parsedStyle; + const { markerStartOffset, markerEndOffset } = this.attributes; + const { markerStart, markerEnd } = this.parsedStyle; const marker = isStart ? markerStart : markerEnd; if (!marker || !isDisplayObject(marker)) { diff --git a/packages/g-lite/src/display-objects/Polygon.ts b/packages/g-lite/src/display-objects/Polygon.ts index dda42b4c0..d2da9ca25 100644 --- a/packages/g-lite/src/display-objects/Polygon.ts +++ b/packages/g-lite/src/display-objects/Polygon.ts @@ -141,13 +141,8 @@ export class Polygon extends DisplayObject< } private transformMarker(isStart: boolean) { - const { - markerStart, - markerEnd, - markerStartOffset, - markerEndOffset, - points: P, - } = this.parsedStyle; + const { markerStartOffset, markerEndOffset } = this.attributes; + const { markerStart, markerEnd, points: P, isClosed } = this.parsedStyle; const { points } = P || {}; const marker = isStart ? markerStart : markerEnd; @@ -174,7 +169,7 @@ export class Polygon extends DisplayObject< } else { const { length } = points; - if (!this.parsedStyle.isClosed) { + if (!isClosed) { ox = points[length - 1][0]; oy = points[length - 1][1]; x = points[length - 2][0] - points[length - 1][0]; @@ -197,7 +192,7 @@ export class Polygon extends DisplayObject< } private placeMarkerMid(marker: DisplayObject) { - const { points: P } = this.parsedStyle; + const { isClosed, points: P } = this.parsedStyle; const { points } = P || {}; // clear all existed markers @@ -207,11 +202,7 @@ export class Polygon extends DisplayObject< this.markerMidList = []; if (marker && isDisplayObject(marker) && points) { - for ( - let i = 1; - i < (this.parsedStyle.isClosed ? points.length : points.length - 1); - i++ - ) { + for (let i = 1; i < (isClosed ? points.length : points.length - 1); i++) { const ox = points[i][0]; const oy = points[i][1]; diff --git a/packages/g-lite/src/display-objects/Rect.ts b/packages/g-lite/src/display-objects/Rect.ts index 1bec77bec..4d605c22a 100644 --- a/packages/g-lite/src/display-objects/Rect.ts +++ b/packages/g-lite/src/display-objects/Rect.ts @@ -4,11 +4,11 @@ import { Shape } from '../types'; import { DisplayObject } from './DisplayObject'; export interface RectStyleProps extends BaseStyleProps { - x?: number | string; - y?: number | string; + x?: number; + y?: number; z?: number; - width: number | string; - height: number | string; + width: number; + height: number; isBillboard?: boolean; isSizeAttenuation?: boolean; /** diff --git a/packages/g-lite/src/display-objects/Text.ts b/packages/g-lite/src/display-objects/Text.ts index 2255d6b89..6110f45b4 100644 --- a/packages/g-lite/src/display-objects/Text.ts +++ b/packages/g-lite/src/display-objects/Text.ts @@ -13,9 +13,9 @@ import { DisplayObject } from './DisplayObject'; import type { Path } from './Path'; export interface TextStyleProps extends BaseStyleProps { - x?: number | string; - y?: number | string; - z?: number | string; + x?: number; + y?: number; + z?: number; /** * Always face the camera. @@ -32,7 +32,7 @@ export interface TextStyleProps extends BaseStyleProps { */ isSizeAttenuation?: boolean; - text: number | string; + text: string; /** * The text-align property sets the horizontal alignment of the inline-level content. @@ -87,7 +87,7 @@ export interface TextStyleProps extends BaseStyleProps { * The startOffset attribute defines an offset from the start of the path for the initial current text position along the path after converting the path to the \ element's coordinate system. * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/startOffset */ - textPathStartOffset?: number | string; + textPathStartOffset?: number; /** * @see https://developer.mozilla.org/en-US/docs/Web/CSS/text-decoration-line @@ -114,7 +114,7 @@ export interface TextStyleProps extends BaseStyleProps { * The font-size property sets the size of the font. * @see https://developer.mozilla.org/en-US/docs/Web/CSS/font-size */ - fontSize?: number | string; + fontSize?: number; /** * The font-family property specifies a prioritized list of one or more font family names and/or generic family names for the selected element. @@ -144,13 +144,13 @@ export interface TextStyleProps extends BaseStyleProps { * The line-height property sets the height of a line box. * @see https://developer.mozilla.org/en-US/docs/Web/CSS/line-height */ - lineHeight?: number | string; + lineHeight?: number; /** * It specifies the spacing between letters when drawing text. * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/letterSpacing */ - letterSpacing?: number | string; + letterSpacing?: number; /** * The white-space property sets how white space inside an element is handled. @@ -185,13 +185,13 @@ export interface TextStyleProps extends BaseStyleProps { * The dx attribute indicates a shift along the x-axis on the position of an element or its content. * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/dx */ - dx?: number | string; + dx?: number; /** * The dy attribute indicates a shift along the y-axis on the position of an element or its content. * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/dy */ - dy?: number | string; + dy?: number; } export interface ParsedTextStyleProps extends ParsedBaseStyleProps { x: number; diff --git a/packages/g-lite/src/dom/Document.ts b/packages/g-lite/src/dom/Document.ts index e1883aa66..8df771666 100644 --- a/packages/g-lite/src/dom/Document.ts +++ b/packages/g-lite/src/dom/Document.ts @@ -150,7 +150,7 @@ export class Document extends Node implements IDocument { const hitTestList: DisplayObject[] = []; rBushNodes.forEach(({ displayObject }) => { const { pointerEvents = 'auto' } = - displayObject.parsedStyle as ParsedBaseStyleProps; + displayObject.attributes as ParsedBaseStyleProps; // account for `visibility` // @see https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events diff --git a/packages/g-lite/src/dom/Element.ts b/packages/g-lite/src/dom/Element.ts index 2f1338ea7..82b3ba693 100644 --- a/packages/g-lite/src/dom/Element.ts +++ b/packages/g-lite/src/dom/Element.ts @@ -518,26 +518,7 @@ export class Element< /** * Renderers will use these used values. */ - parsedStyle: ParsedStyleProps = { - // opacity: '', - // fillOpacity: '', - // strokeOpacity: '', - // transformOrigin: '', - // visibility: '', - // pointerEvents: '', - // lineWidth: '', - // lineCap: '', - // lineJoin: '', - // increasedLineWidthForHitTesting: '', - // fontSize: '', - // fontFamily: '', - // fontStyle: '', - // fontWeight: '', - // fontVariant: '', - // textAlign: '', - // textBaseline: '', - // textTransform: '', - } as ParsedStyleProps; + parsedStyle: ParsedStyleProps = {} as ParsedStyleProps; /** * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/computedStyleMap diff --git a/packages/g-lite/src/global-runtime.ts b/packages/g-lite/src/global-runtime.ts index dfc8cd13c..5c01fc644 100644 --- a/packages/g-lite/src/global-runtime.ts +++ b/packages/g-lite/src/global-runtime.ts @@ -58,7 +58,7 @@ export interface GlobalRuntime { sceneGraphSelector: SceneGraphSelector; sceneGraphService: SceneGraphService; textService: TextService; - geometryUpdaterFactory: Record>; + geometryUpdaterFactory: Record; styleValueRegistry: DefaultStyleValueRegistry; layoutRegistry: LayoutRegistry; CSSPropertySyntaxFactory: Record< @@ -78,7 +78,7 @@ export interface GlobalRuntime { /** * Replace with IoC container */ -const geometryUpdaterFactory: Record> = (() => { +const geometryUpdaterFactory: Record = (() => { const rectUpdater = new RectUpdater(); const polylineUpdater = new PolylineUpdater(); return { @@ -94,6 +94,7 @@ const geometryUpdaterFactory: Record> = (() => { [Shape.PATH]: new PathUpdater(), [Shape.HTML]: new HTMLUpdater(), [Shape.MESH]: null, + [Shape.FRAGMENT]: null, }; })(); diff --git a/packages/g-lite/src/index.ts b/packages/g-lite/src/index.ts index 24a16614b..5fe61544b 100644 --- a/packages/g-lite/src/index.ts +++ b/packages/g-lite/src/index.ts @@ -65,5 +65,6 @@ export { setDOMSize, translatePathToString, turn2deg, + getParsedStyle, } from './utils'; export { RBush }; diff --git a/packages/g-lite/src/services/SceneGraphService.ts b/packages/g-lite/src/services/SceneGraphService.ts index e77017f49..4509c5e6f 100644 --- a/packages/g-lite/src/services/SceneGraphService.ts +++ b/packages/g-lite/src/services/SceneGraphService.ts @@ -964,7 +964,7 @@ export class DefaultSceneGraphService implements SceneGraphService { const clipped = findClosestClipPathTarget(element as DisplayObject); if (clipped) { // use bounds under world space - const clipPathBounds = clipped.parsedStyle.clipPath.getBounds(render); + const clipPathBounds = clipped.attributes.clipPath.getBounds(render); if (!aabb) { aabb.update(clipPathBounds.center, clipPathBounds.halfExtents); } else if (clipPathBounds) { diff --git a/packages/g-lite/src/services/TextService.ts b/packages/g-lite/src/services/TextService.ts index a63bfd3ee..5d752224b 100644 --- a/packages/g-lite/src/services/TextService.ts +++ b/packages/g-lite/src/services/TextService.ts @@ -1,5 +1,5 @@ import { CanvasLike, GlobalRuntime } from '..'; -import type { ParsedTextStyleProps } from '../display-objects'; +import type { Text } from '../display-objects'; import { Rectangle } from '../shapes'; import { toFontString } from '../utils'; @@ -74,6 +74,10 @@ const regexCannotEnd = new RegExp( `${regexCannotEndZhCn.source}|${regexCannotEndZhTw.source}|${regexCannotEndJaJp.source}|${regexCannotEndKoKr.source}`, ); +const getTextOf = (object: Text) => { + return object.parsedStyle.text || object.attributes.text || ''; +}; + /** * Borrow from pixi/packages/text/src/TextMetrics.ts */ @@ -171,11 +175,8 @@ export class TextService { return properties; } - measureText( - text: string, - parsedStyle: ParsedTextStyleProps, - offscreenCanvas: CanvasLike, - ): TextMetrics { + measureText(object: Text, offscreenCanvas: CanvasLike): TextMetrics { + const text = getTextOf(object); const { fontSize = 16, wordWrap = false, @@ -187,12 +188,10 @@ export class TextService { textPath, textPathSide, textPathStartOffset, - // dropShadow = 0, - // dropShadowDistance = 0, leading = 0, - } = parsedStyle; + } = object.attributes; - const font = toFontString(parsedStyle); + const font = toFontString(object.attributes); const fontProperties = this.measureFont(font, offscreenCanvas); // fallback in case UA disallow canvas data extraction @@ -206,10 +205,8 @@ export class TextService { context.font = font; // no overflowing by default - parsedStyle.isOverflowing = false; - const outputText = wordWrap - ? this.wordWrap(text, parsedStyle, offscreenCanvas) - : text; + object.parsedStyle.isOverflowing = false; + const outputText = wordWrap ? this.wordWrap(object, offscreenCanvas) : text; const lines = outputText.split(/(?:\r\n|\r|\n)/); const lineWidths = new Array(lines.length); @@ -335,17 +332,15 @@ export class TextService { private setGraphemeOnPath() {} - private wordWrap( - text: string, - parsedStyle: ParsedTextStyleProps, - offscreenCanvas: CanvasLike, - ): string { + private wordWrap(object: Text, offscreenCanvas: CanvasLike): string { + const text = getTextOf(object); const { wordWrapWidth = 0, letterSpacing = 0, maxLines = Infinity, textOverflow, - } = parsedStyle; + } = object.attributes; + const parsedStyle = object.parsedStyle; const context = this.runtime.offscreenCanvasCreator.getOrCreateContext(offscreenCanvas); const maxWidth = wordWrapWidth + letterSpacing; diff --git a/packages/g-lite/src/services/aabb/CircleUpdater.ts b/packages/g-lite/src/services/aabb/CircleUpdater.ts index 09ec24268..66b53357d 100644 --- a/packages/g-lite/src/services/aabb/CircleUpdater.ts +++ b/packages/g-lite/src/services/aabb/CircleUpdater.ts @@ -1,14 +1,9 @@ -import type { - Circle, - ParsedCircleStyleProps, -} from '../../display-objects/Circle'; +import type { Circle } from '../../display-objects/Circle'; import type { GeometryAABBUpdater } from './interfaces'; -export class CircleUpdater - implements GeometryAABBUpdater -{ - update(parsedStyle: ParsedCircleStyleProps, object: Circle) { - const { cx = 0, cy = 0, r = 0 } = parsedStyle; +export class CircleUpdater implements GeometryAABBUpdater { + update(object: Circle) { + const { cx = 0, cy = 0, r = 0 } = object.attributes; return { cx, diff --git a/packages/g-lite/src/services/aabb/EllipseUpdater.ts b/packages/g-lite/src/services/aabb/EllipseUpdater.ts index 94a8d058e..ea4c9753d 100644 --- a/packages/g-lite/src/services/aabb/EllipseUpdater.ts +++ b/packages/g-lite/src/services/aabb/EllipseUpdater.ts @@ -1,14 +1,9 @@ -import type { - Ellipse, - ParsedEllipseStyleProps, -} from '../../display-objects/Ellipse'; +import type { Ellipse } from '../../display-objects/Ellipse'; import type { GeometryAABBUpdater } from './interfaces'; -export class EllipseUpdater - implements GeometryAABBUpdater -{ - update(parsedStyle: ParsedEllipseStyleProps, object: Ellipse) { - const { cx = 0, cy = 0, rx = 0, ry = 0 } = parsedStyle; +export class EllipseUpdater implements GeometryAABBUpdater { + update(object: Ellipse) { + const { cx = 0, cy = 0, rx = 0, ry = 0 } = object.attributes; return { cx, diff --git a/packages/g-lite/src/services/aabb/GroupUpdater.ts b/packages/g-lite/src/services/aabb/GroupUpdater.ts index 4e1342577..91ad7dbf3 100644 --- a/packages/g-lite/src/services/aabb/GroupUpdater.ts +++ b/packages/g-lite/src/services/aabb/GroupUpdater.ts @@ -1,10 +1,8 @@ -import type { Group, ParsedImageStyleProps } from '../../display-objects'; +import type { Group } from '../../display-objects'; import type { GeometryAABBUpdater } from './interfaces'; -export class GroupUpdater - implements GeometryAABBUpdater -{ - update(parsedStyle: ParsedImageStyleProps, object: Group) { +export class GroupUpdater implements GeometryAABBUpdater { + update(object: Group) { return { cx: 0, cy: 0, diff --git a/packages/g-lite/src/services/aabb/HTMLUpdater.ts b/packages/g-lite/src/services/aabb/HTMLUpdater.ts index 755bd7eb5..914e4c661 100644 --- a/packages/g-lite/src/services/aabb/HTMLUpdater.ts +++ b/packages/g-lite/src/services/aabb/HTMLUpdater.ts @@ -1,9 +1,9 @@ -import type { HTML, ParsedHTMLStyleProps } from '../../display-objects/HTML'; +import type { HTML } from '../../display-objects/HTML'; import type { GeometryAABBUpdater } from './interfaces'; -export class HTMLUpdater implements GeometryAABBUpdater { - update(parsedStyle: ParsedHTMLStyleProps, object: HTML) { - const { x = 0, y = 0, width = 0, height = 0 } = parsedStyle; +export class HTMLUpdater implements GeometryAABBUpdater { + update(object: HTML) { + const { x = 0, y = 0, width = 0, height = 0 } = object.attributes; return { cx: x + width / 2, diff --git a/packages/g-lite/src/services/aabb/LineUpdater.ts b/packages/g-lite/src/services/aabb/LineUpdater.ts index 7a02cd756..5ce529640 100644 --- a/packages/g-lite/src/services/aabb/LineUpdater.ts +++ b/packages/g-lite/src/services/aabb/LineUpdater.ts @@ -1,9 +1,9 @@ -import type { ParsedLineStyleProps } from '../../display-objects/Line'; +import type { Line } from '../../display-objects/Line'; import type { GeometryAABBUpdater } from './interfaces'; -export class LineUpdater implements GeometryAABBUpdater { - update(parsedStyle: ParsedLineStyleProps) { - const { x1, y1, x2, y2 } = parsedStyle; +export class LineUpdater implements GeometryAABBUpdater { + update(object: Line) { + const { x1, y1, x2, y2 } = object.attributes; const minX = Math.min(x1, x2); const maxX = Math.max(x1, x2); diff --git a/packages/g-lite/src/services/aabb/PathUpdater.ts b/packages/g-lite/src/services/aabb/PathUpdater.ts index a06f16be6..2cbb16eaf 100644 --- a/packages/g-lite/src/services/aabb/PathUpdater.ts +++ b/packages/g-lite/src/services/aabb/PathUpdater.ts @@ -1,9 +1,9 @@ -import type { ParsedPathStyleProps } from '../../display-objects'; +import type { Path } from '../../display-objects'; import type { GeometryAABBUpdater } from './interfaces'; -export class PathUpdater implements GeometryAABBUpdater { - update(parsedStyle: ParsedPathStyleProps) { - const { d } = parsedStyle; +export class PathUpdater implements GeometryAABBUpdater { + update(object: Path) { + const { d } = object.parsedStyle; const { x, y, width, height } = d.rect; const hwidth = width / 2; diff --git a/packages/g-lite/src/services/aabb/PolylineUpdater.ts b/packages/g-lite/src/services/aabb/PolylineUpdater.ts index beba68c0b..1b6e1841e 100644 --- a/packages/g-lite/src/services/aabb/PolylineUpdater.ts +++ b/packages/g-lite/src/services/aabb/PolylineUpdater.ts @@ -1,14 +1,11 @@ import { isArray } from '@antv/util'; -import type { ParsedPolylineStyleProps } from '../../display-objects'; +import type { Polyline } from '../../display-objects'; import type { GeometryAABBUpdater } from './interfaces'; -export class PolylineUpdater - implements GeometryAABBUpdater -{ - update(parsedStyle: ParsedPolylineStyleProps) { - if (parsedStyle.points && isArray(parsedStyle.points.points)) { - const { points } = parsedStyle.points; - +export class PolylineUpdater implements GeometryAABBUpdater { + update(object: Polyline) { + const points = object.parsedStyle?.points?.points; + if (points && isArray(points)) { // FIXME: account for miter lineJoin const minX = Math.min(...points.map((point) => point[0])); const maxX = Math.max(...points.map((point) => point[0])); diff --git a/packages/g-lite/src/services/aabb/RectUpdater.ts b/packages/g-lite/src/services/aabb/RectUpdater.ts index eb8934867..c7c46448b 100644 --- a/packages/g-lite/src/services/aabb/RectUpdater.ts +++ b/packages/g-lite/src/services/aabb/RectUpdater.ts @@ -7,9 +7,10 @@ import type { } from '../../display-objects'; import type { GeometryAABBUpdater } from './interfaces'; -export class RectUpdater implements GeometryAABBUpdater { - update(parsedStyle: ParsedImageStyleProps, object: Image | Rect | Group) { - const { x = 0, y = 0, src, width = 0, height = 0 } = parsedStyle; +export class RectUpdater implements GeometryAABBUpdater { + update(object: Image | Rect | Group) { + const { x = 0, y = 0, src, width = 0, height = 0 } = object.attributes; + const parsedStyle = object.parsedStyle as ParsedImageStyleProps; let contentWidth = width; let contentHeight = height; diff --git a/packages/g-lite/src/services/aabb/TextUpdater.ts b/packages/g-lite/src/services/aabb/TextUpdater.ts index 6e5186193..ca25a89d2 100644 --- a/packages/g-lite/src/services/aabb/TextUpdater.ts +++ b/packages/g-lite/src/services/aabb/TextUpdater.ts @@ -1,25 +1,17 @@ -import type { - DisplayObject, - ParsedTextStyleProps, -} from '../../display-objects'; +import type { DisplayObject, Text } from '../../display-objects'; import { GlobalRuntime } from '../../global-runtime'; +import { getParsedStyle } from '../../utils/style'; import type { GeometryAABBUpdater } from './interfaces'; -export class TextUpdater implements GeometryAABBUpdater { +export class TextUpdater implements GeometryAABBUpdater { constructor(private globalRuntime: GlobalRuntime) {} - private isReadyToMeasure( - parsedStyle: ParsedTextStyleProps, - object: DisplayObject, - ) { - const { text } = parsedStyle; - - return text; + private isReadyToMeasure(object: DisplayObject) { + return getParsedStyle(object, 'text'); } - update(parsedStyle: ParsedTextStyleProps, object: DisplayObject) { + update(object: Text) { const { - text, textAlign = 'start', lineWidth = 1, textBaseline = 'alphabetic', @@ -27,10 +19,10 @@ export class TextUpdater implements GeometryAABBUpdater { dy = 0, x = 0, y = 0, - } = parsedStyle; + } = object.attributes; - if (!this.isReadyToMeasure(parsedStyle, object)) { - parsedStyle.metrics = { + if (!this.isReadyToMeasure(object)) { + object.parsedStyle.metrics = { font: '', width: 0, height: 0, @@ -56,11 +48,10 @@ export class TextUpdater implements GeometryAABBUpdater { const { offscreenCanvas } = object?.ownerDocument?.defaultView?.getConfig() || {}; const metrics = this.globalRuntime.textService.measureText( - text, - parsedStyle, + object, offscreenCanvas, ); - parsedStyle.metrics = metrics; + object.parsedStyle.metrics = metrics; const { width, height } = metrics; diff --git a/packages/g-lite/src/services/aabb/interfaces.ts b/packages/g-lite/src/services/aabb/interfaces.ts index 8a5a21663..72a0c7723 100644 --- a/packages/g-lite/src/services/aabb/interfaces.ts +++ b/packages/g-lite/src/services/aabb/interfaces.ts @@ -1,11 +1,7 @@ import type { DisplayObject } from '../../display-objects/DisplayObject'; -import type { ParsedBaseStyleProps } from '../../types'; -export interface GeometryAABBUpdater { - update: ( - parsedStyle: T, - object: DisplayObject, - ) => { +export interface GeometryAABBUpdater { + update: (object: DisplayObject) => { cx: number; cy: number; cz?: number; diff --git a/packages/g-lite/src/types.ts b/packages/g-lite/src/types.ts index f323e51e5..ff306e7cb 100644 --- a/packages/g-lite/src/types.ts +++ b/packages/g-lite/src/types.ts @@ -186,11 +186,11 @@ export interface BaseStyleProps { stroke?: ColorType | Pattern; /** 描边透明度 */ - strokeOpacity?: number | string; + strokeOpacity?: number; /** 填充颜色 */ fill?: ColorType | Pattern; /** 填充透明度 */ - fillOpacity?: number | string; + fillOpacity?: number; /** * The fill-rule attribute is a presentation attribute defining the algorithm to use to determine the inside part of a shape. @@ -199,23 +199,23 @@ export interface BaseStyleProps { fillRule?: 'nonzero' | 'evenodd'; /** 整体透明度 */ - opacity?: number | string; + opacity?: number; /** * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-width */ - strokeWidth?: string | number; + strokeWidth?: number; /** * alias if strokeWidth * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineWidth */ - lineWidth?: string | number; + lineWidth?: number; /** * increased line width when hitting test */ - increasedLineWidthForHitTesting?: string | number; + increasedLineWidthForHitTesting?: number; /** * 交互区域 */ diff --git a/packages/g-lite/src/utils/dom.ts b/packages/g-lite/src/utils/dom.ts index 57e0f5e65..a6e106ad3 100644 --- a/packages/g-lite/src/utils/dom.ts +++ b/packages/g-lite/src/utils/dom.ts @@ -42,7 +42,7 @@ export function findClosestClipPathTarget( ): DisplayObject { let el = object; do { - const clipPath = el.parsedStyle?.clipPath; + const clipPath = el.attributes?.clipPath; if (clipPath) return el; el = el.parentElement as DisplayObject; } while (el !== null); diff --git a/packages/g-lite/src/utils/index.ts b/packages/g-lite/src/utils/index.ts index 4cfc7e307..aa063017a 100644 --- a/packages/g-lite/src/utils/index.ts +++ b/packages/g-lite/src/utils/index.ts @@ -13,3 +13,4 @@ export * from './raf'; export * from './tapable'; export * from './text'; export * from './transform-mat4'; +export * from './style'; diff --git a/packages/g-lite/src/utils/path.ts b/packages/g-lite/src/utils/path.ts index ec204cb80..3907187e9 100644 --- a/packages/g-lite/src/utils/path.ts +++ b/packages/g-lite/src/utils/path.ts @@ -882,21 +882,16 @@ export function convertToPath( let commands: AbsoluteArray = [] as unknown as AbsoluteArray; switch (object.nodeName) { case Shape.LINE: - const { x1 = 0, y1 = 0, x2 = 0, y2 = 0 } = (object as Line).parsedStyle; + const { x1 = 0, y1 = 0, x2 = 0, y2 = 0 } = (object as Line).attributes; commands = lineToCommands(x1, y1, x2, y2); break; case Shape.CIRCLE: { - const { r = 0, cx = 0, cy = 0 } = (object as Circle).parsedStyle; + const { r = 0, cx = 0, cy = 0 } = (object as Circle).attributes; commands = ellipseToCommands(r, r, cx, cy); break; } case Shape.ELLIPSE: { - const { - rx = 0, - ry = 0, - cx = 0, - cy = 0, - } = (object as Ellipse).parsedStyle; + const { rx = 0, ry = 0, cx = 0, cy = 0 } = (object as Ellipse).attributes; commands = ellipseToCommands(rx, ry, cx, cy); break; } @@ -914,8 +909,8 @@ export function convertToPath( height = 0, x = 0, y = 0, - radius, - } = (object as Rect).parsedStyle; + } = (object as Rect).attributes; + const { radius } = (object as Rect).parsedStyle; const hasRadius = radius && radius.some((r) => r !== 0); commands = rectToCommands( @@ -981,13 +976,17 @@ export function translatePathToString( : '' }`; case 'C': - return `C ${params[1]} ${params[2]},${params[3]} ${params[4]},${params[5]} ${params[6]}${ + return `C ${params[1]} ${params[2]},${params[3]} ${params[4]},${ + params[5] + } ${params[6]}${ useEndOffset ? ` L ${params[5] + endOffsetX},${params[6] + endOffsetY}` : '' }`; case 'A': - return `A ${params[1]} ${params[2]} ${params[3]} ${params[4]} ${params[5]} ${params[6]} ${params[7]}${ + return `A ${params[1]} ${params[2]} ${params[3]} ${params[4]} ${ + params[5] + } ${params[6]} ${params[7]}${ useEndOffset ? ` L ${params[6] + endOffsetX},${params[7] + endOffsetY}` : '' diff --git a/packages/g-lite/src/utils/style.ts b/packages/g-lite/src/utils/style.ts new file mode 100644 index 000000000..ae1d938f5 --- /dev/null +++ b/packages/g-lite/src/utils/style.ts @@ -0,0 +1,11 @@ +import { DisplayObject } from '../display-objects'; + +export function getParsedStyle< + T extends DisplayObject, + K extends keyof T['parsedStyle'], +>(object: T, key: K, defaultValue = undefined) { + return ( + ((object.parsedStyle[key] ?? + object.attributes[key]) as T['parsedStyle'][K]) ?? defaultValue + ); +} diff --git a/packages/g-lite/src/utils/text.ts b/packages/g-lite/src/utils/text.ts index ff7fbb2a2..f770cfe99 100644 --- a/packages/g-lite/src/utils/text.ts +++ b/packages/g-lite/src/utils/text.ts @@ -1,5 +1,5 @@ import { isNumber } from '@antv/util'; -import type { ParsedTextStyleProps } from '../display-objects/Text'; +import type { TextStyleProps } from '../display-objects/Text'; const genericFontFamilies = [ 'serif', @@ -11,7 +11,7 @@ const genericFontFamilies = [ ]; const stringRegExp = /([\"\'])[^\'\"]+\1/; -export function toFontString(attributes: Partial) { +export function toFontString(attributes: Partial) { const { fontSize = 16, fontFamily = 'sans-serif', diff --git a/packages/g-plugin-3d/src/lights/DirectionalLight.ts b/packages/g-plugin-3d/src/lights/DirectionalLight.ts index 10fe56088..7225feb11 100644 --- a/packages/g-plugin-3d/src/lights/DirectionalLight.ts +++ b/packages/g-plugin-3d/src/lights/DirectionalLight.ts @@ -33,7 +33,8 @@ export class DirectionalLight extends Light { } uploadUBO(uniforms: RenderInstUniform[], index: number) { - const { fill, direction, intensity } = this.parsedStyle; + const { fill, direction, intensity } = this + .attributes as DirectionalLightProps; if (isCSSRGB(fill)) { const fillColor = [ diff --git a/packages/g-plugin-a11y/src/TextExtractor.ts b/packages/g-plugin-a11y/src/TextExtractor.ts index 589a18604..493e90111 100644 --- a/packages/g-plugin-a11y/src/TextExtractor.ts +++ b/packages/g-plugin-a11y/src/TextExtractor.ts @@ -56,11 +56,11 @@ color: transparent !important; const $el = this.getOrCreateEl(text); switch (name) { case 'text': - const { text: textContent } = text.parsedStyle; + const { text: textContent } = text.attributes; $el.textContent = textContent; break; case 'visibility': - const { visibility } = text.parsedStyle; + const { visibility } = text.attributes; if (visibility === 'visible') { this.getOrCreateEl(text); } else { @@ -68,11 +68,11 @@ color: transparent !important; } break; case 'x': - const { x } = text.parsedStyle; + const { x } = text.attributes; $el.style.left = `${x}px`; break; case 'y': - const { y } = text.parsedStyle; + const { y } = text.attributes; $el.style.top = `${y}px`; break; case 'modelMatrix': @@ -81,13 +81,8 @@ color: transparent !important; case 'textBaseline': case 'dx': case 'dy': - const { - transformOrigin, - textAlign, - textBaseline, - dx = 0, - dy = 0, - } = text.parsedStyle; + const { textAlign, textBaseline, dx = 0, dy = 0 } = text.attributes; + const { transformOrigin } = text.parsedStyle; $el.style['transform-origin'] = `${ (transformOrigin && transformOrigin[0].value) || 0 } ${(transformOrigin && transformOrigin[1].value) || 0}`; @@ -114,11 +109,11 @@ color: transparent !important; $el.style.transform = `translate(${dx}px,${dy}px) translate(${offsetX},${offsetY}) matrix3d(${worldTransform.toString()})`; break; case 'fontSize': - const { fontSize = 0 } = text.parsedStyle; + const { fontSize = 0 } = text.attributes; $el.style.fontSize = `${fontSize}px`; break; case 'fontFamily': - const { fontFamily } = text.parsedStyle; + const { fontFamily } = text.attributes; $el.style.fontFamily = fontFamily; break; } diff --git a/packages/g-plugin-annotation/src/SelectablePlugin.ts b/packages/g-plugin-annotation/src/SelectablePlugin.ts index 55676c65b..cb0659851 100644 --- a/packages/g-plugin-annotation/src/SelectablePlugin.ts +++ b/packages/g-plugin-annotation/src/SelectablePlugin.ts @@ -588,8 +588,8 @@ export class SelectablePlugin implements RenderingPlugin { }); } else if (target.nodeName === Shape.ELLIPSE) { target.attr({ - cx: rect.x + target.parsedStyle.rx, - cy: rect.y + target.parsedStyle.ry, + cx: rect.x + target.attributes.rx, + cy: rect.y + target.attributes.ry, }); } else if (target.nodeName === Shape.LINE) { const [[x1, y1], [x2, y2]] = polyline.points; diff --git a/packages/g-plugin-annotation/src/rendering/drawPoint-render.ts b/packages/g-plugin-annotation/src/rendering/drawPoint-render.ts index 370dd4b2b..3360d28c8 100644 --- a/packages/g-plugin-annotation/src/rendering/drawPoint-render.ts +++ b/packages/g-plugin-annotation/src/rendering/drawPoint-render.ts @@ -42,7 +42,7 @@ export const renderDrawPoints = ( ? { fill: polylineActiveVertexFill, fillOpacity: polylineActiveVertexFillOpacity, - r: polylineActiveVertexSize as number, + r: polylineActiveVertexSize, stroke: polylineActiveVertexStroke, strokeOpacity: polylineActiveVertexStrokeOpacity, lineWidth: polylineActiveVertexStrokeWidth, @@ -50,7 +50,7 @@ export const renderDrawPoints = ( : { fill: polylineVertexFill, fillOpacity: polylineVertexFillOpacity, - r: polylineVertexSize as number, + r: polylineVertexSize, stroke: polylineVertexStroke, strokeOpacity: polylineVertexStrokeOpacity, lineWidth: polylineVertexStrokeWidth, diff --git a/packages/g-plugin-annotation/src/selectable/SelectableCircle.ts b/packages/g-plugin-annotation/src/selectable/SelectableCircle.ts index 586ff2698..27dbd8973 100644 --- a/packages/g-plugin-annotation/src/selectable/SelectableCircle.ts +++ b/packages/g-plugin-annotation/src/selectable/SelectableCircle.ts @@ -17,7 +17,7 @@ export class SelectableCircle extends AbstractSelectable { target, } = this.style; - const { cx, cy, r } = target.parsedStyle; + const { cx, cy, r } = target.attributes; const zoom = this.ownerDocument.defaultView.getCamera().getZoom(); this.mask = new Circle({ @@ -48,7 +48,7 @@ export class SelectableCircle extends AbstractSelectable { destroy(): void {} moveMask(dx: number, dy: number) { - const { cx, cy } = this.mask.parsedStyle; + const { cx, cy } = this.mask.attributes; this.mask.attr({ cx: cx + dx, cy: cy + dy, @@ -56,7 +56,7 @@ export class SelectableCircle extends AbstractSelectable { } triggerMovingEvent(dx: number, dy: number) { - const { cx, cy } = this.mask.parsedStyle; + const { cx, cy } = this.mask.attributes; this.style.target.dispatchEvent( new CustomEvent(SelectableEvent.MOVING, { movingX: dx + cx, @@ -68,7 +68,7 @@ export class SelectableCircle extends AbstractSelectable { } triggerMovedEvent() { - const { cx, cy } = this.mask.parsedStyle; + const { cx, cy } = this.mask.attributes; this.style.target.dispatchEvent( new CustomEvent(SelectableEvent.MOVED, { circle: { @@ -85,7 +85,7 @@ export class SelectableCircle extends AbstractSelectable { let shiftX = 0; let shiftY = 0; const moveAt = (canvasX: number, canvasY: number) => { - const { cx, cy } = this.mask.parsedStyle; + const { cx, cy } = this.mask.attributes; // account for multi-selection this.plugin.selected.forEach((selected) => { @@ -101,7 +101,7 @@ export class SelectableCircle extends AbstractSelectable { const target = e.target as DisplayObject; if (target === this.mask) { - const { cx, cy } = this.mask.parsedStyle; + const { cx, cy } = this.mask.attributes; shiftX = e.canvasX - cx; shiftY = e.canvasY - cy; diff --git a/packages/g-plugin-annotation/src/selectable/SelectableImage.ts b/packages/g-plugin-annotation/src/selectable/SelectableImage.ts index ba727526a..bfd2e8b5a 100644 --- a/packages/g-plugin-annotation/src/selectable/SelectableImage.ts +++ b/packages/g-plugin-annotation/src/selectable/SelectableImage.ts @@ -97,7 +97,7 @@ export class SelectableImage extends AbstractSelectable { lineWidth: anchorStrokeWidth, }, }); - const { x, y, width, height } = target.parsedStyle; + const { x, y, width, height } = target.attributes; this.tlAnchor.style.cx = x; this.tlAnchor.style.cy = y; @@ -152,8 +152,8 @@ export class SelectableImage extends AbstractSelectable { destroy(): void {} moveMask(dx: number, dy: number) { - const maskX = this.mask.parsedStyle.x + dx; - const maskY = this.mask.parsedStyle.y + dy; + const maskX = this.mask.attributes.x + dx; + const maskY = this.mask.attributes.y + dy; const maskWidth = Number(this.mask.style.width); const maskHeight = Number(this.mask.style.height); @@ -174,8 +174,8 @@ export class SelectableImage extends AbstractSelectable { } triggerMovingEvent(dx: number, dy: number) { - const maskX = this.mask.parsedStyle.x; - const maskY = this.mask.parsedStyle.y; + const maskX = this.mask.attributes.x; + const maskY = this.mask.attributes.y; this.style.target.dispatchEvent( new CustomEvent(SelectableEvent.MOVING, { movingX: maskX + dx, @@ -190,8 +190,8 @@ export class SelectableImage extends AbstractSelectable { this.style.target.dispatchEvent( new CustomEvent(SelectableEvent.MOVED, { rect: { - x: this.mask.parsedStyle.x, - y: this.mask.parsedStyle.y, + x: this.mask.attributes.x, + y: this.mask.attributes.y, }, }), ); @@ -211,7 +211,7 @@ export class SelectableImage extends AbstractSelectable { let shiftX = 0; let shiftY = 0; const moveAt = (canvasX: number, canvasY: number) => { - const { x, y } = this.mask.parsedStyle; + const { x, y } = this.mask.attributes; const dx = canvasX - shiftX - x; const dy = canvasY - shiftY - y; @@ -226,7 +226,7 @@ export class SelectableImage extends AbstractSelectable { const target = e.target as DisplayObject; if (target === this.mask) { - const { x, y } = this.mask.parsedStyle; + const { x, y } = this.mask.attributes; shiftX = e.canvasX - x; shiftY = e.canvasY - y; @@ -248,8 +248,8 @@ export class SelectableImage extends AbstractSelectable { const originMaskHeight = Number(this.mask.style.height); // position in canvas coordinates - const ox = this.mask.parsedStyle.x; - const oy = this.mask.parsedStyle.y; + const ox = this.mask.attributes.x; + const oy = this.mask.attributes.y; if (target === this.mask) { moveAt(canvasX, canvasY); diff --git a/packages/g-plugin-annotation/src/selectable/SelectablePolyline.ts b/packages/g-plugin-annotation/src/selectable/SelectablePolyline.ts index 7c2eceaf1..7068a9e50 100644 --- a/packages/g-plugin-annotation/src/selectable/SelectablePolyline.ts +++ b/packages/g-plugin-annotation/src/selectable/SelectablePolyline.ts @@ -23,7 +23,7 @@ export class SelectablePolyline extends AbstractSelectable { let points = []; if (target.nodeName === Shape.LINE) { - const { x1, y1, x2, y2 } = target.parsedStyle; + const { x1, y1, x2, y2 } = target.attributes; points.push([x1, y1]); points.push([x2, y2]); } else if (target.nodeName === Shape.POLYLINE) { diff --git a/packages/g-plugin-annotation/src/selectable/SelectableRect.ts b/packages/g-plugin-annotation/src/selectable/SelectableRect.ts index 5822823e1..7a4862f33 100644 --- a/packages/g-plugin-annotation/src/selectable/SelectableRect.ts +++ b/packages/g-plugin-annotation/src/selectable/SelectableRect.ts @@ -168,8 +168,8 @@ export class SelectableRect extends AbstractSelectable { destroy(): void {} moveMask(dx: number, dy: number) { - const maskX = this.mask.parsedStyle.x + dx; - const maskY = this.mask.parsedStyle.y + dy; + const maskX = this.mask.attributes.x + dx; + const maskY = this.mask.attributes.y + dy; const maskWidth = Number(this.mask.style.width); const maskHeight = Number(this.mask.style.height); @@ -188,8 +188,8 @@ export class SelectableRect extends AbstractSelectable { } triggerMovingEvent(dx: number, dy: number) { - const maskX = this.mask.parsedStyle.x; - const maskY = this.mask.parsedStyle.y; + const maskX = this.mask.attributes.x; + const maskY = this.mask.attributes.y; this.style.target.dispatchEvent( new CustomEvent(SelectableEvent.MOVING, { movingX: maskX + dx, @@ -204,8 +204,8 @@ export class SelectableRect extends AbstractSelectable { this.style.target.dispatchEvent( new CustomEvent(SelectableEvent.MOVED, { rect: { - x: this.mask.parsedStyle.x, - y: this.mask.parsedStyle.y, + x: this.mask.attributes.x, + y: this.mask.attributes.y, }, }), ); @@ -223,7 +223,7 @@ export class SelectableRect extends AbstractSelectable { let shiftX = 0; let shiftY = 0; const moveAt = (canvasX: number, canvasY: number) => { - const { x, y } = this.mask.parsedStyle; + const { x, y } = this.mask.attributes; const dx = canvasX - shiftX - x; const dy = canvasY - shiftY - y; @@ -238,7 +238,7 @@ export class SelectableRect extends AbstractSelectable { const target = e.target as DisplayObject; if (target === this.mask) { - const { x, y } = this.mask.parsedStyle; + const { x, y } = this.mask.attributes; shiftX = e.canvasX - x; shiftY = e.canvasY - y; @@ -260,8 +260,8 @@ export class SelectableRect extends AbstractSelectable { const originMaskHeight = Number(this.mask.style.height); // position in canvas coordinates - const ox = this.mask.parsedStyle.x; - const oy = this.mask.parsedStyle.y; + const ox = this.mask.attributes.x; + const oy = this.mask.attributes.y; // const angles = this.getEulerAngles(); if (target === this.mask) { diff --git a/packages/g-plugin-annotation/src/selectable/SelectableRectPolygon.ts b/packages/g-plugin-annotation/src/selectable/SelectableRectPolygon.ts index e9f597765..562942bca 100644 --- a/packages/g-plugin-annotation/src/selectable/SelectableRectPolygon.ts +++ b/packages/g-plugin-annotation/src/selectable/SelectableRectPolygon.ts @@ -356,7 +356,7 @@ export class SelectableRectPolygon extends AbstractSelectable { } else if (target === this.rotateAnchor) { const { x: ox, y: oy } = lineIntersect(tl, br, tr, bl); - const { cx: rx, cy: ry } = this.rotateAnchor.parsedStyle; + const { cx: rx, cy: ry } = this.rotateAnchor.attributes; const v1 = [rx - ox, ry - oy]; const v2 = [canvasX - ox, canvasY - oy]; // @see https://www.mathworks.com/matlabcentral/answers/180131-how-can-i-find-the-angle-between-two-vectors-including-directional-information diff --git a/packages/g-plugin-annotation/src/tokens.ts b/packages/g-plugin-annotation/src/tokens.ts index dd8e587a7..822954088 100644 --- a/packages/g-plugin-annotation/src/tokens.ts +++ b/packages/g-plugin-annotation/src/tokens.ts @@ -71,7 +71,7 @@ export interface SelectableStyle { */ anchorFill: string; anchorStroke: string; - anchorSize: string | number; + anchorSize: number; anchorFillOpacity: number; anchorStrokeOpacity: number; anchorStrokeWidth: number; @@ -81,7 +81,7 @@ export interface SelectableStyle { */ selectedAnchorFill: string; selectedAnchorStroke: string; - selectedAnchorSize: string | number; + selectedAnchorSize: number; selectedAnchorFillOpacity: number; selectedAnchorStrokeOpacity: number; selectedAnchorStrokeWidth: number; @@ -91,7 +91,7 @@ export interface SelectableStyle { */ midAnchorFill: string; midAnchorStroke: string; - midAnchorSize: string | number; + midAnchorSize: number; midAnchorFillOpacity: number; midAnchorStrokeOpacity: number; midAnchorStrokeWidth: number; diff --git a/packages/g-plugin-box2d/src/Box2DPlugin.ts b/packages/g-plugin-box2d/src/Box2DPlugin.ts index e87ae5ae9..1613b0d08 100644 --- a/packages/g-plugin-box2d/src/Box2DPlugin.ts +++ b/packages/g-plugin-box2d/src/Box2DPlugin.ts @@ -245,7 +245,7 @@ export class Box2DPlugin implements RenderingPlugin { b2BodyDef, b2_dynamicBody, } = this.Box2D; - const { nodeName, parsedStyle } = target; + const { nodeName, parsedStyle, attributes } = target; let shape: | Box2D.b2EdgeShape @@ -253,7 +253,7 @@ export class Box2DPlugin implements RenderingPlugin { | Box2D.b2PolygonShape | Box2D.b2ChainShape; if (nodeName === Shape.LINE) { - const { x1, y1, x2, y2 } = parsedStyle as ParsedLineStyleProps; + const { x1, y1, x2, y2 } = attributes as ParsedLineStyleProps; // @see https://box2d.org/documentation/md__d_1__git_hub_box2d_docs_collision.html#autotoc_md39 shape = new b2EdgeShape(); const points = sortPointsInCCW([ @@ -284,7 +284,7 @@ export class Box2DPlugin implements RenderingPlugin { // new b2Vec2(next[0] + eps, next[1] ), ); } else if (nodeName === Shape.RECT || nodeName === Shape.IMAGE) { - const { width, height } = parsedStyle as ParsedRectStyleProps; + const { width, height } = attributes as ParsedRectStyleProps; shape = new b2PolygonShape(); // @see https://box2d.org/documentation/classb2_polygon_shape.html#af80eb52027ffe85dd4d0a3110eae9d1b // @ts-ignore @@ -296,7 +296,7 @@ export class Box2DPlugin implements RenderingPlugin { ); } else if (nodeName === Shape.CIRCLE) { // @see https://box2d.org/documentation/md__d_1__git_hub_box2d_docs_collision.html#autotoc_md37 - const { r } = parsedStyle as ParsedCircleStyleProps; + const { r } = attributes as ParsedCircleStyleProps; shape = new b2CircleShape(); shape.set_m_radius(r); } else if (nodeName === Shape.ELLIPSE) { @@ -330,7 +330,7 @@ export class Box2DPlugin implements RenderingPlugin { bullet = false, friction, restitution, - } = target.parsedStyle; + } = target.attributes; if (rigid === 'static') { bodyDef = new b2BodyDef(); diff --git a/packages/g-plugin-canvas-path-generator/src/index.ts b/packages/g-plugin-canvas-path-generator/src/index.ts index a416bbd01..991c53b7e 100644 --- a/packages/g-plugin-canvas-path-generator/src/index.ts +++ b/packages/g-plugin-canvas-path-generator/src/index.ts @@ -26,6 +26,7 @@ export class Plugin extends AbstractRendererPlugin { [Shape.IMAGE]: undefined, [Shape.HTML]: undefined, [Shape.MESH]: undefined, + [Shape.FRAGMENT]: undefined, }; // @ts-ignore diff --git a/packages/g-plugin-canvas-path-generator/src/interfaces.ts b/packages/g-plugin-canvas-path-generator/src/interfaces.ts index 0565476a1..402ebc98f 100644 --- a/packages/g-plugin-canvas-path-generator/src/interfaces.ts +++ b/packages/g-plugin-canvas-path-generator/src/interfaces.ts @@ -1,9 +1,9 @@ -import type { ParsedBaseStyleProps } from '@antv/g-lite'; +import type { DisplayObject } from '@antv/g-lite'; /** * generate path in local space */ -export type PathGenerator = ( +export type PathGenerator = ( context: CanvasRenderingContext2D, - attributes: T, + object: T, ) => void; diff --git a/packages/g-plugin-canvas-path-generator/src/paths/Circle.ts b/packages/g-plugin-canvas-path-generator/src/paths/Circle.ts index 005d4200b..16b887c77 100644 --- a/packages/g-plugin-canvas-path-generator/src/paths/Circle.ts +++ b/packages/g-plugin-canvas-path-generator/src/paths/Circle.ts @@ -1,9 +1,9 @@ -import type { ParsedCircleStyleProps } from '@antv/g-lite'; +import type { Circle } from '@antv/g-lite'; export function generatePath( context: CanvasRenderingContext2D, - parsedStyle: ParsedCircleStyleProps, + circle: Circle, ) { - const { cx = 0, cy = 0, r } = parsedStyle; + const { cx = 0, cy = 0, r } = circle.attributes; context.arc(cx, cy, r, 0, Math.PI * 2, false); } diff --git a/packages/g-plugin-canvas-path-generator/src/paths/Ellipse.ts b/packages/g-plugin-canvas-path-generator/src/paths/Ellipse.ts index e8d6f6dd4..b5fd47ce1 100644 --- a/packages/g-plugin-canvas-path-generator/src/paths/Ellipse.ts +++ b/packages/g-plugin-canvas-path-generator/src/paths/Ellipse.ts @@ -1,10 +1,10 @@ -import type { ParsedEllipseStyleProps } from '@antv/g-lite'; +import type { Ellipse } from '@antv/g-lite'; export function generatePath( context: CanvasRenderingContext2D, - parsedStyle: ParsedEllipseStyleProps, + ellipse: Ellipse, ) { - const { cx = 0, cy = 0, rx, ry } = parsedStyle; + const { cx = 0, cy = 0, rx, ry } = ellipse.attributes; // @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/ellipse if (context.ellipse) { diff --git a/packages/g-plugin-canvas-path-generator/src/paths/Line.ts b/packages/g-plugin-canvas-path-generator/src/paths/Line.ts index ae23155fd..be0bbd1dd 100644 --- a/packages/g-plugin-canvas-path-generator/src/paths/Line.ts +++ b/packages/g-plugin-canvas-path-generator/src/paths/Line.ts @@ -1,20 +1,10 @@ -import type { ParsedLineStyleProps } from '@antv/g-lite'; +import type { Line } from '@antv/g-lite'; import { isDisplayObject } from '@antv/g-lite'; -export function generatePath( - context: CanvasRenderingContext2D, - parsedStyle: ParsedLineStyleProps, -) { - const { - x1, - y1, - x2, - y2, - markerStart, - markerEnd, - markerStartOffset, - markerEndOffset, - } = parsedStyle; +export function generatePath(context: CanvasRenderingContext2D, line: Line) { + const { x1, y1, x2, y2, markerStartOffset, markerEndOffset } = + line.attributes; + const { markerStart, markerEnd } = line.parsedStyle; let startOffsetX = 0; let startOffsetY = 0; diff --git a/packages/g-plugin-canvas-path-generator/src/paths/Path.ts b/packages/g-plugin-canvas-path-generator/src/paths/Path.ts index a5800a62c..f307d9586 100644 --- a/packages/g-plugin-canvas-path-generator/src/paths/Path.ts +++ b/packages/g-plugin-canvas-path-generator/src/paths/Path.ts @@ -1,13 +1,11 @@ -import type { ParsedPathStyleProps, Path } from '@antv/g-lite'; +import type { Path } from '@antv/g-lite'; import { isDisplayObject } from '@antv/g-lite'; -export function generatePath( - context: CanvasRenderingContext2D, - parsedStyle: ParsedPathStyleProps, -) { - const { markerStart, markerEnd, markerStartOffset, markerEndOffset } = - parsedStyle; - const { absolutePath, segments } = parsedStyle.d; +export function generatePath(context: CanvasRenderingContext2D, path: Path) { + const { markerStartOffset, markerEndOffset } = path.attributes; + const { d } = path.parsedStyle; + const { markerStart, markerEnd } = path.parsedStyle; + const { absolutePath, segments } = d; let startOffsetX = 0; let startOffsetY = 0; diff --git a/packages/g-plugin-canvas-path-generator/src/paths/Polygon.ts b/packages/g-plugin-canvas-path-generator/src/paths/Polygon.ts index 78581930c..d29e6a69d 100644 --- a/packages/g-plugin-canvas-path-generator/src/paths/Polygon.ts +++ b/packages/g-plugin-canvas-path-generator/src/paths/Polygon.ts @@ -1,13 +1,16 @@ -import type { ParsedPolygonStyleProps } from '@antv/g-lite'; +import type { Polygon } from '@antv/g-lite'; import { isDisplayObject } from '@antv/g-lite'; export function generatePath( context: CanvasRenderingContext2D, - parsedStyle: ParsedPolygonStyleProps, + polygon: Polygon, ) { - const { markerStart, markerEnd, markerStartOffset, markerEndOffset } = - parsedStyle; - const { points } = parsedStyle.points; + const { markerStartOffset, markerEndOffset } = polygon.attributes; + const { + markerStart, + markerEnd, + points: { points }, + } = polygon.parsedStyle; const { length } = points; const x1 = points[0][0]; diff --git a/packages/g-plugin-canvas-path-generator/src/paths/Polyline.ts b/packages/g-plugin-canvas-path-generator/src/paths/Polyline.ts index b9a3b516a..caf25618a 100644 --- a/packages/g-plugin-canvas-path-generator/src/paths/Polyline.ts +++ b/packages/g-plugin-canvas-path-generator/src/paths/Polyline.ts @@ -1,13 +1,16 @@ -import type { ParsedPolylineStyleProps } from '@antv/g-lite'; +import type { Polyline } from '@antv/g-lite'; import { isDisplayObject } from '@antv/g-lite'; export function generatePath( context: CanvasRenderingContext2D, - parsedStyle: ParsedPolylineStyleProps, + polyline: Polyline, ) { - const { markerStart, markerEnd, markerStartOffset, markerEndOffset } = - parsedStyle; - const { points } = parsedStyle.points; + const { markerStartOffset, markerEndOffset } = polyline.attributes; + const { + markerStart, + markerEnd, + points: { points }, + } = polyline.parsedStyle; const { length } = points; const x1 = points[0][0]; diff --git a/packages/g-plugin-canvas-path-generator/src/paths/Rect.ts b/packages/g-plugin-canvas-path-generator/src/paths/Rect.ts index 406cff204..7fb6daa31 100644 --- a/packages/g-plugin-canvas-path-generator/src/paths/Rect.ts +++ b/packages/g-plugin-canvas-path-generator/src/paths/Rect.ts @@ -1,11 +1,9 @@ -import type { ParsedRectStyleProps } from '@antv/g-lite'; +import type { Rect } from '@antv/g-lite'; import { clamp } from '@antv/util'; -export function generatePath( - context: CanvasRenderingContext2D, - parsedStyle: ParsedRectStyleProps, -) { - const { x = 0, y = 0, radius, width, height } = parsedStyle; +export function generatePath(context: CanvasRenderingContext2D, rect: Rect) { + const { x = 0, y = 0, width, height } = rect.attributes; + const { radius } = rect.parsedStyle; const w = width; const h = height; diff --git a/packages/g-plugin-canvas-picker/src/CanvasPickerPlugin.ts b/packages/g-plugin-canvas-picker/src/CanvasPickerPlugin.ts index fe8635f34..fd3325b83 100644 --- a/packages/g-plugin-canvas-picker/src/CanvasPickerPlugin.ts +++ b/packages/g-plugin-canvas-picker/src/CanvasPickerPlugin.ts @@ -1,13 +1,12 @@ import type { BaseStyleProps, DisplayObject, - ParsedBaseStyleProps, + GlobalRuntime, + IDocument, PickingResult, RenderingPlugin, - Shape, - IDocument, RenderingPluginContext, - GlobalRuntime, + Shape, } from '@antv/g-lite'; import { findClosestClipPathTarget, Point } from '@antv/g-lite'; import type { PathGenerator } from '@antv/g-plugin-canvas-path-generator'; @@ -98,7 +97,7 @@ export class CanvasPickerPlugin implements RenderingPlugin { // should look up in the ancestor node const clipped = findClosestClipPathTarget(displayObject); if (clipped) { - const { clipPath } = clipped.parsedStyle as ParsedBaseStyleProps; + const { clipPath } = clipped.attributes; const isHitClipPath = this.isHit( clipPath, position, @@ -176,7 +175,7 @@ export class CanvasPickerPlugin implements RenderingPlugin { this.context.pathGeneratorFactory[displayObject.nodeName]; if (generatePath) { context.beginPath(); - generatePath(context, displayObject.parsedStyle); + generatePath(context, displayObject); context.closePath(); } diff --git a/packages/g-plugin-canvas-renderer/src/CanvasRendererPlugin.ts b/packages/g-plugin-canvas-renderer/src/CanvasRendererPlugin.ts index d6460cabb..155a0ef38 100644 --- a/packages/g-plugin-canvas-renderer/src/CanvasRendererPlugin.ts +++ b/packages/g-plugin-canvas-renderer/src/CanvasRendererPlugin.ts @@ -399,9 +399,8 @@ export class CanvasRendererPlugin implements RenderingPlugin { // @ts-ignore const styleRenderer = this.context.styleRendererFactory[nodeName]; const generatePath = this.pathGeneratorFactory[nodeName]; - // clip path - const { clipPath } = object.parsedStyle as ParsedBaseStyleProps; + const { clipPath } = object.attributes; if (clipPath) { this.applyWorldTransform(context, clipPath); @@ -414,7 +413,7 @@ export class CanvasRendererPlugin implements RenderingPlugin { restoreStack.push(object); context.beginPath(); - generatePath(context, clipPath.parsedStyle); + generatePath(context, clipPath); context.closePath(); context.clip(); } @@ -433,7 +432,7 @@ export class CanvasRendererPlugin implements RenderingPlugin { if (generatePath) { context.beginPath(); - generatePath(context, object.parsedStyle); + generatePath(context, object); if ( object.nodeName !== Shape.LINE && object.nodeName !== Shape.PATH && @@ -535,8 +534,8 @@ export class CanvasRendererPlugin implements RenderingPlugin { context: CanvasRenderingContext2D, object: DisplayObject, ) { - const { stroke, fill, opacity, lineDash, lineDashOffset } = - object.parsedStyle as ParsedBaseStyleProps; + const { opacity, lineDash, lineDashOffset } = object.attributes; + const { stroke, fill } = object.parsedStyle as ParsedBaseStyleProps; // @see https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/setLineDash if (lineDash) { context.setLineDash(lineDash); diff --git a/packages/g-plugin-canvas-renderer/src/index.ts b/packages/g-plugin-canvas-renderer/src/index.ts index 19511fc97..4b0b81510 100644 --- a/packages/g-plugin-canvas-renderer/src/index.ts +++ b/packages/g-plugin-canvas-renderer/src/index.ts @@ -43,6 +43,7 @@ export class Plugin extends AbstractRendererPlugin<{ [Shape.GROUP]: undefined, [Shape.HTML]: undefined, [Shape.MESH]: undefined, + [Shape.FRAGMENT]: undefined, }; this.context.defaultStyleRendererFactory = defaultStyleRendererFactory; diff --git a/packages/g-plugin-canvas-renderer/src/shapes/styles/Default.ts b/packages/g-plugin-canvas-renderer/src/shapes/styles/Default.ts index babd1c1e6..caaff8d34 100644 --- a/packages/g-plugin-canvas-renderer/src/shapes/styles/Default.ts +++ b/packages/g-plugin-canvas-renderer/src/shapes/styles/Default.ts @@ -12,6 +12,7 @@ import { GradientType, isPattern, Shape, + getParsedStyle, } from '@antv/g-lite'; import type { ImagePool } from '@antv/g-plugin-image-loader'; import { isNil } from '@antv/util'; @@ -30,21 +31,18 @@ export class DefaultRenderer implements StyleRenderer { runtime: GlobalRuntime, ) { const { - fill, fillRule, opacity = 1, fillOpacity = 1, - stroke, strokeOpacity = 1, lineWidth = 1, lineCap, lineJoin, shadowType, - shadowColor, shadowBlur, - filter, - miterLimit, - } = parsedStyle; + } = object.attributes; + const { fill, stroke, shadowColor, filter, miterLimit } = + object.parsedStyle; const hasFill = fill && !(fill as CSSRGB).isNone; const hasStroke = stroke && !(stroke as CSSRGB).isNone && lineWidth > 0; @@ -162,8 +160,8 @@ export function setShadowAndFilter( context: CanvasRenderingContext2D, hasShadow: boolean, ) { - const { filter, shadowColor, shadowBlur, shadowOffsetX, shadowOffsetY } = - object.parsedStyle as ParsedBaseStyleProps; + const { shadowBlur, shadowOffsetX, shadowOffsetY } = object.attributes; + const { filter, shadowColor } = object.parsedStyle as ParsedBaseStyleProps; if (filter && filter.length) { // use raw filter string @@ -190,7 +188,9 @@ export function getPattern( let $offscreenCanvas: HTMLCanvasElement; let dpr: number; if ((pattern.image as Rect).nodeName === 'rect') { - const { width, height } = (pattern.image as Rect).parsedStyle; + const width = getParsedStyle(pattern.image as Rect, 'width', 0); + const height = getParsedStyle(pattern.image as Rect, 'height', 0); + dpr = canvasContext.contextService.getDPR(); const { offscreenCanvas } = canvasContext.config; $offscreenCanvas = runtime.offscreenCanvasCreator.getOrCreateCanvas( diff --git a/packages/g-plugin-canvas-renderer/src/shapes/styles/Image.ts b/packages/g-plugin-canvas-renderer/src/shapes/styles/Image.ts index b7a43cfa8..f62e6d765 100644 --- a/packages/g-plugin-canvas-renderer/src/shapes/styles/Image.ts +++ b/packages/g-plugin-canvas-renderer/src/shapes/styles/Image.ts @@ -1,17 +1,17 @@ -import type { DisplayObject, ParsedImageStyleProps } from '@antv/g-lite'; +import type { DisplayObject, Image, ParsedImageStyleProps } from '@antv/g-lite'; +import { getParsedStyle } from '@antv/g-lite'; import { ImagePool, type ImageCache } from '@antv/g-plugin-image-loader'; import { isNil } from '@antv/util'; import { mat4 } from 'gl-matrix'; +import { calculateOverlapRect, transformRect } from '../../utils/math'; import { setShadowAndFilter } from './Default'; import type { StyleRenderer } from './interfaces'; -import { transformRect, calculateOverlapRect } from '../../utils/math'; export class ImageRenderer implements StyleRenderer { constructor(private imagePool: ImagePool) {} static renderFull( context: CanvasRenderingContext2D, - parsedStyle: ParsedImageStyleProps, object: DisplayObject, data: { image: HTMLImageElement; @@ -29,7 +29,6 @@ export class ImageRenderer implements StyleRenderer { #renderDownSampled( context: CanvasRenderingContext2D, - parsedStyle: ParsedImageStyleProps, object: DisplayObject, data: { src: string | HTMLImageElement; @@ -65,7 +64,6 @@ export class ImageRenderer implements StyleRenderer { #renderTile( context: CanvasRenderingContext2D, - parsedStyle: ParsedImageStyleProps, object: DisplayObject, data: { src: string | HTMLImageElement; @@ -141,17 +139,12 @@ export class ImageRenderer implements StyleRenderer { render( context: CanvasRenderingContext2D, parsedStyle: ParsedImageStyleProps, - object: DisplayObject, + object: Image, ) { - const { - x = 0, - y = 0, - width, - height, - src, - shadowColor, - shadowBlur, - } = parsedStyle; + const { x = 0, y = 0, src, shadowBlur } = object.attributes; + const { shadowColor } = object.parsedStyle; + const width = getParsedStyle(object, 'width'); + const height = getParsedStyle(object, 'height'); const imageCache = this.imagePool.getImageSync(src, object); const image = imageCache?.img; @@ -198,7 +191,7 @@ export class ImageRenderer implements StyleRenderer { !object.ownerDocument.defaultView.getConfig() .enableLargeImageOptimization ) { - ImageRenderer.renderFull(context, parsedStyle, object, { + ImageRenderer.renderFull(context, object, { image, drawRect: [x, y, iw, ih], }); @@ -209,7 +202,7 @@ export class ImageRenderer implements StyleRenderer { const sizeOfOrigin = imageRect[2] / imageCache.size[0]; if (sizeOfOrigin < (imageCache.downSamplingRate || 0.5)) { - this.#renderDownSampled(context, parsedStyle, object, { + this.#renderDownSampled(context, object, { src, imageCache, drawRect: [x, y, iw, ih], @@ -219,7 +212,7 @@ export class ImageRenderer implements StyleRenderer { } if (!ImagePool.isSupportTile) { - ImageRenderer.renderFull(context, parsedStyle, object, { + ImageRenderer.renderFull(context, object, { image, drawRect: [x, y, iw, ih], }); @@ -227,7 +220,7 @@ export class ImageRenderer implements StyleRenderer { return; } - this.#renderTile(context, parsedStyle, object, { + this.#renderTile(context, object, { src, imageCache, imageRect, diff --git a/packages/g-plugin-canvas-renderer/src/shapes/styles/Text.ts b/packages/g-plugin-canvas-renderer/src/shapes/styles/Text.ts index 37174a0f4..1e9ccbce4 100644 --- a/packages/g-plugin-canvas-renderer/src/shapes/styles/Text.ts +++ b/packages/g-plugin-canvas-renderer/src/shapes/styles/Text.ts @@ -32,22 +32,24 @@ export class TextRenderer implements StyleRenderer { textAlign = 'start', textBaseline = 'alphabetic', lineJoin = 'miter', - miterLimit = 10, letterSpacing = 0, - stroke, - fill, fillRule, fillOpacity = 1, strokeOpacity = 1, opacity = 1, - metrics, x = 0, y = 0, dx, dy, - shadowColor, shadowBlur, - } = parsedStyle; + } = object.attributes; + const { + stroke, + fill, + metrics, + shadowColor, + miterLimit = 10, + } = object.parsedStyle; const { font, lines, height, lineHeight, lineMetrics } = metrics; diff --git a/packages/g-plugin-canvaskit-renderer/src/CanvaskitRendererPlugin.ts b/packages/g-plugin-canvaskit-renderer/src/CanvaskitRendererPlugin.ts index 3b279c9aa..4ffa1f5bd 100644 --- a/packages/g-plugin-canvaskit-renderer/src/CanvaskitRendererPlugin.ts +++ b/packages/g-plugin-canvaskit-renderer/src/CanvaskitRendererPlugin.ts @@ -320,6 +320,7 @@ export class CanvaskitRendererPlugin implements RenderingPlugin { let src: TextureSource; if (isString(image)) { + // @ts-ignore const imageCache = (this.context.imagePool as ImagePool).getImageSync( image, object, @@ -509,21 +510,20 @@ export class CanvaskitRendererPlugin implements RenderingPlugin { const renderer = this.rendererContributionFactory[object.nodeName]; const { - fill, - stroke, lineWidth, lineCap = 'butt', lineJoin = 'miter', lineDash, lineDashOffset, - miterLimit, opacity, fillOpacity, strokeOpacity, shadowBlur, shadowColor, clipPath, - } = object.parsedStyle as ParsedBaseStyleProps; + } = object.attributes; + const { fill, stroke, miterLimit } = + object.parsedStyle as ParsedBaseStyleProps; // apply clipPath if (clipPath) { diff --git a/packages/g-plugin-canvaskit-renderer/src/renderers/Circle.ts b/packages/g-plugin-canvaskit-renderer/src/renderers/Circle.ts index c72f3cd30..a3e3093b0 100644 --- a/packages/g-plugin-canvaskit-renderer/src/renderers/Circle.ts +++ b/packages/g-plugin-canvaskit-renderer/src/renderers/Circle.ts @@ -1,4 +1,4 @@ -import type { DisplayObject, ParsedCircleStyleProps } from '@antv/g-lite'; +import type { DisplayObject } from '@antv/g-lite'; import type { RendererContribution, RendererContributionContext, @@ -13,8 +13,7 @@ export class CircleRenderer implements RendererContribution { shadowFillPaint, shadowStrokePaint, } = context; - const { cx, cy, r, shadowOffsetX, shadowOffsetY } = - object.parsedStyle as ParsedCircleStyleProps; + const { cx, cy, r, shadowOffsetX, shadowOffsetY } = object.attributes; if (shadowFillPaint || shadowStrokePaint) { canvas.drawCircle( diff --git a/packages/g-plugin-canvaskit-renderer/src/renderers/Ellipse.ts b/packages/g-plugin-canvaskit-renderer/src/renderers/Ellipse.ts index e6b9679d6..250196add 100644 --- a/packages/g-plugin-canvaskit-renderer/src/renderers/Ellipse.ts +++ b/packages/g-plugin-canvaskit-renderer/src/renderers/Ellipse.ts @@ -1,4 +1,4 @@ -import type { DisplayObject, ParsedEllipseStyleProps } from '@antv/g-lite'; +import type { DisplayObject } from '@antv/g-lite'; import type { RendererContribution, RendererContributionContext, @@ -18,8 +18,7 @@ export class EllipseRenderer implements RendererContribution { shadowFillPaint, shadowStrokePaint, } = context; - const { cx, cy, rx, ry, shadowOffsetX, shadowOffsetY } = - object.parsedStyle as ParsedEllipseStyleProps; + const { cx, cy, rx, ry, shadowOffsetX, shadowOffsetY } = object.attributes; if (shadowFillPaint || shadowStrokePaint) { canvas.drawOval( diff --git a/packages/g-plugin-canvaskit-renderer/src/renderers/Image.ts b/packages/g-plugin-canvaskit-renderer/src/renderers/Image.ts index e64ef9330..c4afefc97 100644 --- a/packages/g-plugin-canvaskit-renderer/src/renderers/Image.ts +++ b/packages/g-plugin-canvaskit-renderer/src/renderers/Image.ts @@ -1,9 +1,5 @@ -import type { - CanvasContext, - DisplayObject, - ParsedImageStyleProps, - ContextService, -} from '@antv/g-lite'; +import type { CanvasContext, ContextService, Image } from '@antv/g-lite'; +import { getParsedStyle } from '@antv/g-lite'; import type { ImagePool } from '@antv/g-plugin-image-loader'; import type { CanvasKitContext, @@ -20,14 +16,15 @@ import type { export class ImageRenderer implements RendererContribution { constructor(private context: CanvasContext) {} - render(object: DisplayObject, context: RendererContributionContext) { + render(object: Image, context: RendererContributionContext) { const { surface, CanvasKit } = ( this.context.contextService as ContextService ).getContext(); const { canvas } = context; - const { x, y, width, height, src, fillOpacity, opacity } = - object.parsedStyle as ParsedImageStyleProps; - + const width = getParsedStyle(object, 'width', 0); + const height = getParsedStyle(object, 'height', 0); + const { x, y, src, fillOpacity, opacity } = object.parsedStyle; + // @ts-ignore const imageCache = (this.context.imagePool as ImagePool).getImageSync( src, object, diff --git a/packages/g-plugin-device-renderer/src/index.ts b/packages/g-plugin-device-renderer/src/index.ts index 8fec80859..2bc57552d 100644 --- a/packages/g-plugin-device-renderer/src/index.ts +++ b/packages/g-plugin-device-renderer/src/index.ts @@ -76,6 +76,7 @@ export class Plugin extends AbstractRendererPlugin { [Shape.MESH]: new MeshRenderer(), [Shape.GROUP]: undefined, [Shape.HTML]: undefined, + [Shape.FRAGMENT]: undefined, }; const batchManager = new BatchManager( diff --git a/packages/g-plugin-html-renderer/src/HTMLRenderingPlugin.ts b/packages/g-plugin-html-renderer/src/HTMLRenderingPlugin.ts index 1fca2bd6a..470775b34 100644 --- a/packages/g-plugin-html-renderer/src/HTMLRenderingPlugin.ts +++ b/packages/g-plugin-html-renderer/src/HTMLRenderingPlugin.ts @@ -247,7 +247,7 @@ export class HTMLRenderingPlugin implements RenderingPlugin { const $el = this.getOrCreateEl(object); switch (name) { case 'innerHTML': - const { innerHTML } = object.parsedStyle; + const { innerHTML } = object.attributes; if (isString(innerHTML)) { $el.innerHTML = innerHTML; } else { @@ -256,10 +256,10 @@ export class HTMLRenderingPlugin implements RenderingPlugin { } break; case 'x': - $el.style.left = `${object.parsedStyle.x}px`; + $el.style.left = `${object.attributes.x}px`; break; case 'y': - $el.style.top = `${object.parsedStyle.y}px`; + $el.style.top = `${object.attributes.y}px`; break; case 'transformOrigin': const { transformOrigin } = object.parsedStyle; @@ -270,13 +270,13 @@ export class HTMLRenderingPlugin implements RenderingPlugin { )} ${transformOrigin[1].buildCSSText(null, null, '')}`; break; case 'width': - const { width } = object.parsedStyle; + const { width } = object.attributes; $el.style.width = isNumber(width) ? `${width}px` : (width as string).toString(); break; case 'height': - const { height } = object.parsedStyle; + const { height } = object.attributes; $el.style.height = isNumber(height) ? `${height}px` : (height as string).toString(); @@ -286,15 +286,15 @@ export class HTMLRenderingPlugin implements RenderingPlugin { $el.style['z-index'] = `${zIndex}`; break; case 'visibility': - const { visibility } = object.parsedStyle; + const { visibility } = object.attributes; $el.style.visibility = visibility; break; case 'pointerEvents': - const { pointerEvents = 'auto' } = object.parsedStyle; + const { pointerEvents = 'auto' } = object.attributes; $el.style.pointerEvents = pointerEvents; break; case 'opacity': - const { opacity } = object.parsedStyle; + const { opacity } = object.attributes; $el.style.opacity = `${opacity}`; break; case 'fill': @@ -332,7 +332,7 @@ export class HTMLRenderingPlugin implements RenderingPlugin { $el.style['border-style'] = 'solid'; break; case 'lineWidth': - const { lineWidth } = object.parsedStyle; + const { lineWidth } = object.attributes; $el.style['border-width'] = `${lineWidth || 0}px`; break; case 'lineDash': diff --git a/packages/g-plugin-image-loader/src/LoadImagePlugin.ts b/packages/g-plugin-image-loader/src/LoadImagePlugin.ts index f332a3f95..36552311c 100644 --- a/packages/g-plugin-image-loader/src/LoadImagePlugin.ts +++ b/packages/g-plugin-image-loader/src/LoadImagePlugin.ts @@ -5,7 +5,7 @@ import type { RenderingPlugin, RenderingPluginContext, } from '@antv/g-lite'; -import { ElementEvent, Shape } from '@antv/g-lite'; +import { ElementEvent, Shape, getParsedStyle } from '@antv/g-lite'; import { isString } from '@antv/util'; import { ImagePool } from './ImagePool'; @@ -21,7 +21,8 @@ export class LoadImagePlugin implements RenderingPlugin { imageWidth: number, imageHeight: number, ) => { - const { width, height } = object.parsedStyle; + const width = getParsedStyle(object, 'width'); + const height = getParsedStyle(object, 'height'); if (width && !height) { object.setAttribute('height', (imageHeight / imageWidth) * width); } else if (!width && height) { diff --git a/packages/g-plugin-matterjs/src/MatterJSPlugin.ts b/packages/g-plugin-matterjs/src/MatterJSPlugin.ts index 0f04c1bbc..daba91b9e 100644 --- a/packages/g-plugin-matterjs/src/MatterJSPlugin.ts +++ b/packages/g-plugin-matterjs/src/MatterJSPlugin.ts @@ -2,7 +2,6 @@ import type { DisplayObject, FederatedEvent, MutationEvent, - ParsedLineStyleProps, ParsedPolygonStyleProps, RenderingPlugin, RenderingPluginContext, @@ -219,7 +218,7 @@ export class MatterJSPlugin implements RenderingPlugin { } private addActor(target: DisplayObject) { - const { nodeName, parsedStyle } = target; + const { nodeName, attributes, parsedStyle } = target; const { rigid, restitution = 0, @@ -230,7 +229,7 @@ export class MatterJSPlugin implements RenderingPlugin { // anchor, velocity = [0, 0], angularVelocity = 0, - } = parsedStyle; + } = attributes; const bounds = target.getBounds(); if (!AABB.isEmpty(bounds)) { @@ -266,8 +265,7 @@ export class MatterJSPlugin implements RenderingPlugin { let body: Body; if (nodeName === Shape.LINE) { - const { x1, y1, x2, y2, lineWidth } = - parsedStyle as ParsedLineStyleProps; + const { x1, y1, x2, y2, lineWidth } = attributes; const p1 = vec2.fromValues(x1, y1); const p2 = vec2.fromValues(x2, y2); const basis = vec2.sub(vec2.create(), p2, p1); @@ -313,21 +311,6 @@ export class MatterJSPlugin implements RenderingPlugin { config, ); } else if (nodeName === Shape.POLYLINE) { - // const { points } = parsedStyle as ParsedBaseStyleProps; - // const pointsInCCW = sortPointsInCCW(points.points); - // const vertices: Box2D.b2Vec2[] = pointsInCCW.map(([x, y]) => new b2Vec2(x , y )); - // const prev = pointsInCCW[0]; - // const next = pointsInCCW[pointsInCCW.length - 1]; - // const eps = 0.1; - // shape = createChainShape( - // this.Box2D, - // vertices, - // false, - // vertices[0], - // vertices[vertices.length - 1], - // // new b2Vec2(prev[0] + eps, prev[1] ), - // // new b2Vec2(next[0] + eps, next[1] ), - // ); } else if (nodeName === Shape.RECT || nodeName === Shape.IMAGE) { // matterjs set origin to center of rectangle target.style.transformOrigin = 'center center'; diff --git a/packages/g-plugin-rough-canvas-renderer/src/renderers/Circle.ts b/packages/g-plugin-rough-canvas-renderer/src/renderers/Circle.ts index 5b96e2ea7..7bb6ad34f 100644 --- a/packages/g-plugin-rough-canvas-renderer/src/renderers/Circle.ts +++ b/packages/g-plugin-rough-canvas-renderer/src/renderers/Circle.ts @@ -8,7 +8,7 @@ export class CircleRenderer implements CanvasRenderer.StyleRenderer { parsedStyle: ParsedCircleStyleProps, object: DisplayObject, ) { - const { cx = 0, cy = 0, r } = parsedStyle; + const { cx = 0, cy = 0, r } = object.attributes; // rough.js use diameter instead of radius // @see https://github.com/rough-stuff/rough/wiki#circle-x-y-diameter--options // @ts-ignore diff --git a/packages/g-plugin-rough-canvas-renderer/src/renderers/Ellipse.ts b/packages/g-plugin-rough-canvas-renderer/src/renderers/Ellipse.ts index b9bf1ca6e..b2cfb6a94 100644 --- a/packages/g-plugin-rough-canvas-renderer/src/renderers/Ellipse.ts +++ b/packages/g-plugin-rough-canvas-renderer/src/renderers/Ellipse.ts @@ -8,7 +8,7 @@ export class EllipseRenderer implements CanvasRenderer.StyleRenderer { parsedStyle: ParsedEllipseStyleProps, object: DisplayObject, ) { - const { cx = 0, cy = 0, rx, ry } = parsedStyle; + const { cx = 0, cy = 0, rx, ry } = object.attributes; // @ts-ignore context.roughCanvas.ellipse( cx, diff --git a/packages/g-plugin-rough-canvas-renderer/src/renderers/Line.ts b/packages/g-plugin-rough-canvas-renderer/src/renderers/Line.ts index 440260dfc..c897b015f 100644 --- a/packages/g-plugin-rough-canvas-renderer/src/renderers/Line.ts +++ b/packages/g-plugin-rough-canvas-renderer/src/renderers/Line.ts @@ -8,7 +8,7 @@ export class LineRenderer implements CanvasRenderer.StyleRenderer { parsedStyle: ParsedLineStyleProps, object: DisplayObject, ) { - const { x1 = 0, y1 = 0, x2 = 0, y2 = 0 } = parsedStyle; + const { x1 = 0, y1 = 0, x2 = 0, y2 = 0 } = object.attributes; // @see https://github.com/rough-stuff/rough/wiki#line-x1-y1-x2-y2--options // @ts-ignore context.roughCanvas.line(x1, y1, x2, y2, generateRoughOptions(object)); diff --git a/packages/g-plugin-rough-canvas-renderer/src/renderers/Rect.ts b/packages/g-plugin-rough-canvas-renderer/src/renderers/Rect.ts index bb6faa29a..80c0a96a4 100644 --- a/packages/g-plugin-rough-canvas-renderer/src/renderers/Rect.ts +++ b/packages/g-plugin-rough-canvas-renderer/src/renderers/Rect.ts @@ -8,7 +8,7 @@ export class RectRenderer implements CanvasRenderer.StyleRenderer { parsedStyle: ParsedRectStyleProps, object: DisplayObject, ) { - const { x = 0, y = 0, width, height } = parsedStyle; + const { x = 0, y = 0, width, height } = object.attributes; // @see https://github.com/rough-stuff/rough/wiki#rectangle-x-y-width-height--options // @ts-ignore context.roughCanvas.rectangle( diff --git a/packages/g-plugin-rough-canvas-renderer/src/util.ts b/packages/g-plugin-rough-canvas-renderer/src/util.ts index 9a03f6e5a..7f7cbe942 100644 --- a/packages/g-plugin-rough-canvas-renderer/src/util.ts +++ b/packages/g-plugin-rough-canvas-renderer/src/util.ts @@ -32,8 +32,6 @@ const MIN_STROKE_WIDTH = 0.1; export function generateRoughOptions(object: DisplayObject) { const { - fill, - stroke, fillOpacity = 1, strokeOpacity = 1, lineWidth = 1, @@ -57,7 +55,8 @@ export function generateRoughOptions(object: DisplayObject) { dashGap, zigzagOffset, preserveVertices, - } = object.parsedStyle as ParsedBaseStyleProps & Options; + } = object.attributes; + const { fill, stroke } = object.parsedStyle as ParsedBaseStyleProps & Options; // @see https://github.com/rough-stuff/rough/wiki#options const options: Options = { diff --git a/packages/g-plugin-rough-svg-renderer/src/RoughElementLifeCycleContribution.ts b/packages/g-plugin-rough-svg-renderer/src/RoughElementLifeCycleContribution.ts index 78b8fef86..37ca6c3a2 100644 --- a/packages/g-plugin-rough-svg-renderer/src/RoughElementLifeCycleContribution.ts +++ b/packages/g-plugin-rough-svg-renderer/src/RoughElementLifeCycleContribution.ts @@ -2,13 +2,9 @@ import type { CanvasContext, DisplayObject, GlobalRuntime, - ParsedCircleStyleProps, - ParsedEllipseStyleProps, - ParsedLineStyleProps, ParsedPathStyleProps, ParsedPolygonStyleProps, ParsedPolylineStyleProps, - ParsedRectStyleProps, Text, } from '@antv/g-lite'; import { Shape, translatePathToString } from '@antv/g-lite'; @@ -72,7 +68,7 @@ export class RoughElementLifeCycleContribution $el: SVGElement, svgElementMap: WeakMap, ) { - const { nodeName, parsedStyle } = object; + const { nodeName } = object; switch (nodeName) { case Shape.CIRCLE: case Shape.ELLIPSE: @@ -92,13 +88,12 @@ export class RoughElementLifeCycleContribution break; } case Shape.IMAGE: { - SVGRenderer.updateImageElementAttribute($el, parsedStyle); + SVGRenderer.updateImageElementAttribute($el, object); break; } case Shape.TEXT: { SVGRenderer.updateTextElementAttribute( $el, - parsedStyle, object as Text, this.runtime, ); @@ -120,19 +115,14 @@ export class RoughElementLifeCycleContribution switch (nodeName) { case Shape.CIRCLE: { - const { cx = 0, cy = 0, r } = parsedStyle as ParsedCircleStyleProps; + const { cx = 0, cy = 0, r } = object.attributes; // rough.js use diameter instead of radius // @see https://github.com/rough-stuff/rough/wiki#circle-x-y-diameter--options $roughG = roughSVG.circle(cx, cy, r * 2, generateRoughOptions(object)); break; } case Shape.ELLIPSE: { - const { - cx = 0, - cy = 0, - rx, - ry, - } = parsedStyle as ParsedEllipseStyleProps; + const { cx = 0, cy = 0, rx, ry } = object.attributes; $roughG = roughSVG.ellipse( cx, cy, @@ -143,12 +133,7 @@ export class RoughElementLifeCycleContribution break; } case Shape.RECT: { - const { - x = 0, - y = 0, - width, - height, - } = parsedStyle as ParsedRectStyleProps; + const { x = 0, y = 0, width, height } = object.attributes; // @see https://github.com/rough-stuff/rough/wiki#rectangle-x-y-width-height--options $roughG = roughSVG.rectangle( x, @@ -160,12 +145,7 @@ export class RoughElementLifeCycleContribution break; } case Shape.LINE: { - const { - x1 = 0, - y1 = 0, - x2 = 0, - y2 = 0, - } = parsedStyle as ParsedLineStyleProps; + const { x1 = 0, y1 = 0, x2 = 0, y2 = 0 } = object.attributes; // @see https://github.com/rough-stuff/rough/wiki#line-x1-y1-x2-y2--options $roughG = roughSVG.line(x1, y1, x2, y2, generateRoughOptions(object)); break; diff --git a/packages/g-plugin-rough-svg-renderer/src/util.ts b/packages/g-plugin-rough-svg-renderer/src/util.ts index 4e6e588cd..ab3bebff2 100644 --- a/packages/g-plugin-rough-svg-renderer/src/util.ts +++ b/packages/g-plugin-rough-svg-renderer/src/util.ts @@ -55,8 +55,6 @@ const MIN_STROKE_WIDTH = 0.1; export function generateRoughOptions(object: DisplayObject) { const { - fill, - stroke, fillOpacity = 1, strokeOpacity = 1, bowing, @@ -80,7 +78,8 @@ export function generateRoughOptions(object: DisplayObject) { dashGap, zigzagOffset, preserveVertices, - } = object.parsedStyle as ParsedBaseStyleProps & Options; + } = object.attributes; + const { fill, stroke } = object.parsedStyle as ParsedBaseStyleProps & Options; // @see https://github.com/rough-stuff/rough/wiki#options const options: Options = { diff --git a/packages/g-plugin-svg-renderer/src/DefaultElementLifeCycleContribution.ts b/packages/g-plugin-svg-renderer/src/DefaultElementLifeCycleContribution.ts index 6a6e6bbdb..7969548c8 100644 --- a/packages/g-plugin-svg-renderer/src/DefaultElementLifeCycleContribution.ts +++ b/packages/g-plugin-svg-renderer/src/DefaultElementLifeCycleContribution.ts @@ -2,6 +2,9 @@ import type { CanvasContext, DisplayObject, GlobalRuntime, + Line, + Path, + Polyline, Text, } from '@antv/g-lite'; import { Shape } from '@antv/g-lite'; @@ -130,37 +133,32 @@ export class DefaultElementLifeCycleContribution updateElementAttribute(object: DisplayObject) { // @ts-ignore const { $el } = object.elementSVG as ElementSVG; - const { nodeName, parsedStyle } = object; + const { nodeName } = object; switch (nodeName) { case Shape.IMAGE: { - updateImageElementAttribute($el, parsedStyle); + updateImageElementAttribute($el, object); break; } case Shape.RECT: { - updateRectElementAttribute($el, parsedStyle); + updateRectElementAttribute($el, object); break; } case Shape.LINE: { - updateLineElementAttribute($el, parsedStyle); + updateLineElementAttribute($el, object as Line); break; } case Shape.POLYGON: case Shape.POLYLINE: { - updatePolylineElementAttribute($el, parsedStyle); + updatePolylineElementAttribute($el, object as Polyline); break; } case Shape.PATH: { - updatePathElementAttribute($el, parsedStyle); + updatePathElementAttribute($el, object as Path); break; } case Shape.TEXT: { - updateTextElementAttribute( - $el, - parsedStyle, - object as Text, - this.runtime, - ); + updateTextElementAttribute($el, object as Text, this.runtime); break; } } diff --git a/packages/g-plugin-svg-renderer/src/SVGRendererPlugin.ts b/packages/g-plugin-svg-renderer/src/SVGRendererPlugin.ts index 6ff8bac14..1821dd1e5 100644 --- a/packages/g-plugin-svg-renderer/src/SVGRendererPlugin.ts +++ b/packages/g-plugin-svg-renderer/src/SVGRendererPlugin.ts @@ -240,8 +240,8 @@ export class SVGRendererPlugin implements RenderingPlugin { // @ts-ignore const $el = object.elementSVG?.$el; - const { fill, stroke, clipPath } = - object.parsedStyle as ParsedBaseStyleProps; + const { clipPath } = object.attributes; + const { fill, stroke } = object.parsedStyle as ParsedBaseStyleProps; if (fill && !isCSSRGB(fill)) { this.defElementManager.createOrUpdateGradientAndPattern( @@ -267,7 +267,9 @@ export class SVGRendererPlugin implements RenderingPlugin { object.getWorldTransform(), ); - const clipPathId = `${CLIP_PATH_PREFIX + clipPath.entity}-${object.entity}`; + const clipPathId = `${CLIP_PATH_PREFIX + clipPath.entity}-${ + object.entity + }`; const $def = this.defElementManager.getDefElement(); const $existed = $def.querySelector(`#${clipPathId}`); if ($existed) { @@ -503,12 +505,14 @@ export class SVGRendererPlugin implements RenderingPlugin { // update common attributes attributes.forEach((name) => { const usedName = SVG_ATTR_MAP[name]; - const computedValue = parsedStyle[name]; + const attrValue = object.attributes[name]; + const parsedValue = parsedStyle[name] ?? attrValue; + const computedValue = parsedValue; const computedValueStr = !isNil(computedValue) && computedValue.toString(); const formattedValueStr = FORMAT_VALUE_MAP[name]?.[computedValueStr] || computedValueStr; - const usedValue = parsedStyle[name]; + const usedValue = parsedValue; const inherited = usedName && !!propertyMetadataCache[name]?.inh; // @@ -683,7 +687,7 @@ export class SVGRendererPlugin implements RenderingPlugin { const svgElement = (object as any).elementSVG as ElementSVG; let { $hitTestingEl } = svgElement; const increasedLineWidthForHitTesting = Number( - object.parsedStyle.increasedLineWidthForHitTesting, + object.attributes.increasedLineWidthForHitTesting, ); // account for hitArea @@ -708,7 +712,7 @@ export class SVGRendererPlugin implements RenderingPlugin { // increase interactive line width $hitTestingEl.setAttribute( 'stroke-width', - `${increasedLineWidthForHitTesting + object.parsedStyle.lineWidth}`, + `${increasedLineWidthForHitTesting + object.attributes.lineWidth}`, ); } else if ($hitTestingEl) { $groupEl.removeChild($hitTestingEl); diff --git a/packages/g-plugin-svg-renderer/src/shapes/defs/Pattern.ts b/packages/g-plugin-svg-renderer/src/shapes/defs/Pattern.ts index e3e6fab70..e9d04e847 100644 --- a/packages/g-plugin-svg-renderer/src/shapes/defs/Pattern.ts +++ b/packages/g-plugin-svg-renderer/src/shapes/defs/Pattern.ts @@ -307,7 +307,10 @@ function createOrUpdatePattern( } if ((image as Rect).nodeName === 'rect') { - const { width, height } = (image as Rect).parsedStyle; + const { + width = (image as Rect).attributes.width, + height = (image as Rect).attributes.height, + } = (image as Rect).parsedStyle; const $pattern = create$Pattern( document, diff --git a/packages/g-plugin-svg-renderer/src/shapes/defs/Shadow.ts b/packages/g-plugin-svg-renderer/src/shapes/defs/Shadow.ts index 8de996697..de85c7b02 100644 --- a/packages/g-plugin-svg-renderer/src/shapes/defs/Shadow.ts +++ b/packages/g-plugin-svg-renderer/src/shapes/defs/Shadow.ts @@ -18,10 +18,10 @@ export function createOrUpdateShadow( const { shadowType = 'outer', shadowBlur, - shadowColor, shadowOffsetX, shadowOffsetY, - } = object.parsedStyle as ParsedBaseStyleProps; + } = object.attributes; + const { shadowColor } = object.parsedStyle as ParsedBaseStyleProps; const hasShadow = !isNil(shadowColor) && shadowBlur > 0; const shadowId = FILTER_DROPSHADOW_PREFIX + object.entity; diff --git a/packages/g-plugin-svg-renderer/src/shapes/paths/Image.ts b/packages/g-plugin-svg-renderer/src/shapes/paths/Image.ts index fe93e74f4..f06b247c4 100644 --- a/packages/g-plugin-svg-renderer/src/shapes/paths/Image.ts +++ b/packages/g-plugin-svg-renderer/src/shapes/paths/Image.ts @@ -1,11 +1,8 @@ -import type { ParsedImageStyleProps } from '@antv/g-lite'; +import type { Image as GImage } from '@antv/g-lite'; import { isString } from '@antv/util'; -export function updateImageElementAttribute( - $el: SVGElement, - parsedStyle: ParsedImageStyleProps, -) { - const { src = '', x = 0, y = 0, width, height } = parsedStyle; +export function updateImageElementAttribute($el: SVGElement, object: GImage) { + const { src = '', x = 0, y = 0, width, height } = object.attributes; $el.setAttribute('x', `${x}`); $el.setAttribute('y', `${y}`); diff --git a/packages/g-plugin-svg-renderer/src/shapes/paths/Line.ts b/packages/g-plugin-svg-renderer/src/shapes/paths/Line.ts index 9f4d26757..93be4d3b0 100644 --- a/packages/g-plugin-svg-renderer/src/shapes/paths/Line.ts +++ b/packages/g-plugin-svg-renderer/src/shapes/paths/Line.ts @@ -1,20 +1,10 @@ -import type { ParsedLineStyleProps } from '@antv/g-lite'; +import type { Line } from '@antv/g-lite'; import { isDisplayObject } from '@antv/g-lite'; -export function updateLineElementAttribute( - $el: SVGElement, - parsedStyle: ParsedLineStyleProps, -) { - const { - x1, - y1, - x2, - y2, - markerStart, - markerEnd, - markerStartOffset, - markerEndOffset, - } = parsedStyle; +export function updateLineElementAttribute($el: SVGElement, object: Line) { + const { x1, y1, x2, y2, markerStartOffset, markerEndOffset } = + object.attributes; + const { markerStart, markerEnd } = object.parsedStyle; let startOffsetX = 0; let startOffsetY = 0; diff --git a/packages/g-plugin-svg-renderer/src/shapes/paths/Path.ts b/packages/g-plugin-svg-renderer/src/shapes/paths/Path.ts index 33f5bf532..9148cb444 100644 --- a/packages/g-plugin-svg-renderer/src/shapes/paths/Path.ts +++ b/packages/g-plugin-svg-renderer/src/shapes/paths/Path.ts @@ -1,12 +1,9 @@ -import type { ParsedPathStyleProps, Path } from '@antv/g-lite'; +import type { Path } from '@antv/g-lite'; import { isDisplayObject, translatePathToString } from '@antv/g-lite'; -export function updatePathElementAttribute( - $el: SVGElement, - parsedStyle: ParsedPathStyleProps, -) { - const { d, markerStart, markerEnd, markerStartOffset, markerEndOffset } = - parsedStyle; +export function updatePathElementAttribute($el: SVGElement, object: Path) { + const { markerStartOffset, markerEndOffset } = object.attributes; + const { d, markerStart, markerEnd } = object.parsedStyle; let startOffsetX = 0; let startOffsetY = 0; diff --git a/packages/g-plugin-svg-renderer/src/shapes/paths/Polyline.ts b/packages/g-plugin-svg-renderer/src/shapes/paths/Polyline.ts index 405149d32..4eaa6cb70 100644 --- a/packages/g-plugin-svg-renderer/src/shapes/paths/Polyline.ts +++ b/packages/g-plugin-svg-renderer/src/shapes/paths/Polyline.ts @@ -1,17 +1,16 @@ -import type { ParsedPolylineStyleProps } from '@antv/g-lite'; +import type { Polyline } from '@antv/g-lite'; import { isDisplayObject } from '@antv/g-lite'; export function updatePolylineElementAttribute( $el: SVGElement, - parsedStyle: ParsedPolylineStyleProps, + object: Polyline, ) { + const { markerStartOffset, markerEndOffset } = object.attributes; const { points: { points }, markerStart, - markerStartOffset, markerEnd, - markerEndOffset, - } = parsedStyle; + } = object.parsedStyle; const { length } = points; if (points && length >= 2) { diff --git a/packages/g-plugin-svg-renderer/src/shapes/paths/Rect.ts b/packages/g-plugin-svg-renderer/src/shapes/paths/Rect.ts index 98d7b42fb..b3b496735 100644 --- a/packages/g-plugin-svg-renderer/src/shapes/paths/Rect.ts +++ b/packages/g-plugin-svg-renderer/src/shapes/paths/Rect.ts @@ -1,11 +1,9 @@ -import type { ParsedRectStyleProps } from '@antv/g-lite'; +import type { Rect } from '@antv/g-lite'; import { clamp } from '@antv/util'; -export function updateRectElementAttribute( - $el: SVGElement, - parsedStyle: ParsedRectStyleProps, -) { - const { radius, x = 0, y = 0, width, height } = parsedStyle; +export function updateRectElementAttribute($el: SVGElement, object: Rect) { + const { x = 0, y = 0, width, height } = object.attributes; + const { radius } = object.parsedStyle; // CSSKeyword: auto if (!isFinite(width) || !isFinite(height)) { diff --git a/packages/g-plugin-svg-renderer/src/shapes/paths/Text.ts b/packages/g-plugin-svg-renderer/src/shapes/paths/Text.ts index 4306f0c6d..8ca32de14 100644 --- a/packages/g-plugin-svg-renderer/src/shapes/paths/Text.ts +++ b/packages/g-plugin-svg-renderer/src/shapes/paths/Text.ts @@ -1,4 +1,4 @@ -import type { GlobalRuntime, ParsedTextStyleProps, Text } from '@antv/g-lite'; +import type { GlobalRuntime, Text } from '@antv/g-lite'; import { TEXT_PATH_PREFIX } from '../../SVGRendererPlugin'; import { createSVGElement } from '../../utils/dom'; import { convertHTML } from '../../utils/format'; @@ -15,7 +15,6 @@ const BASELINE_MAP: Record = { export function updateTextElementAttribute( $el: SVGElement, - parsedStyle: ParsedTextStyleProps, text: Text, runtime: GlobalRuntime, ) { @@ -33,9 +32,9 @@ export function updateTextElementAttribute( textDecorationLine = '', textDecorationColor = '', textDecorationStyle = '', - metrics, - } = parsedStyle; - let { textBaseline = 'alphabetic' } = parsedStyle; + } = text.attributes; + const { metrics } = text.parsedStyle; + let { textBaseline = 'alphabetic' } = text.attributes; if (textBaseline === 'alphabetic') { textBaseline = 'bottom'; diff --git a/packages/g-plugin-yoga/src/YogaPlugin.ts b/packages/g-plugin-yoga/src/YogaPlugin.ts index f8e67edec..8fcd0da37 100644 --- a/packages/g-plugin-yoga/src/YogaPlugin.ts +++ b/packages/g-plugin-yoga/src/YogaPlugin.ts @@ -424,7 +424,7 @@ export class YogaPlugin implements RenderingPlugin { } private isFlex(object: DisplayObject) { - return object?.parsedStyle?.display === 'flex'; + return object?.attributes?.display === 'flex'; } private setDefaultValues(node: YogaNode) { diff --git a/packages/g-plugin-zdog-canvas-renderer/src/renderers/Circle.ts b/packages/g-plugin-zdog-canvas-renderer/src/renderers/Circle.ts index 592c367ee..c435c2b8e 100644 --- a/packages/g-plugin-zdog-canvas-renderer/src/renderers/Circle.ts +++ b/packages/g-plugin-zdog-canvas-renderer/src/renderers/Circle.ts @@ -1,14 +1,15 @@ import type { CanvasRenderer } from '@antv/g-canvas'; -import type { DisplayObject, ParsedCircleStyleProps } from '@antv/g-lite'; +import type { Circle, ParsedCircleStyleProps } from '@antv/g-lite'; import { Anchor, Ellipse } from 'zdog'; export class CircleRenderer implements CanvasRenderer.StyleRenderer { render( context: CanvasRenderingContext2D & { scene: Anchor }, parsedStyle: ParsedCircleStyleProps, - object: DisplayObject, + object: Circle, ) { - const { r, lineWidth, fill } = parsedStyle; + const { r, lineWidth } = object.attributes; + const { fill } = parsedStyle; new Ellipse({ addTo: context.scene, diff --git a/packages/g-plugin-zdog-svg-renderer/src/ZdogElementLifeCycleContribution.ts b/packages/g-plugin-zdog-svg-renderer/src/ZdogElementLifeCycleContribution.ts index e9942f621..6565e68d2 100644 --- a/packages/g-plugin-zdog-svg-renderer/src/ZdogElementLifeCycleContribution.ts +++ b/packages/g-plugin-zdog-svg-renderer/src/ZdogElementLifeCycleContribution.ts @@ -59,7 +59,7 @@ export class ZdogElementLifeCycleContribution } updateElementAttribute(object: DisplayObject, $el: SVGElement) { - const { nodeName, parsedStyle } = object; + const { nodeName } = object; switch (nodeName) { case Shape.CIRCLE: case Shape.ELLIPSE: @@ -79,13 +79,12 @@ export class ZdogElementLifeCycleContribution break; } case Shape.IMAGE: { - SVGRenderer.updateImageElementAttribute($el, parsedStyle); + SVGRenderer.updateImageElementAttribute($el, object); break; } case Shape.TEXT: { SVGRenderer.updateTextElementAttribute( $el, - parsedStyle, object as Text, this.runtime, ); diff --git a/packages/g-plugin-zdog-svg-renderer/src/ZdogRendererPlugin.ts b/packages/g-plugin-zdog-svg-renderer/src/ZdogRendererPlugin.ts index e59450dad..7fdf03f29 100644 --- a/packages/g-plugin-zdog-svg-renderer/src/ZdogRendererPlugin.ts +++ b/packages/g-plugin-zdog-svg-renderer/src/ZdogRendererPlugin.ts @@ -6,6 +6,7 @@ import { RenderingPlugin, RenderingPluginContext, ParsedCircleStyleProps, + CircleStyleProps, } from '@antv/g-lite'; import { G_SVG_PREFIX } from '@antv/g-plugin-svg-renderer'; import { Anchor, Ellipse, Group } from 'zdog'; @@ -33,8 +34,9 @@ export class ZdogRendererPlugin implements RenderingPlugin { break; } case Shape.CIRCLE: { - const { cx, cy, r, lineWidth, fill } = - parsedStyle as ParsedCircleStyleProps; + const { cx, cy, r, lineWidth } = + object.attributes as CircleStyleProps; + const { fill } = parsedStyle as ParsedCircleStyleProps; zdogShape = new Ellipse({ diameter: 2 * r, stroke: lineWidth, @@ -80,6 +82,7 @@ export class ZdogRendererPlugin implements RenderingPlugin { $camera.removeChild($camera.firstChild); } + // @ts-ignore this.scene.renderGraphSvg($camera); });