Skip to content

Commit

Permalink
Add initial implementation for pinch to zoom based on existing scale …
Browse files Browse the repository at this point in the history
…factor
  • Loading branch information
matthiaslehnertum committed Sep 26, 2023
1 parent 220018d commit e2dda36
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 4 deletions.
57 changes: 55 additions & 2 deletions src/main/components/canvas/canvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,82 @@ import { UMLElementComponent } from '../uml-element/uml-element-component';
import { CanvasContainer } from './canvas-styles';
import { UMLElementState } from '../../services/uml-element/uml-element-types';
import { UMLRelationship } from '../../services/uml-relationship/uml-relationship';
import {EditorRepository} from '../../services/editor/editor-repository';

const MIN_SCALE: number = 0.5;
const MAX_SCALE: number = 5.0;

type OwnProps = {};

type StateProps = {
diagram: IUMLDiagram;
isStatic: boolean;
elements: UMLElementState;
scale: number;
};

type DispatchProps = {};
type DispatchProps = {
changeScale: typeof EditorRepository.changeScale;
};

type Props = OwnProps & StateProps & DispatchProps;

const initialState = Object.freeze({
gestureStartScale: 1.0 as number
});


const enhance = connect<StateProps, DispatchProps, OwnProps, ModelState>(
(state) => ({
diagram: state.diagram,
isStatic: state.editor.readonly,
elements: state.elements,
scale: state.editor.scale
}),
null,
{
changeScale: EditorRepository.changeScale,
},
null,
{ forwardRef: true },
);

export class CanvasComponent extends Component<Props> implements Omit<ILayer, 'layer'> {
state = initialState;

layer: RefObject<SVGSVGElement> = createRef();

componentDidMount() {

const {scale = 1} = this.props;

window.addEventListener('wheel', (event) => {
event.preventDefault();

if (event.ctrlKey) {
this.props.changeScale(this.clamp(scale - event.deltaY * 0.01, MIN_SCALE, MAX_SCALE));
}
});


window.addEventListener('gesturestart', (event) => {
event.preventDefault();

this.setState({
...this.state,
gestureStartZoomFactor: scale
});
});

window.addEventListener('gesturechange', (event) => {
event.preventDefault();
this.props.changeScale(this.clamp(this.state.gestureStartScale * (event as any).scale, MIN_SCALE, MAX_SCALE));
});

window.addEventListener('gestureend', function (event) {
event.preventDefault();
});
}

origin = (): Point => {
if (!this.layer.current) {
return new Point();
Expand All @@ -52,6 +101,10 @@ export class CanvasComponent extends Component<Props> implements Omit<ILayer, 'l
return point.subtract(origin).round().add(origin);
};

clamp = (value: number, min: number, max: number) : number => {
return Math.max(min, Math.min(value, max));
};

render() {
const { elements, diagram, isStatic } = this.props;

Expand Down
8 changes: 8 additions & 0 deletions src/main/services/editor/editor-reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ export const EditorReducer: Reducer<EditorState, Actions> = (state = initialStat
view: payload.view,
};
}
case EditorActionTypes.CHANGE_SCALE: {
const { payload } = action;

return {
...state,
scale: payload.scale,
};
}
}
return state;
};
7 changes: 6 additions & 1 deletion src/main/services/editor/editor-repository.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { ApollonView, ChangeViewAction, EditorActionTypes } from './editor-types';
import {ApollonView, ChangeScaleAction, ChangeViewAction, EditorActionTypes} from './editor-types';

export class EditorRepository {
static changeView = (view: ApollonView): ChangeViewAction => ({
type: EditorActionTypes.CHANGE_VIEW,
payload: { view },
undoable: false,
});
static changeScale = (scale: number): ChangeScaleAction => ({
type: EditorActionTypes.CHANGE_SCALE,
payload: { scale },
undoable: false,
});
}
9 changes: 8 additions & 1 deletion src/main/services/editor/editor-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const enum ApollonView {

export const enum EditorActionTypes {
CHANGE_VIEW = '@@element/CHANGE_VIEW',
CHANGE_SCALE = '@@element/CHANGE_SCALE',
}

export type EditorState = {
Expand All @@ -33,10 +34,16 @@ export type EditorState = {
readonly scale: number;
};

export type EditorActions = ChangeViewAction;
export type EditorActions = ChangeViewAction | ChangeScaleAction;

export type ChangeViewAction = Action<EditorActionTypes.CHANGE_VIEW> & {
payload: {
view: ApollonView;
};
};

export type ChangeScaleAction = Action<EditorActionTypes.CHANGE_SCALE> & {
payload: {
scale: number;
};
};

0 comments on commit e2dda36

Please sign in to comment.