Skip to content

Commit

Permalink
fix: html element's getBounds logic exception (#1743) (#1764)
Browse files Browse the repository at this point in the history
  • Loading branch information
wang1212 authored Aug 30, 2024
1 parent 5e4a1d6 commit fcd0467
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 51 deletions.
6 changes: 6 additions & 0 deletions .changeset/silver-chicken-heal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@antv/g-plugin-html-renderer': patch
'@antv/g-lite': patch
---

fix: html element's `getBounds` logic exception (#1743)
29 changes: 21 additions & 8 deletions demo/camera+html.html → demo/issues/issue-1743.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@
padding: 0;
}

html,
body {
height: 100vh;
padding: 111px 0 0 111px;
/* padding: 100px 0 0 100px; */
}

#container {
/* border: 1px solid #ddd; */
background-color: #ddd;
width: 100%;
height: 100%;
}
Expand All @@ -29,16 +32,14 @@
<body>
<div id="container"></div>
<script
src="../packages/g/dist/index.umd.min.js"
src="../../packages/g/dist/index.umd.min.js"
type="application/javascript"
></script>
<script
src="../packages/g-canvas/dist/index.umd.min.js"
src="../../packages/g-canvas/dist/index.umd.min.js"
type="application/javascript"
></script>
<script src="../packages/g-plugin-control/dist/index.umd.min.js"></script>
<!-- <script src="../packages/g-svg/dist/index.umd.min.js" type="application/javascript"></script>
<script src="../packages/g-webgl/dist/index.umd.min.js" type="application/javascript"></script> -->
<script src="../../packages/g-plugin-control/dist/index.umd.min.js"></script>
<script>
console.log(window.G);
const { Circle, CanvasEvent, Canvas, HTML } = window.G;
Expand All @@ -50,8 +51,8 @@
// create a canvas
const canvas = new Canvas({
container: 'container',
width: 800,
height: 800,
width: 600,
height: 600,
renderer: canvasRenderer,
});

Expand All @@ -61,6 +62,9 @@
cy: 200,
r: 50,
fill: 'red',
transform: 'translate(120px, 120px) scale(2)',
transformOrigin: 'center center',
// transformOrigin: '200px 200px',
},
});

Expand All @@ -72,13 +76,22 @@
height: 100,
innerHTML:
'<h1 style="width: 100px; height: 100px;">This is Title</h1>',
transform: 'translate(120px, 120px) scale(2)',
transformOrigin: 'center center',
// transformOrigin: '50px 50px',
},
});

canvas.addEventListener(CanvasEvent.READY, () => {
canvas.appendChild(circle);
canvas.appendChild(html);

// console.log(
// 'transform',
// circle.getWorldTransform(),
// html.getWorldTransform(),
// );

console.log('canvas.getCamera()', canvas.getCamera(), circle, html);
console.log(
'circle',
Expand Down
60 changes: 27 additions & 33 deletions packages/g-lite/src/display-objects/HTML.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { mat4 } from 'gl-matrix';
import type { DisplayObjectConfig } from '../dom';
import { runtime } from '../global-runtime';
import { AABB, Rectangle } from '../shapes';
import { AABB } from '../shapes';
import type { BaseStyleProps, ParsedBaseStyleProps } from '../types';
import { Shape } from '../types';
import { DisplayObject } from './DisplayObject';
Expand Down Expand Up @@ -61,45 +61,39 @@ export class HTML extends DisplayObject<HTMLStyleProps, ParsedHTMLStyleProps> {
/**
* override with $el.getBoundingClientRect
* @see https://developer.mozilla.org/zh-CN/docs/Web/API/Element/getBoundingClientRect
*
* ! The calculation logic of the html element should be consistent with that of the canvas element
*/
getBoundingClientRect(): Rectangle {
if (this.parsedStyle.$el) {
const cameraMatrix = this.ownerDocument.defaultView
.getCamera()
.getOrthoMatrix();
const bBox = this.parsedStyle.$el.getBoundingClientRect();

return Rectangle.applyTransform(
bBox,
mat4.invert(mat4.create(), cameraMatrix),
);
} else {
const { x, y, width, height } = this.parsedStyle;
return new Rectangle(x, y, width, height);
}
}
// getBoundingClientRect(): Rectangle {
// if (this.parsedStyle.$el) {
// return this.parsedStyle.$el.getBoundingClientRect();
// } else {
// const { x, y, width, height } = this.parsedStyle;
// return new Rectangle(x, y, width, height);
// }
// }

getClientRects() {
return [this.getBoundingClientRect()];
}

getBounds() {
const clientRect = this.getBoundingClientRect();
// calc context's offset
// @ts-ignore
const canvasRect = this.ownerDocument?.defaultView
?.getContextService()
.getBoundingClientRect();
// getBounds() {
// const clientRect = this.getBoundingClientRect();
// // calc context's offset
// // @ts-ignore
// const canvasRect = this.ownerDocument?.defaultView
// ?.getContextService()
// .getBoundingClientRect();

const aabb = new AABB();
const minX = clientRect.left - (canvasRect?.left || 0);
const minY = clientRect.top - (canvasRect?.top || 0);
aabb.setMinMax(
[minX, minY, 0],
[minX + clientRect.width, minY + clientRect.height, 0],
);
return aabb;
}
// const aabb = new AABB();
// const minX = clientRect.left - (canvasRect?.left || 0);
// const minY = clientRect.top - (canvasRect?.top || 0);
// aabb.setMinMax(
// [minX, minY, 0],
// [minX + clientRect.width, minY + clientRect.height, 0],
// );
// return aabb;
// }

getLocalBounds() {
if (this.parentNode) {
Expand Down
3 changes: 2 additions & 1 deletion packages/g-lite/src/global-runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import {
RectUpdater,
TextService,
TextUpdater,
HTMLUpdater,
} from './services';
import { CanvasLike, Shape } from './types';

Expand Down Expand Up @@ -104,7 +105,7 @@ const geometryUpdaterFactory: Record<Shape, GeometryAABBUpdater<any>> = (() => {
[Shape.POLYLINE]: polylineUpdater,
[Shape.POLYGON]: polylineUpdater,
[Shape.PATH]: new PathUpdater(),
[Shape.HTML]: null,
[Shape.HTML]: new HTMLUpdater(),
[Shape.MESH]: null,
};
})();
Expand Down
15 changes: 15 additions & 0 deletions packages/g-lite/src/services/aabb/HTMLUpdater.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { HTML, ParsedHTMLStyleProps } from '../../display-objects/HTML';
import type { GeometryAABBUpdater } from './interfaces';

export class HTMLUpdater implements GeometryAABBUpdater<ParsedHTMLStyleProps> {
update(parsedStyle: ParsedHTMLStyleProps, object: HTML) {
const { x = 0, y = 0, width = 0, height = 0 } = parsedStyle;

return {
cx: x + width / 2,
cy: y + height / 2,
hwidth: width / 2,
hheight: height / 2,
};
}
}
1 change: 1 addition & 0 deletions packages/g-lite/src/services/aabb/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export { PolylineUpdater } from './PolylineUpdater';
export { RectUpdater } from './RectUpdater';
export { TextUpdater } from './TextUpdater';
export { GroupUpdater } from './GroupUpdater';
export { HTMLUpdater } from './HTMLUpdater';
25 changes: 16 additions & 9 deletions packages/g-plugin-html-renderer/src/HTMLRenderingPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
Shape,
} from '@antv/g-lite';
import { isNil, isNumber, isString } from '@antv/util';
import type { mat4 } from 'gl-matrix';
import type { mat4, vec3 } from 'gl-matrix';

const CANVAS_CAMERA_ID = 'g-canvas-camera';

Expand All @@ -36,14 +36,17 @@ export class HTMLRenderingPlugin implements RenderingPlugin {
HTMLElement
>();

private joinTransformMatrix(matrix: mat4) {
/**
* ! The reason for adding `offset` is that the `transform-origin` coordinate system of DOM is the local coordinate system of the element, while the `transform-origin` coordinate system of canvas drawing is the local coordinate system of the element's parent element. At the same time, the `transform` attribute value of the DOM element does not include `transform-origin`.
*/
private joinTransformMatrix(matrix: mat4, offset: vec3 = [0, 0, 0]) {
return `matrix(${[
matrix[0],
matrix[1],
matrix[4],
matrix[5],
matrix[12],
matrix[13],
matrix[12] + offset[0],
matrix[13] + offset[1],
].join(',')})`;
}

Expand All @@ -56,6 +59,7 @@ export class HTMLRenderingPlugin implements RenderingPlugin {
const setTransform = (object: HTML, $el: HTMLElement) => {
$el.style.transform = this.joinTransformMatrix(
object.getWorldTransform(),
object.getOrigin(),
);
};

Expand Down Expand Up @@ -118,8 +122,8 @@ export class HTMLRenderingPlugin implements RenderingPlugin {
const handleCanvasResize = () => {
if (this.$camera) {
const { width, height } = this.context.config;
this.$camera.style.width = `${width || 0}px`;
this.$camera.style.height = `${height || 0}px`;
this.$camera.parentElement.style.width = `${width || 0}px`;
this.$camera.parentElement.style.height = `${height || 0}px`;
}
};

Expand Down Expand Up @@ -237,6 +241,7 @@ export class HTMLRenderingPlugin implements RenderingPlugin {
$existedElement.style['will-change'] = 'transform';
$existedElement.style.transform = this.joinTransformMatrix(
object.getWorldTransform(),
object.getOrigin(),
);
}

Expand All @@ -263,9 +268,11 @@ export class HTMLRenderingPlugin implements RenderingPlugin {
break;
case 'transformOrigin':
const { transformOrigin } = object.parsedStyle;
$el.style[
'transform-origin'
] = `${transformOrigin[0].value} ${transformOrigin[1].value}`;
$el.style['transform-origin'] = `${transformOrigin[0].buildCSSText(
null,
null,
'',
)} ${transformOrigin[1].buildCSSText(null, null, '')}`;
break;
case 'width':
if (this.context.enableCSSParsing) {
Expand Down

0 comments on commit fcd0467

Please sign in to comment.