improves appearance on safari
This commit is contained in:
parent
8dfef5c302
commit
708223fffa
8 changed files with 103 additions and 14 deletions
|
@ -20,7 +20,7 @@ export default function Bounds() {
|
|||
if (!bounds) 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 (
|
||||
<g
|
||||
|
|
25
components/canvas/defs.tsx
Normal file
25
components/canvas/defs.tsx
Normal 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)
|
||||
}
|
|
@ -6,14 +6,14 @@ import { getShapeUtils } from "lib/shape-utils"
|
|||
import { getPage } from "utils/utils"
|
||||
|
||||
function Shape({ id }: { id: string }) {
|
||||
const rGroup = useRef<SVGGElement>(null)
|
||||
|
||||
const isHovered = useSelector((state) => state.data.hoveredId === id)
|
||||
|
||||
const isSelected = useSelector((state) => state.values.selectedIds.has(id))
|
||||
|
||||
const shape = useSelector(({ data }) => getPage(data).shapes[id])
|
||||
|
||||
const rGroup = useRef<SVGGElement>(null)
|
||||
|
||||
const handlePointerDown = useCallback(
|
||||
(e: React.PointerEvent) => {
|
||||
e.stopPropagation()
|
||||
|
@ -72,9 +72,9 @@ function Shape({ id }: { id: string }) {
|
|||
onPointerMove={handlePointerMove}
|
||||
>
|
||||
<defs>{getShapeUtils(shape).render(shape)}</defs>
|
||||
<HoverIndicator as="use" xlinkHref={"#" + id} />
|
||||
<MainShape as="use" xlinkHref={"#" + id} {...shape.style} />
|
||||
<Indicator as="use" xlinkHref={"#" + id} />
|
||||
<HoverIndicator as="use" href={"#" + id} />
|
||||
<MainShape as="use" href={"#" + id} {...shape.style} />
|
||||
<Indicator as="use" href={"#" + id} />
|
||||
</StyledGroup>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import React, { useEffect, useRef } from "react"
|
|||
import state from "state"
|
||||
import inputs from "state/inputs"
|
||||
import * as vec from "utils/vec"
|
||||
import { usePinch } from "react-use-gesture"
|
||||
|
||||
/**
|
||||
* Capture zoom gestures (pinches, wheels and pans) and send to the state.
|
||||
|
@ -65,5 +66,36 @@ export default function useZoomEvents(
|
|||
}
|
||||
}, [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() }
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
"react": "17.0.2",
|
||||
"react-dom": "17.0.2",
|
||||
"react-feather": "^2.0.9",
|
||||
"react-use-gesture": "^9.1.3",
|
||||
"uuid": "^8.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -130,6 +130,7 @@ const state = createState({
|
|||
STRETCHED: "stretchSelection",
|
||||
DISTRIBUTED: "distributeSelection",
|
||||
MOVED: "moveSelection",
|
||||
STARTED_PINCHING: { to: "pinching" },
|
||||
},
|
||||
initial: "notPointing",
|
||||
states: {
|
||||
|
@ -248,6 +249,12 @@ const state = createState({
|
|||
},
|
||||
},
|
||||
},
|
||||
pinching: {
|
||||
on: {
|
||||
STOPPED_PINCHING: { to: "selecting" },
|
||||
PINCHED: { do: "pinchCamera" },
|
||||
},
|
||||
},
|
||||
draw: {
|
||||
initial: "creating",
|
||||
states: {
|
||||
|
@ -829,12 +836,31 @@ const state = createState({
|
|||
|
||||
setZoomCSS(camera.zoom)
|
||||
},
|
||||
panCamera(data, payload: { delta: number[]; point: number[] }) {
|
||||
panCamera(data, payload: { delta: number[] }) {
|
||||
const { camera } = data
|
||||
data.camera.point = vec.sub(
|
||||
camera.point,
|
||||
vec.div(payload.delta, camera.zoom)
|
||||
)
|
||||
camera.point = vec.sub(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) {
|
||||
commands.deleteSelected(data)
|
||||
|
|
|
@ -45,7 +45,7 @@ const { styled, global, css, theme, getCssString } = createCss({
|
|||
zStrokeWidth: () => (value: number | number[]) => {
|
||||
if (Array.isArray(value)) {
|
||||
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 {
|
||||
strokeWidth: `calc(${value} / var(--camera-zoom))`,
|
||||
strokeWidth: `calc(${value}px / var(--camera-zoom))`,
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
|
@ -6697,6 +6697,11 @@ react-style-singleton@^2.1.0:
|
|||
invariant "^2.2.4"
|
||||
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:
|
||||
version "17.0.2"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
|
||||
|
|
Loading…
Reference in a new issue