Skip to content

Commit

Permalink
fix: PuruVJ#61 - allow three different ways of dealing with the problem
Browse files Browse the repository at this point in the history
  • Loading branch information
Raiondesu committed Sep 20, 2023
1 parent 6965d57 commit 4ad6b66
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 1 deletion.
21 changes: 21 additions & 0 deletions docs/src/documentation/options/touchAction/+option.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
title: touchAction
type: 'Property.TouchAction | ((el: HTMLElement, setTouchAction: (action: Property.TouchAction) => void) => void)'
defaultValue: 'none'
---

import Code from '$components/options/OptionsCode.astro';
import Example from '$components/options/OptionsExample.astro';
import Examples from '$components/options/OptionsExamples.svelte';

export const shortDescription =
'Choose when and how to set "touch-action" style for mobile devices';

<p>{shortDescription}</p>

By default, the "touch-action" style is set to `none` upon initalizing the draggable on an element.

This option allows to change the default to some other value in a number of ways:
1. Simply set to another value for any draggable elements that use this draggable instance.
2. Set to different values based on amount of pixels the element was dragged.
3. Set a callback to assign the property to a different value for a specific element based on any arbitrary logic.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
"brotli-size": "^4.0.0",
"csstype": "^3.1.2",
"fast-glob": "^3.2.12",
"jsdom": "^21.1.0",
"nx": "15.7.2",
Expand Down
45 changes: 44 additions & 1 deletion packages/core/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { Property } from 'csstype';

export type DragBoundsCoords = {
/** Number of pixels from left of the document */
left: number;
Expand Down Expand Up @@ -182,6 +184,14 @@ export type DragOptions = {
*/
handle?: string | HTMLElement | HTMLElement[];

/**
* Choose when and how to set touch action for mobile devices
*/
touchAction?:
| Property.TouchAction
| Partial<Record<number, Property.TouchAction>>
| ((el: HTMLElement, setTouchAction: (action: Property.TouchAction) => void) => void);

/**
* Class to apply on the element on which `use:draggable` is applied.
* Note that if `handle` is provided, it will still apply class on the element to which this action is applied, **NOT** the handle
Expand Down Expand Up @@ -258,6 +268,8 @@ export const draggable = (node: HTMLElement, options: DragOptions = {}) => {
cancel,
handle,

touchAction = 'none',

defaultClass = DEFAULT_CLASS.MAIN,
defaultClassDragging = DEFAULT_CLASS.DRAGGING,
defaultClassDragged = DEFAULT_CLASS.DRAGGED,
Expand Down Expand Up @@ -361,8 +373,32 @@ export const draggable = (node: HTMLElement, options: DragOptions = {}) => {
listen('pointerup', dragEnd, false);
listen('pointermove', drag, false);

let setTouchAction: undefined | ((threshold: number) => void) = undefined;

// On mobile, touch can become extremely janky without it
setStyle(node, 'touch-action', 'none');
if (typeof touchAction === 'function') {
touchAction(node, (action) => setStyle(node, 'touch-action', action))
} else if (typeof touchAction === 'string') {
setStyle(node, 'touch-action', touchAction);
} else {
const thresholds = Object.keys(touchAction).map(threshold => Number(threshold)).sort();

setTouchAction = (threshold: number) => {
const crossedThreshold = thresholds.find(value => threshold >= value);

if (
typeof touchAction !== 'object' ||
typeof crossedThreshold !== 'number' ||
(typeof touchAction === 'object' && !(crossedThreshold in touchAction))
) return;

const touchActionValue = touchAction[crossedThreshold];

if (typeof touchActionValue !== 'string') return;

setStyle(node, 'touch-action', touchActionValue);
};
}

const calculateInverseScale = () => {
// Calculate the current scale of the node
Expand Down Expand Up @@ -507,6 +543,13 @@ export const draggable = (node: HTMLElement, options: DragOptions = {}) => {
xOffset = translateX;
yOffset = translateY;

if (setTouchAction) {
const initialVector = (initialX * initialX + initialY * initialY);
const finalVector = (finalX * finalX + finalY * finalY);

setTouchAction(finalVector - initialVector);
}

fireSvelteDragEvent();

setTranslate();
Expand Down

0 comments on commit 4ad6b66

Please sign in to comment.