Trying new pinch to zoom mode

This commit is contained in:
2024-07-25 15:46:38 +02:00
parent 4b901a87d7
commit 1c9812c3a8
7 changed files with 68 additions and 20 deletions

View File

@@ -31,10 +31,12 @@ const results = computed(() => {
</div>
<Teleport to="body" v-if="input !== ''">
<div class="search-results" :style="{top: (pos.bottom + 4) + 'px', left: pos.left + 'px', width: pos.width + 'px'}">
<div class="suggestion-item" v-if="results.length > 0" v-for="result of results" :key="result._path" @mouseenter="(e) => (e.target as HTMLElement).classList.add('is-selected')" @mouseleave="(e) => (e.target as HTMLElement).classList.remove('is-selected')" @mousedown="navigateTo('/explorer' + result._path); input = ''">
<div class="suggestion-item" v-if="results.length > 0" v-for="result of results" :key="result._path" @mouseenter="(e) => (e.target as HTMLElement).classList.add('is-selected')" @mouseleave="(e) => (e.target as HTMLElement).classList.remove('is-selected')" @mousedown.prevent="navigateTo('/explorer' + result._path); input = ''">
<div class="suggestion-content">
<div class="suggestion-title">
{{ result.title.substring(0, clear(result.title).indexOf(clear(input))) }}<span class="suggestion-highlight">{{ result.title.substring(clear(result.title).indexOf(clear(input)), clear(result.title).indexOf(clear(input)) + clear(input).length + 1) }}</span>{{ result.title.substring(clear(result.title).indexOf(clear(input)) + clear(input).length + 1) }}
<ProseA :href="result._path">
{{ result.title.substring(0, clear(result.title).indexOf(clear(input))) }}<span class="suggestion-highlight">{{ result.title.substring(clear(result.title).indexOf(clear(input)), clear(result.title).indexOf(clear(input)) + clear(input).length + 1) }}</span>{{ result.title.substring(clear(result.title).indexOf(clear(input)) + clear(input).length + 1) }}
</ProseA>
</div>
</div>
</div>

View File

@@ -25,7 +25,7 @@ function darken(rgb: string): boolean
const props = defineProps<Props>();
const classes: any = { 'canvas-node-group': props.node.type === 'group', 'is-themed': props.node.color !== undefined, 'mod-canvas-color-custom': (props.node?.color?.startsWith('#') ?? false) };
const classes: Record<string, boolean> = { 'canvas-node-group': props.node.type === 'group', 'is-themed': props.node.color !== undefined, 'mod-canvas-color-custom': (props.node?.color?.startsWith('#') ?? false) };
const size = Math.max(props.node.width, props.node.height);
if(props.node.color !== undefined)

View File

@@ -14,6 +14,8 @@ let centerX = ref(0), centerY = ref(0), canvas = ref<HTMLDivElement>();
let minX = ref(+Infinity), minY = ref(+Infinity), maxX = ref(-Infinity), maxY = ref(-Infinity);
let bbox = ref<DOMRect>();
let lastPinchLength = 0;
let _minX = +Infinity, _minY = +Infinity, _maxX = -Infinity, _maxY = -Infinity;
onMounted(async () => {
@@ -66,7 +68,7 @@ const onPointerDown = (event: PointerEvent) => {
}
const onPointerMove = (event: PointerEvent) => {
if (event.isPrimary === false) return;
if (event.isPrimary === false || dragging === false) return;
dispX.value -= (posX - event.clientX) / zoom.value;
dispY.value -= (posY - event.clientY) / zoom.value;
@@ -79,11 +81,39 @@ const onPointerUp = (event: PointerEvent) => {
dragging = false;
document.removeEventListener('pointermove', onPointerMove);
document.removeEventListener('pointerup', onPointerUp);
document.removeEventListener('pointercancel', onPointerUp);
}
const onWheel = (event: WheelEvent) => {
zoom.value = clamp(zoom.value * 1 + (event.deltaY * -0.001), minZoom.value, 3);
zoom.value = clamp(zoom.value + (event.deltaY * -0.001), minZoom.value, 3);
}
const onTouchStart = (event: TouchEvent) => {
if(event.touches?.length === 2)
{
dragging = false;
lastPinchLength = length(event.touches[0].clientX, event.touches[0].clientY, event.touches[1].clientX, event.touches[1].clientY);
document.addEventListener('touchmove', onTouchMove);
document.addEventListener('touchend', onTouchEnd);
}
}
const onTouchEnd = (event: TouchEvent) => {
if(event.touches?.length !== 2)
dragging = true;
document.removeEventListener('touchmove', onTouchMove);
document.removeEventListener('touchend', onTouchEnd);
}
const onTouchMove = (event: TouchEvent) => {
if(event.touches?.length === 2)
{
const l = length(event.touches[0].clientX, event.touches[0].clientY, event.touches[1].clientX, event.touches[1].clientY);
zoom.value = clamp(zoom.value + ((lastPinchLength - l) * -0.01), minZoom.value, 3);
lastPinchLength = l;
}
}
const reset = (_: MouseEvent) => {
@@ -98,6 +128,9 @@ function clamp(x: number, min: number, max: number): number {
return min;
return x;
}
function length(x1: number, y1: number, x2: number, y2: number): number {
return Math.sqrt((x2 - x1)^2 + (y2 - y1)^2);
}
function edgePos(side: 'bottom' | 'top' | 'left' | 'right', pos: { x: number, y: number }, n: number): { x: number, y: number } {
switch (side) {
case "left":
@@ -180,7 +213,7 @@ function getCenter(n: { x: number, y: number }, i: { x: number, y: number }, r:
</script>
<template>
<div ref="canvas" @pointerdown="onPointerDown" @wheel.passive="onWheel" @touchstart.prevent="" @dragstart.prevent=""
<div ref="canvas" @pointerdown="onPointerDown" @wheel.passive="onWheel" @touchstart.prevent="onTouchStart" @dragstart.prevent=""
class="canvas-wrapper node-insert-event mod-zoomed-out"
:style="{ '--zoom-multiplier': (1 / Math.pow(zoom, 0.7)) }">
<div class="canvas-controls" style="z-index: 999;">