Skip to content

Instantly share code, notes, and snippets.

@suhaotian
Last active November 23, 2019 17:46
Show Gist options
  • Save suhaotian/72bd877fa7858921cf5ae354fb38d843 to your computer and use it in GitHub Desktop.
Save suhaotian/72bd877fa7858921cf5ae354fb38d843 to your computer and use it in GitHub Desktop.
floating menu ball like iOS
import React, { useState, useRef } from 'react';
import { useSpring, animated } from 'react-spring';
import { useDrag } from 'react-use-gesture';
import { useWindowSize } from 'react-use';
function calcMinDirection(
x: number,
y: number,
w: number,
h: number,
parentWidth: number,
parentHeight: number
): string {
const headerThreshold = 0.2;
//let min = x
let min_dir = 'left';
if (parentWidth - x < x) {
//min = parentHeight - x
min_dir = 'right';
}
if (y < headerThreshold) {
// y < headerThreshold
min_dir = 'top';
}
if (parentHeight - y < h + headerThreshold) {
// height + headerThreshold
min_dir = 'bottom';
}
return min_dir;
}
function snapback(
direction: string,
x: number,
y: number,
w: number,
h: number,
parentWidth: number,
parentHeight: number
): Array<number> {
if (direction == 'left') {
x -= x;
}
if (direction == 'right') {
x -= x + w - parentWidth;
}
if (direction == 'top') {
y -= y;
}
if (direction == 'bottom') {
y -= y + h - parentHeight;
}
return [x, y];
}
export function DragBall(props: any) {
const { size, ...rest } = props;
const { width, height } = useWindowSize();
const ref = useRef({ x: 0, y: 0 }); // 缓存最后一次位置
const [style, set] = useSpring(() => ({ x: 0, y: 0, scale: 1 }));
const bind = useDrag(({ down, movement: [x, y] }) => {
const last = ref.current;
const xx = x + last.x,
yy = y + last.y;
if (down) {
set({
x: xx,
y: yy,
scale: 1.2,
});
} else {
const direction = calcMinDirection(xx, yy, size, size, width, height);
const [xxx, yyy] = snapback(direction, xx, yy, size, size, width, height);
last.x = xxx;
last.y = yyy;
set({
x: xxx,
y: yyy,
scale: 1,
});
}
});
return <animated.div {...bind()} style={style} {...rest} />;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment