瀏覽代碼

move rountangles themselfes from html div to svg, fix zoom bug

Jakob Pietron 2 年之前
父節點
當前提交
e6c66f7bb9

+ 41 - 28
src/frontend/rountangleEditor/RountangleComponent.tsx

@@ -46,7 +46,7 @@ export class RountangleComponent extends React.Component<RountangleProps, Rounta
         }
     }
 
-    onPointerDown = (event: React.PointerEvent<HTMLDivElement>) => {
+    onPointerDown = (event: React.PointerEvent<SVGRectElement>) => {
         // only left mouse button
         if (event.button !== 0) return;
 
@@ -57,7 +57,7 @@ export class RountangleComponent extends React.Component<RountangleProps, Rounta
         event.preventDefault();
     }
 
-    onPointerMove = (event: React.PointerEvent<HTMLDivElement>) => {
+    onPointerMove = (event: React.PointerEvent<SVGRectElement>) => {
         if (!this.state.dragging) return;
 
         if (event.movementX !== 0 || event.movementY !== 0) {
@@ -72,7 +72,7 @@ export class RountangleComponent extends React.Component<RountangleProps, Rounta
         event.preventDefault();
     }
 
-    onPointerUp = (event: React.PointerEvent<HTMLDivElement>) => {
+    onPointerUp = (event: React.PointerEvent<SVGRectElement>) => {
         event.currentTarget.releasePointerCapture(event.pointerId);
         event.stopPropagation();
         event.preventDefault();
@@ -134,32 +134,45 @@ export class RountangleComponent extends React.Component<RountangleProps, Rounta
 
     render() {
         return(
-            <foreignObject
-                x={this.props.posX + this.state.movementsX}
-                y={this.props.posY + this.state.movementsY}
-                width={this.props.width + this.state.resizeWidth}
-                height={this.props.height + this.state.resizeHeight}
-                className={'re-div-wrapper'}
+            <g
+                className={`re-rountangle-wrapper ${this.state.dragging ? 'dragging' : ''}`}
             >
-            <div
-              className={`re-rountangle ${this.state.dragging ? 'dragging' : ''}`}
-              onPointerDown={this.onPointerDown}
-              onPointerMove={this.onPointerMove}
-              onPointerUp={this.onPointerUp}
-              onDoubleClick={this.onDoubleClick}
-          >
-              <div title={this.props.id.toString()} className={'re-rountangle-name'}>
-                  {this.props.name}
-              </div>
-              <RountangleResizeHandleComponent
-                  id={this.props.id}
-                  height={this.props.height + this.state.resizeHeight}
-                  width={this.props.width + this.state.resizeWidth}
-                  onResize={this.onResize}
-                  onResizeComplete={this.onResizeComplete}
-              />
-          </div>
-            </foreignObject>
+                <rect
+                    rx={5}
+                    ry={5}
+                    x={this.props.posX + this.state.movementsX}
+                    y={this.props.posY + this.state.movementsY}
+                    width={this.props.width + this.state.resizeWidth}
+                    height={this.props.height + this.state.resizeHeight}
+                    className={'re-rountangle'}
+                />
+                <foreignObject
+                    x={this.props.posX + this.state.movementsX}
+                    y={this.props.posY + this.state.movementsY}
+                    width={this.props.width + this.state.resizeWidth}
+                    height={this.props.height + this.state.resizeHeight}
+                    onPointerDown={this.onPointerDown}
+                    onPointerMove={this.onPointerMove}
+                    onPointerUp={this.onPointerUp}
+                    onDoubleClick={this.onDoubleClick}
+                >
+                    <div
+                        className={'re-rountangle-name'}
+                        title={this.props.id.toString()}
+                    >
+                        <span>{this.props.name}</span>
+                    </div>
+                </foreignObject>
+                <RountangleResizeHandleComponent
+                    id={this.props.id}
+                    x={this.props.posX + this.state.movementsX}
+                    y={this.props.posY + this.state.movementsY}
+                    height={this.props.height + this.state.resizeHeight}
+                    width={this.props.width + this.state.resizeWidth}
+                    onResize={this.onResize}
+                    onResizeComplete={this.onResizeComplete}
+                />
+            </g>
         );
     }
 }

+ 16 - 22
src/frontend/rountangleEditor/RountangleEditor.css

@@ -6,40 +6,34 @@
     cursor: move;
 }
 
-.re-div-wrapper {
+.re-rountangle-wrapper {
     filter: drop-shadow(.1rem .1rem .1em deeppink);
 }
 .re-rountangle {
-    position: absolute;
-    border: 3px solid black;
-    border-radius: 5px;
-    display: flex;
-    flex-direction: column;
-    justify-content: center;
-    text-align: center;
+    stroke: black;
+    stroke-width: 3px;
     overflow: hidden;
     font-weight: bold;
-    width: 100%;
-    height: 100%;
-    min-height: 50px;
-    min-width: 50px;
+    fill: transparent;
 }
-.re-rountangle:hover {
+.re-rountangle-wrapper:hover {
     cursor: grab;
 }
-.re-rountangle:hover.dragging {
+.re-rountangle-wrapper:hover.dragging {
     cursor: grabbing;
 }
 .re-rountangle-name {
-
+    font-weight: 600;
+    text-overflow: ellipsis;
+    text-align: center;
+    height: 100%;
+    max-height: 100%;
+    display: flex;
+    justify-content: center;
+    flex-direction: column;
+    pointer-events: none;
 }
 .re-rountangle-resize-handle {
-    width: 20px;
-    height: 20px;
-    position: absolute;
-    bottom: -10px;
-    right: -10px;
-    background: deeppink;
+    fill: deeppink;
     cursor: nwse-resize;
-    rotate: 45deg;
 }

+ 2 - 1
src/frontend/rountangleEditor/RountangleEditor.tsx

@@ -281,12 +281,13 @@ export class RountangleEditor extends React.Component<RountangleEditorProps, Rou
         if(!this.canvasRef.current) return;
 
         const newZoom = event.deltaY > 0 ? Math.min(this.state.zoom * 1.1, 3.0) : Math.max(this.state.zoom * 0.9, 0.1);
+
         this.setState({
             zoom: newZoom,
             translateX: this.state.translateX + (this.state.baseWidth * this.state.zoom - this.state.baseWidth * newZoom)/2,
             translateY: this.state.translateY + (this.state.baseHeight * this.state.zoom - this.state.baseHeight * newZoom)/2,
             currentWidth: this.state.baseWidth * newZoom,
-            currentHeight: this.state.currentHeight * newZoom
+            currentHeight: this.state.baseHeight * newZoom
         })
     }
 

+ 19 - 7
src/frontend/rountangleEditor/RountangleResizeHandleComponent.tsx

@@ -4,6 +4,8 @@ import {PrimitiveValue} from "../../onion/types";
 
 interface RountangleResizeHandleProps {
     id:               PrimitiveValue;
+    x:                number;
+    y:                number;
     width:            number;
     height:           number;
     onResize:         (deltaX: number, deltaY: number) => void;
@@ -18,7 +20,9 @@ export interface RountangleResizeHandleState {
 export class RountangleResizeHandleComponent extends React.Component<RountangleResizeHandleProps, RountangleResizeHandleState> {
     shouldComponentUpdate(nextProps: Readonly<RountangleResizeHandleProps>, nextState: Readonly<RountangleState>, nextContext: any): boolean {
         return this.props.width !== nextProps.width
-            || this.props.height !== nextProps.height;
+            || this.props.height !== nextProps.height
+            || this.props.x !== nextProps.x
+            || this.props.y !== nextProps.y
     }
 
     constructor(props: RountangleResizeHandleProps) {
@@ -29,7 +33,7 @@ export class RountangleResizeHandleComponent extends React.Component<RountangleR
         }
     }
 
-    onPointerDown = (event: React.PointerEvent<HTMLDivElement>) => {
+    onPointerDown = (event: React.PointerEvent<SVGSVGElement>) => {
         // only left mouse button
         if (event.button !== 0) return;
 
@@ -44,7 +48,7 @@ export class RountangleResizeHandleComponent extends React.Component<RountangleR
         event.preventDefault();
     }
 
-    onPointerMove = (event: React.PointerEvent<HTMLDivElement>) => {
+    onPointerMove = (event: React.PointerEvent<SVGSVGElement>) => {
         if (!this.state.dragging) return;
 
         this.props.onResize(event.movementX, event.movementY);
@@ -53,7 +57,7 @@ export class RountangleResizeHandleComponent extends React.Component<RountangleR
         event.preventDefault();
     }
 
-    onPointerUp = (event: React.PointerEvent<HTMLDivElement>) => {
+    onPointerUp = (event: React.PointerEvent<SVGSVGElement>) => {
         event.currentTarget.releasePointerCapture(event.pointerId);
         event.stopPropagation();
         event.preventDefault();
@@ -68,11 +72,19 @@ export class RountangleResizeHandleComponent extends React.Component<RountangleR
     }
 
     render() {
-        return <div
-            className={'re-rountangle-resize-handle'}
+        return <svg
+            x={this.props.x + this.props.width - 16}
+            y={this.props.y + this.props.height - 16}
+            width={15}
+            height={15}
+            className="re-rountangle-resize-handle"
             onPointerDown={this.onPointerDown}
             onPointerMove={this.onPointerMove}
             onPointerUp={this.onPointerUp}
-        />
+        >
+            <polygon
+                points={"15,0 15,15, 0,15"}
+            />
+        </svg>
     }
 }