Fix trackpad pinch-to-zoom on Safari macOS
This commit is contained in:
parent
13a95bf517
commit
5e209eca1c
|
|
@ -1,5 +1,11 @@
|
|||
# Changelog
|
||||
|
||||
## 0.2.2 (2026-03-01)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Fix trackpad pinch-to-zoom on Safari macOS
|
||||
|
||||
## 0.2.1 (2026-03-01)
|
||||
|
||||
### UI
|
||||
|
|
|
|||
1
components.d.ts
vendored
1
components.d.ts
vendored
|
|
@ -63,7 +63,6 @@ declare module 'vue' {
|
|||
IconLucideLink: typeof import('~icons/lucide/link')['default']
|
||||
IconLucideLoaderCircle: typeof import('~icons/lucide/loader-circle')['default']
|
||||
IconLucideMessageCircle: typeof import('~icons/lucide/message-circle')['default']
|
||||
IconLucidePanelLeft: typeof import('~icons/lucide/panel-left')['default']
|
||||
IconLucidePlus: typeof import('~icons/lucide/plus')['default']
|
||||
IconLucideRadius: typeof import('~icons/lucide/radius')['default']
|
||||
IconLucideRotateCcw: typeof import('~icons/lucide/rotate-ccw')['default']
|
||||
|
|
|
|||
2
desktop/Cargo.lock
generated
2
desktop/Cargo.lock
generated
|
|
@ -2466,7 +2466,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "open_pencil"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
dependencies = [
|
||||
"font-kit",
|
||||
"serde",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "open_pencil"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
description = "A Tauri App"
|
||||
authors = ["you"]
|
||||
edition = "2021"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "OpenPencil",
|
||||
"version": "0.2.1",
|
||||
"version": "0.2.2",
|
||||
"identifier": "net.dannote.open-pencil",
|
||||
"build": {
|
||||
"beforeDevCommand": "bun run dev",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "open-pencil-app",
|
||||
"private": true,
|
||||
"version": "0.2.1",
|
||||
"version": "0.2.2",
|
||||
"type": "module",
|
||||
"workspaces": [
|
||||
"packages/*"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@open-pencil/cli",
|
||||
"version": "0.2.1",
|
||||
"version": "0.2.2",
|
||||
"type": "module",
|
||||
"bin": {
|
||||
"open-pencil": "./src/index.ts"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@open-pencil/core",
|
||||
"version": "0.2.1",
|
||||
"version": "0.2.2",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
|
|
|
|||
|
|
@ -1047,6 +1047,7 @@ export function useCanvasInput(
|
|||
}
|
||||
|
||||
// Touch support for iOS/mobile: single-finger pan, two-finger pinch-zoom
|
||||
const isTouchDevice = matchMedia('(pointer: coarse)').matches
|
||||
let activeTouches: Touch[] = []
|
||||
let pinchStartDist = 0
|
||||
let pinchStartZoom = 0
|
||||
|
|
@ -1058,6 +1059,7 @@ export function useCanvasInput(
|
|||
}
|
||||
|
||||
function onTouchStart(e: TouchEvent) {
|
||||
if (!isTouchDevice) return
|
||||
e.preventDefault()
|
||||
activeTouches = Array.from(e.touches)
|
||||
const canvas = canvasRef.value
|
||||
|
|
@ -1084,6 +1086,7 @@ export function useCanvasInput(
|
|||
}
|
||||
|
||||
function onTouchMove(e: TouchEvent) {
|
||||
if (!isTouchDevice) return
|
||||
e.preventDefault()
|
||||
activeTouches = Array.from(e.touches)
|
||||
const canvas = canvasRef.value
|
||||
|
|
@ -1122,6 +1125,7 @@ export function useCanvasInput(
|
|||
}
|
||||
|
||||
function onTouchEnd(e: TouchEvent) {
|
||||
if (!isTouchDevice) return
|
||||
e.preventDefault()
|
||||
activeTouches = Array.from(e.touches)
|
||||
|
||||
|
|
@ -1155,6 +1159,31 @@ export function useCanvasInput(
|
|||
useEventListener(canvasRef, 'touchend', onTouchEnd, { passive: false })
|
||||
useEventListener(canvasRef, 'touchcancel', onTouchEnd, { passive: false })
|
||||
|
||||
// Safari macOS: trackpad pinch-to-zoom uses gesture events, not wheel+ctrlKey
|
||||
let gestureStartZoom = 1
|
||||
useEventListener(canvasRef, 'gesturestart' as keyof HTMLElementEventMap, (e: Event) => {
|
||||
e.preventDefault()
|
||||
gestureStartZoom = store.state.zoom
|
||||
}, { passive: false })
|
||||
useEventListener(canvasRef, 'gesturechange' as keyof HTMLElementEventMap, (e: Event) => {
|
||||
e.preventDefault()
|
||||
const ge = e as GestureEvent
|
||||
const canvas = canvasRef.value
|
||||
if (!canvas) return
|
||||
const rect = canvas.getBoundingClientRect()
|
||||
const sx = (ge.clientX ?? rect.width / 2) - rect.left
|
||||
const sy = (ge.clientY ?? rect.height / 2) - rect.top
|
||||
const newZoom = Math.max(0.02, Math.min(256, gestureStartZoom * ge.scale))
|
||||
const zoomRatio = newZoom / store.state.zoom
|
||||
store.state.panX = sx - (sx - store.state.panX) * zoomRatio
|
||||
store.state.panY = sy - (sy - store.state.panY) * zoomRatio
|
||||
store.state.zoom = newZoom
|
||||
store.requestRepaint()
|
||||
}, { passive: false })
|
||||
useEventListener(canvasRef, 'gestureend' as keyof HTMLElementEventMap, (e: Event) => {
|
||||
e.preventDefault()
|
||||
}, { passive: false })
|
||||
|
||||
return {
|
||||
drag,
|
||||
cursorOverride
|
||||
|
|
|
|||
7
src/global.d.ts
vendored
7
src/global.d.ts
vendored
|
|
@ -1,3 +1,10 @@
|
|||
interface GestureEvent extends UIEvent {
|
||||
scale: number
|
||||
rotation: number
|
||||
clientX: number
|
||||
clientY: number
|
||||
}
|
||||
|
||||
interface FilePickerAcceptType {
|
||||
description: string
|
||||
accept: Record<string, string[]>
|
||||
|
|
|
|||
|
|
@ -37,10 +37,7 @@ useEventListener(
|
|||
{ passive: false }
|
||||
)
|
||||
|
||||
// Prevent Safari's native pinch-zoom gesture on the page
|
||||
useEventListener(document, 'gesturestart', (e: Event) => e.preventDefault(), { passive: false })
|
||||
useEventListener(document, 'gesturechange', (e: Event) => e.preventDefault(), { passive: false })
|
||||
useEventListener(document, 'gestureend', (e: Event) => e.preventDefault(), { passive: false })
|
||||
|
||||
|
||||
const params = useUrlSearchParams('history')
|
||||
const showChrome = !('no-chrome' in params)
|
||||
|
|
|
|||
Loading…
Reference in a new issue