Improve menu swipe detection
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
// Dead zone before the swipe action gets detected
|
// Dead zone before the swipe action gets detected
|
||||||
const swipe_inital_offset = 25
|
const swipe_initial_offset = 25
|
||||||
// Amount of pixels after which the navigation triggers
|
// Amount of pixels after which the navigation triggers
|
||||||
const swipe_trigger_offset = 75
|
const swipe_trigger_offset = 75
|
||||||
|
|
||||||
@@ -38,8 +38,8 @@ export const swipe_nav = (
|
|||||||
|
|
||||||
// The cursor must have moved at least 50 pixels and three times as much
|
// The cursor must have moved at least 50 pixels and three times as much
|
||||||
// on the x axis than the y axis for it to count as a swipe
|
// on the x axis than the y axis for it to count as a swipe
|
||||||
if (abs_x > swipe_inital_offset && abs_y < abs_x / 3) {
|
if (abs_x > swipe_initial_offset && abs_y < abs_x / 3) {
|
||||||
set_offset((abs_x - swipe_inital_offset) * neg, false)
|
set_offset((abs_x - swipe_initial_offset) * neg, false)
|
||||||
} else {
|
} else {
|
||||||
set_offset(0, true)
|
set_offset(0, true)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,21 @@ import Tree from "./Tree.svelte";
|
|||||||
import MenuEntry from "./MenuEntry.svelte";
|
import MenuEntry from "./MenuEntry.svelte";
|
||||||
import { writable } from "svelte/store";
|
import { writable } from "svelte/store";
|
||||||
|
|
||||||
|
// The menu swipe will be detected if it was less than this much pixels from the
|
||||||
|
// screen edge
|
||||||
|
const screen_edge_offset = 50
|
||||||
|
|
||||||
|
// Dead zone before the swipe action gets detected
|
||||||
|
const swipe_dead_zone = screen_edge_offset/4
|
||||||
|
|
||||||
|
// If the screen is less wide than this, the menu will appear full screen
|
||||||
|
const min_screen_size_fullscreen_menu = 500
|
||||||
|
|
||||||
|
// If the screen is smaller than this the menu will be closed by default
|
||||||
|
const min_screen_size_menu_open = 800
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
if (document.documentElement.clientWidth < 1000) {
|
if (document.documentElement.clientWidth < min_screen_size_menu_open) {
|
||||||
menu_close()
|
menu_close()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,21 +46,20 @@ onMount(() => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// Dead zone before the swipe action gets detected
|
|
||||||
const swipe_initial_offset = 50
|
|
||||||
const min_screen_size_fullscreen_menu = 500
|
|
||||||
|
|
||||||
let menu: HTMLDivElement
|
let menu: HTMLDivElement
|
||||||
let nav: HTMLElement
|
let nav: HTMLElement
|
||||||
let dragging: boolean = false
|
let dragging: boolean = false
|
||||||
let start_x: number
|
let start_x: number
|
||||||
|
let start_y: number
|
||||||
let render_offset: number
|
let render_offset: number
|
||||||
let initial_offset: number
|
let initial_offset: number
|
||||||
const touchstart = (e: TouchEvent) => {
|
const touchstart = (e: TouchEvent) => {
|
||||||
start_x = e.touches[0].clientX
|
start_x = e.touches[0].clientX
|
||||||
|
start_y = e.touches[0].clientY
|
||||||
const rect = menu.getBoundingClientRect()
|
const rect = menu.getBoundingClientRect()
|
||||||
if (start_x < Math.max(swipe_initial_offset, (rect.width+rect.left))) {
|
if (start_x < Math.max(screen_edge_offset, (rect.width+rect.left))) {
|
||||||
dragging = true
|
dragging = true
|
||||||
|
e.stopPropagation()
|
||||||
}
|
}
|
||||||
|
|
||||||
render_offset = rect.left
|
render_offset = rect.left
|
||||||
@@ -58,7 +70,19 @@ const touchmove = (e: TouchEvent) => {
|
|||||||
if (!dragging) {
|
if (!dragging) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
set_offset(initial_offset+(e.touches[0].clientX - start_x))
|
|
||||||
|
const x = e.touches[0].clientX - start_x
|
||||||
|
const y = e.touches[0].clientY - start_y
|
||||||
|
const abs_x = Math.abs(x)
|
||||||
|
const abs_y = Math.abs(y)
|
||||||
|
|
||||||
|
// The cursor must have moved at least swipe_dead_zone pixels and three
|
||||||
|
// times as much on the x axis than the y axis for it to count as a swipe
|
||||||
|
if (abs_x > swipe_dead_zone && abs_x / 3 > abs_y) {
|
||||||
|
set_offset(initial_offset+(x*2))
|
||||||
|
} else {
|
||||||
|
set_offset(initial_offset)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const touchend = (e: TouchEvent) => {
|
const touchend = (e: TouchEvent) => {
|
||||||
@@ -112,7 +136,7 @@ const menu_close = () => {
|
|||||||
const set_offset = (off: number) => {
|
const set_offset = (off: number) => {
|
||||||
render_offset = off
|
render_offset = off
|
||||||
|
|
||||||
if (off > -swipe_initial_offset) {
|
if (off > -swipe_dead_zone) {
|
||||||
// Clear the transformation if the offset is zero
|
// Clear the transformation if the offset is zero
|
||||||
menu.style.transform = ""
|
menu.style.transform = ""
|
||||||
} else {
|
} else {
|
||||||
@@ -123,8 +147,11 @@ const set_offset = (off: number) => {
|
|||||||
|
|
||||||
<svelte:window ontouchstart={touchstart} ontouchmove={touchmove} ontouchend={touchend}/>
|
<svelte:window ontouchstart={touchstart} ontouchmove={touchmove} ontouchend={touchend}/>
|
||||||
|
|
||||||
<button class="button_toggle_navigation" onclick={toggle_menu}>
|
<button class="menu_button" onclick={toggle_menu}>
|
||||||
<i class="icon">menu</i>
|
<i class="icon">menu</i>
|
||||||
|
{#if $menu_is_open}
|
||||||
|
<span>Menu</span>
|
||||||
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="nav_container" bind:this={menu}>
|
<div class="nav_container" bind:this={menu}>
|
||||||
@@ -225,7 +252,7 @@ const set_offset = (off: number) => {
|
|||||||
background-repeat: var(--background_image_repeat, repeat);
|
background-repeat: var(--background_image_repeat, repeat);
|
||||||
background-attachment: fixed;
|
background-attachment: fixed;
|
||||||
}
|
}
|
||||||
.button_toggle_navigation {
|
.menu_button {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
backface-visibility: hidden;
|
backface-visibility: hidden;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
@@ -236,10 +263,10 @@ const set_offset = (off: number) => {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
border-bottom-right-radius: 0px;
|
border-bottom-right-radius: 4px;
|
||||||
border-bottom-right-radius: 2px;
|
|
||||||
backdrop-filter: blur(6px);
|
backdrop-filter: blur(6px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav_container {
|
.nav_container {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
border-right: 1px solid var(--separator);
|
border-right: 1px solid var(--separator);
|
||||||
@@ -259,8 +286,6 @@ const set_offset = (off: number) => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 15em;
|
width: 15em;
|
||||||
min-width: 10em;
|
|
||||||
max-width: 15em;
|
|
||||||
padding-top: 2em;
|
padding-top: 2em;
|
||||||
}
|
}
|
||||||
.nav > .button {
|
.nav > .button {
|
||||||
|
|||||||
Reference in New Issue
Block a user