浏览代码

implement zooming

Jakob Pietron 2 年之前
父节点
当前提交
7f597dd9e0

+ 5 - 4
src/frontend/rountangleEditor/RountangleComponent.tsx

@@ -7,6 +7,7 @@ import {PrimitiveValue} from "../../onion/types";
 export interface RountangleProps extends Rountangle {
     id:       PrimitiveValue;
     dispatch: (action: RountangleAction) => void;
+    zoom:     number;
 }
 
 export interface RountangleState {
@@ -62,8 +63,8 @@ export class RountangleComponent extends React.Component<RountangleProps, Rounta
         if (event.movementX !== 0 || event.movementY !== 0) {
             this.setState({
                 moved: true,
-                movementsX: this.state.movementsX + event.movementX,
-                movementsY: this.state.movementsY + event.movementY
+                movementsX: this.state.movementsX + event.movementX * this.props.zoom,
+                movementsY: this.state.movementsY + event.movementY * this.props.zoom
             });
         }
 
@@ -111,8 +112,8 @@ export class RountangleComponent extends React.Component<RountangleProps, Rounta
     onResize = (deltaHeight: number, deltaWidth: number) => {
         if (deltaHeight !== 0 || deltaWidth !== 0) {
             this.setState({
-                resizeWidth:  this.state.resizeWidth  + deltaHeight,
-                resizeHeight: this.state.resizeHeight + deltaWidth
+                resizeWidth:  this.state.resizeWidth  + deltaHeight * this.props.zoom,
+                resizeHeight: this.state.resizeHeight + deltaWidth * this.props.zoom
             });
         }
     }

+ 42 - 25
src/frontend/rountangleEditor/RountangleEditor.tsx

@@ -83,11 +83,15 @@ export interface RountangleEditorProps {
 }
 
 interface RountangleEditorState {
-    translateX: number;
-    translateY: number;
-    zoom:       number;
-    dragging:   boolean;
-    moved:      boolean;
+    baseWidth:     number;
+    currentWidth:  number;
+    baseHeight:    number;
+    currentHeight: number;
+    translateX:    number;
+    translateY:    number;
+    zoom:          number;
+    dragging:      boolean;
+    moved:         boolean;
 }
 
 export class RountangleEditor extends React.Component<RountangleEditorProps, RountangleEditorState> {
@@ -99,6 +103,10 @@ export class RountangleEditor extends React.Component<RountangleEditorProps, Rou
         this.canvasRef = React.createRef<SVGSVGElement>();
         this.onDispatchListeners = new Set();
         this.state = {
+            baseWidth: 350,
+            baseHeight: 350,
+            currentHeight: 350,
+            currentWidth: 350,
             translateX: 0,
             translateY: 0,
             zoom: 1.0,
@@ -214,8 +222,8 @@ export class RountangleEditor extends React.Component<RountangleEditorProps, Rou
 
         if (event.movementY !== 0 ||event.movementX !== 0) {
             this.setState({
-                translateX: this.state.translateX - event.movementX,
-                translateY: this.state.translateY - event.movementY,
+                translateX: this.state.translateX - event.movementX * this.state.zoom,
+                translateY: this.state.translateY - event.movementY * this.state.zoom,
                 moved:      true
             });
         }
@@ -224,27 +232,32 @@ export class RountangleEditor extends React.Component<RountangleEditorProps, Rou
         event.preventDefault();
     }
 
+    private clickToSVGPos = (x:number, y: number): DOMPoint | undefined => {
+        // point transformation adapted from https://stackoverflow.com/a/70595400
+        if (!this.canvasRef.current) return undefined;
+
+        const screenCTM = this.canvasRef.current.getScreenCTM();
+        if (screenCTM === null) return undefined;
+
+        const refPoint = new DOMPoint(x, y);
+        return refPoint.matrixTransform(screenCTM.inverse());
+    }
+
     onPointerUp = (event: React.PointerEvent<SVGSVGElement>) => {
         event.stopPropagation();
         event.preventDefault();
         event.currentTarget.releasePointerCapture(event.pointerId);
 
-        console.log('hier');
-
         this.setState({
             dragging: false,
             moved:    false
         });
 
         // add new state on left mouse button and ALT-Key pressed
-        if (event.button === 0 && event.altKey && this.canvasRef.current) {
-            // point transformation adapted from https://stackoverflow.com/a/70595400
-            const refPoint = new DOMPoint(event.clientX, event.clientY);
-            const screenCTM = this.canvasRef.current.getScreenCTM();
-
-            if (screenCTM !== null) {
-                const cursorPoint = refPoint.matrixTransform(screenCTM.inverse())
+        if (event.button === 0 && event.altKey) {
+            const cursorPoint = this.clickToSVGPos(event.clientX, event.clientY);
 
+            if (cursorPoint) {
                 const newRountangleName = prompt('Name', 'New Rountangle');
                 if (newRountangleName) {
                     this.dispatch({
@@ -258,20 +271,23 @@ export class RountangleEditor extends React.Component<RountangleEditorProps, Rou
                         name: newRountangleName});
                 }
             }
-
         }
     }
 
     onWheel = (event: WheelEvent) => {
         event.preventDefault();
         event.stopPropagation();
-        return;
-        if (event.deltaY > 0) {
-            this.setState({zoom: Math.min(this.state.zoom * 1.1, 5)})
-        }
-        else {
-            this.setState({zoom: Math.min(this.state.zoom * 0.9, 5)})
-        }
+        if (event.deltaY === 0) return;
+        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
+        })
     }
 
     render() {
@@ -283,7 +299,7 @@ export class RountangleEditor extends React.Component<RountangleEditorProps, Rou
                    onPointerUp={this.onPointerUp}
                    width='350px'
                    height='100%'
-                   viewBox={`${this.state.translateX} ${this.state.translateY} 350 ${this.canvasRef.current?.viewBox.baseVal.width ?? 100}`}
+                   viewBox={`${this.state.translateX} ${this.state.translateY} ${this.state.currentWidth} ${this.state.currentHeight}`}
                    ref={this.canvasRef}
                >
                    {
@@ -301,6 +317,7 @@ export class RountangleEditor extends React.Component<RountangleEditorProps, Rou
                                 posZ={rountangle.posZ}
                                 width={rountangle.width}
                                 height={rountangle.height}
+                                zoom={this.state.zoom}
                                 dispatch={this.dispatch}
                             />
                        })