improves appearance on safari

This commit is contained in:
Steve Ruiz 2021-05-28 14:08:51 +01:00
parent 8dfef5c302
commit 708223fffa
8 changed files with 103 additions and 14 deletions

View file

@ -20,7 +20,7 @@ export default function Bounds() {
if (!bounds) return null if (!bounds) return null
if (!isSelecting) return null if (!isSelecting) return null
const size = (isMobile().any ? 16 : 8) / zoom // Touch target size const size = (isMobile().any ? 12 : 8) / zoom // Touch target size
return ( return (
<g <g

View file

@ -0,0 +1,25 @@
import { getShapeUtils } from "lib/shape-utils"
import { useSelector } from "state"
import { deepCompareArrays, getPage } from "utils/utils"
export default function Defs() {
const currentPageShapeIds = useSelector(({ data }) => {
return Object.values(getPage(data).shapes)
.sort((a, b) => a.childIndex - b.childIndex)
.map((shape) => shape.id)
}, deepCompareArrays)
return (
<defs>
{currentPageShapeIds.map((id) => (
<Def key={id} id={id} />
))}
</defs>
)
}
export function Def({ id }: { id: string }) {
const shape = useSelector(({ data }) => getPage(data).shapes[id])
return getShapeUtils(shape).render(shape)
}

View file

@ -6,14 +6,14 @@ import { getShapeUtils } from "lib/shape-utils"
import { getPage } from "utils/utils" import { getPage } from "utils/utils"
function Shape({ id }: { id: string }) { function Shape({ id }: { id: string }) {
const rGroup = useRef<SVGGElement>(null)
const isHovered = useSelector((state) => state.data.hoveredId === id) const isHovered = useSelector((state) => state.data.hoveredId === id)
const isSelected = useSelector((state) => state.values.selectedIds.has(id)) const isSelected = useSelector((state) => state.values.selectedIds.has(id))
const shape = useSelector(({ data }) => getPage(data).shapes[id]) const shape = useSelector(({ data }) => getPage(data).shapes[id])
const rGroup = useRef<SVGGElement>(null)
const handlePointerDown = useCallback( const handlePointerDown = useCallback(
(e: React.PointerEvent) => { (e: React.PointerEvent) => {
e.stopPropagation() e.stopPropagation()
@ -72,9 +72,9 @@ function Shape({ id }: { id: string }) {
onPointerMove={handlePointerMove} onPointerMove={handlePointerMove}
> >
<defs>{getShapeUtils(shape).render(shape)}</defs> <defs>{getShapeUtils(shape).render(shape)}</defs>
<HoverIndicator as="use" xlinkHref={"#" + id} /> <HoverIndicator as="use" href={"#" + id} />
<MainShape as="use" xlinkHref={"#" + id} {...shape.style} /> <MainShape as="use" href={"#" + id} {...shape.style} />
<Indicator as="use" xlinkHref={"#" + id} /> <Indicator as="use" href={"#" + id} />
</StyledGroup> </StyledGroup>
) )
} }

View file

@ -2,6 +2,7 @@ import React, { useEffect, useRef } from "react"
import state from "state" import state from "state"
import inputs from "state/inputs" import inputs from "state/inputs"
import * as vec from "utils/vec" import * as vec from "utils/vec"
import { usePinch } from "react-use-gesture"
/** /**
* Capture zoom gestures (pinches, wheels and pans) and send to the state. * Capture zoom gestures (pinches, wheels and pans) and send to the state.
@ -65,5 +66,36 @@ export default function useZoomEvents(
} }
}, [ref]) }, [ref])
return {} const rPinchDa = useRef<number[] | undefined>(undefined)
const rPinchAngle = useRef<number>(undefined)
const rPinchPoint = useRef<number[] | undefined>(undefined)
const bind = usePinch(({ pinching, da, origin }) => {
if (!pinching) {
state.send("STOPPED_PINCHING")
rPinchDa.current = undefined
rPinchPoint.current = undefined
return
}
if (rPinchPoint.current === undefined) {
state.send("STARTED_PINCHING")
rPinchDa.current = da
rPinchPoint.current = origin
}
const [distanceDelta, angleDelta] = vec.sub(rPinchDa.current, da)
state.send("PINCHED", {
delta: vec.sub(rPinchPoint.current, origin),
point: origin,
distanceDelta,
angleDelta,
})
rPinchDa.current = da
rPinchPoint.current = origin
})
return { ...bind() }
} }

View file

@ -21,6 +21,7 @@
"react": "17.0.2", "react": "17.0.2",
"react-dom": "17.0.2", "react-dom": "17.0.2",
"react-feather": "^2.0.9", "react-feather": "^2.0.9",
"react-use-gesture": "^9.1.3",
"uuid": "^8.3.2" "uuid": "^8.3.2"
}, },
"devDependencies": { "devDependencies": {

View file

@ -130,6 +130,7 @@ const state = createState({
STRETCHED: "stretchSelection", STRETCHED: "stretchSelection",
DISTRIBUTED: "distributeSelection", DISTRIBUTED: "distributeSelection",
MOVED: "moveSelection", MOVED: "moveSelection",
STARTED_PINCHING: { to: "pinching" },
}, },
initial: "notPointing", initial: "notPointing",
states: { states: {
@ -248,6 +249,12 @@ const state = createState({
}, },
}, },
}, },
pinching: {
on: {
STOPPED_PINCHING: { to: "selecting" },
PINCHED: { do: "pinchCamera" },
},
},
draw: { draw: {
initial: "creating", initial: "creating",
states: { states: {
@ -829,12 +836,31 @@ const state = createState({
setZoomCSS(camera.zoom) setZoomCSS(camera.zoom)
}, },
panCamera(data, payload: { delta: number[]; point: number[] }) { panCamera(data, payload: { delta: number[] }) {
const { camera } = data const { camera } = data
data.camera.point = vec.sub( camera.point = vec.sub(camera.point, vec.div(payload.delta, camera.zoom))
camera.point, },
vec.div(payload.delta, camera.zoom) pinchCamera(
) data,
payload: {
delta: number[]
distanceDelta: number
angleDelta: number
point: number[]
}
) {
const { camera } = data
camera.point = vec.sub(camera.point, vec.div(payload.delta, camera.zoom))
const next = camera.zoom - (payload.distanceDelta / 300) * camera.zoom
const p0 = screenToWorld(payload.point, data)
camera.zoom = clamp(next, 0.1, 3)
const p1 = screenToWorld(payload.point, data)
camera.point = vec.add(camera.point, vec.sub(p1, p0))
setZoomCSS(camera.zoom)
}, },
deleteSelectedIds(data) { deleteSelectedIds(data) {
commands.deleteSelected(data) commands.deleteSelected(data)

View file

@ -45,7 +45,7 @@ const { styled, global, css, theme, getCssString } = createCss({
zStrokeWidth: () => (value: number | number[]) => { zStrokeWidth: () => (value: number | number[]) => {
if (Array.isArray(value)) { if (Array.isArray(value)) {
return { return {
strokeWidth: `calc(${value[0]} / var(--camera-zoom))`, strokeWidth: `calc(${value[0]}px / var(--camera-zoom))`,
} }
} }
@ -61,7 +61,7 @@ const { styled, global, css, theme, getCssString } = createCss({
// } // }
return { return {
strokeWidth: `calc(${value} / var(--camera-zoom))`, strokeWidth: `calc(${value}px / var(--camera-zoom))`,
} }
}, },
}, },

View file

@ -6697,6 +6697,11 @@ react-style-singleton@^2.1.0:
invariant "^2.2.4" invariant "^2.2.4"
tslib "^1.0.0" tslib "^1.0.0"
react-use-gesture@^9.1.3:
version "9.1.3"
resolved "https://registry.yarnpkg.com/react-use-gesture/-/react-use-gesture-9.1.3.tgz#92bd143e4f58e69bd424514a5bfccba2a1d62ec0"
integrity sha512-CdqA2SmS/fj3kkS2W8ZU8wjTbVBAIwDWaRprX7OKaj7HlGwBasGEFggmk5qNklknqk9zK/h8D355bEJFTpqEMg==
react@17.0.2: react@17.0.2:
version "17.0.2" version "17.0.2"
resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"