Skip to content

Commit

Permalink
Add mouse drag panning support and align wheel behavior with KiCad (#85)
Browse files Browse the repository at this point in the history
* Add mouse drag panning support and align wheel behavior with KiCad

* Clean up unnecessary code and comments
  • Loading branch information
sago35 committed May 24, 2024
1 parent 5c38d14 commit 97060a1
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 11 deletions.
71 changes: 61 additions & 10 deletions src/base/dom/pan-and-zoom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
*/

import { BBox, Camera2, Vec2 } from "../math";
import { Preferences } from "../../kicanvas/preferences";

const line_delta_multiplier = 8;
const page_delta_multiplier = 24;
const zoom_speed = 0.005;
const pan_speed = 1;

export type PanAndZoomCallback = () => void;
const prefs = Preferences.INSTANCE;

/**
* Interactive Pan and Zoom helper
Expand Down Expand Up @@ -84,6 +86,38 @@ export class PanAndZoom {
startDistance = null;
startPosition = null;
});

let dragStartPosition: Vec2 | null = null;
let dragging = false;

this.target.addEventListener("mousedown", (e: MouseEvent) => {
if (e.button === 1 || e.button === 2) {
e.preventDefault();
dragging = true;
dragStartPosition = new Vec2(e.clientX, e.clientY);
}
});

this.target.addEventListener("mousemove", (e: MouseEvent) => {
if (dragging && dragStartPosition !== null) {
const currentPosition = new Vec2(e.clientX, e.clientY);
const delta = currentPosition.sub(dragStartPosition);
this.#handle_pan(-delta.x, -delta.y);
dragStartPosition = currentPosition;
}
});

this.target.addEventListener("mouseup", (e: MouseEvent) => {
if (e.button === 1 || e.button === 2) {
dragging = false;
dragStartPosition = null;
}
});

// Prevent the browser's default context menu.
this.target.addEventListener("contextmenu", (e) => {
e.preventDefault();
});
}

#getDistanceBetweenTouches(touches: TouchList) {
Expand All @@ -102,8 +136,14 @@ export class PanAndZoom {
let dy = e.deltaY;

// shift modifier flips the X and Y axes (horizontal scroll)
if (dx == 0 && e.shiftKey) {
[dx, dy] = [dy, dx];
if (!prefs.alignControlsWithKiCad) {
if (dx == 0 && e.shiftKey) {
[dx, dy] = [dy, dx];
}
} else {
if (dx == 0 && e.ctrlKey) {
[dx, dy] = [dy, dx];
}
}

// work around line/page scrolling
Expand All @@ -119,14 +159,25 @@ export class PanAndZoom {
dx = Math.sign(dx) * Math.min(page_delta_multiplier, Math.abs(dx));
dy = Math.sign(dy) * Math.min(page_delta_multiplier, Math.abs(dy));

// pinch zoom
if (e.ctrlKey) {
this.#rect = this.target.getBoundingClientRect();
this.#handle_zoom(dy, this.#relative_mouse_pos(e));
}
// pan
else {
this.#handle_pan(dx, dy);
if (!prefs.alignControlsWithKiCad) {
// pinch zoom
if (e.ctrlKey) {
this.#rect = this.target.getBoundingClientRect();
this.#handle_zoom(dy, this.#relative_mouse_pos(e));
}
// pan
else {
this.#handle_pan(dx, dy);
}
} else {
if (e.shiftKey || e.ctrlKey) {
this.#handle_pan(-dx, dy);
}
// pinch zoom
else {
this.#rect = this.target.getBoundingClientRect();
this.#handle_zoom(dy, this.#relative_mouse_pos(e));
}
}

this.target.dispatchEvent(
Expand Down
18 changes: 17 additions & 1 deletion src/kicanvas/elements/common/preferences-panel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,14 @@ export class KCPreferencesPanel extends KCUIElement {

override initialContentCallback() {
this.renderRoot.addEventListener("input", (e) => {
prefs.theme = themes.by_name(this.theme_control.value);
const target = e.target as HTMLInputElement;

if (target.name === "theme") {
prefs.theme = themes.by_name(this.theme_control.value);
}
if (target.name === "align-controls-kicad") {
prefs.alignControlsWithKiCad = target.checked;
}
prefs.save();
});
}
Expand All @@ -89,6 +96,15 @@ export class KCPreferencesPanel extends KCUIElement {
</select>
</kc-ui-control>
</kc-ui-control-list>
<kc-ui-control>
<label>
<input
type="checkbox"
name="align-controls-kicad"
checked="${prefs.alignControlsWithKiCad}" />
Align controls with KiCad
</label>
</kc-ui-control>
</kc-ui-panel-body>
</kc-ui-panel>
`;
Expand Down
6 changes: 6 additions & 0 deletions src/kicanvas/preferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,22 @@ export class Preferences extends EventTarget {
private storage = new LocalStorage("kc:prefs");

public theme: Theme = themes.default;
public alignControlsWithKiCad: boolean = true;

public save() {
this.storage.set("theme", this.theme.name);
this.storage.set("alignControlsWithKiCad", this.alignControlsWithKiCad);
this.dispatchEvent(new PreferencesChangeEvent({ preferences: this }));
}

public load() {
this.theme = themes.by_name(
this.storage.get("theme", themes.default.name),
);
this.alignControlsWithKiCad = this.storage.get(
"alignControlsWithKiCad",
false,
);
}
}

Expand Down

0 comments on commit 97060a1

Please sign in to comment.