|
@@ -1,7 +1,5 @@
|
|
|
-import { isSafari, modulate } from '@tldraw/core'
|
|
|
+import { modulate, clamp } from '@tldraw/core'
|
|
|
import { observer } from 'mobx-react-lite'
|
|
|
-import { transparentize } from 'polished'
|
|
|
-import React from 'react'
|
|
|
import { useRendererContext } from '../../../hooks'
|
|
|
import type { TLGridProps } from '../../../types'
|
|
|
|
|
@@ -27,7 +25,9 @@ const SVGGrid = observer(function CanvasGrid({ size }: TLGridProps) {
|
|
|
const yo = point[1] * zoom
|
|
|
const gxo = xo > 0 ? xo % s : s + (xo % s)
|
|
|
const gyo = yo > 0 ? yo % s : s + (yo % s)
|
|
|
- const opacity = zoom < mid ? modulate(zoom, [min, mid], [0, 1]) : 1
|
|
|
+ const opacity = modulate(zoom, [min, mid], [0, 1])
|
|
|
+
|
|
|
+ const hide = opacity > 2 || opacity < 0.1
|
|
|
|
|
|
return (
|
|
|
<pattern
|
|
@@ -37,7 +37,9 @@ const SVGGrid = observer(function CanvasGrid({ size }: TLGridProps) {
|
|
|
height={s}
|
|
|
patternUnits="userSpaceOnUse"
|
|
|
>
|
|
|
- <circle className={`tl-grid-dot`} cx={gxo} cy={gyo} r={1.5} opacity={opacity} />
|
|
|
+ {!hide && (
|
|
|
+ <circle className={`tl-grid-dot`} cx={gxo} cy={gyo} r={1.5} opacity={clamp(opacity, 0, 1)} />
|
|
|
+ )}
|
|
|
</pattern>
|
|
|
)
|
|
|
})}
|
|
@@ -49,91 +51,6 @@ const SVGGrid = observer(function CanvasGrid({ size }: TLGridProps) {
|
|
|
)
|
|
|
})
|
|
|
|
|
|
-// Grid is slow to render. Maybe we render it using canvas?
|
|
|
-const CanvasGrid = observer(function Grid({ size }: TLGridProps) {
|
|
|
- const {
|
|
|
- viewport: {
|
|
|
- camera: { point, zoom },
|
|
|
- bounds,
|
|
|
- },
|
|
|
- } = useRendererContext()
|
|
|
-
|
|
|
- const ref = React.useRef<HTMLCanvasElement>(null)
|
|
|
-
|
|
|
- // Use useEffect will cause the render flickering
|
|
|
- React.useLayoutEffect(() => {
|
|
|
- if (ref.current) {
|
|
|
- const canvas = ref.current
|
|
|
- if (canvas?.getContext) {
|
|
|
- const fillColor = getComputedStyle(canvas)
|
|
|
- .getPropertyValue('--ls-quaternary-background-color')
|
|
|
- .trim()
|
|
|
- const ctx = canvas.getContext('2d')
|
|
|
- if (ctx && fillColor) {
|
|
|
- const { width, height } = canvas
|
|
|
- // fill the canvas with dots
|
|
|
- ctx.clearRect(0, 0, width, height)
|
|
|
-
|
|
|
- const xo = point[0] * zoom
|
|
|
- const yo = point[1] * zoom
|
|
|
-
|
|
|
- STEPS.forEach(([min, mid, _size]) => {
|
|
|
- const s = _size * size * zoom
|
|
|
- const gxo = xo > 0 ? xo % s : s + (xo % s)
|
|
|
- const gyo = yo > 0 ? yo % s : s + (yo % s)
|
|
|
- const opacity = zoom < mid ? modulate(zoom, [min, mid], [0, 1], true) : 1
|
|
|
- ctx.fillStyle = transparentize(1 - opacity, fillColor)
|
|
|
-
|
|
|
- if (opacity < 0.5 || s < 32) return
|
|
|
- for (let i = gyo; i < height; i += s) {
|
|
|
- for (let j = gxo; j < width; j += s) {
|
|
|
- ctx.beginPath()
|
|
|
- ctx.arc(j, i, 1.5, 0, 2 * Math.PI)
|
|
|
- ctx.closePath()
|
|
|
- ctx.fill()
|
|
|
- }
|
|
|
- }
|
|
|
- // Pattern should have better performance, but I cannot make the offset correctly ...
|
|
|
- // for (let i = 0; i < height; i += _size) {
|
|
|
- // const y = i * _size
|
|
|
- // for (let j = 0; j < width; j += _size) {
|
|
|
- // const x = j * _size
|
|
|
- // ctx.fillRect(x, y, _size, _size)
|
|
|
- // }
|
|
|
- // }
|
|
|
- // const pattern = document.createElement('canvas').getContext('2d')
|
|
|
- // if (pattern) {
|
|
|
- // const s = _size * size * zoom
|
|
|
- // if (s < 1) {
|
|
|
- // return
|
|
|
- // }
|
|
|
- // const xo = point[0] * zoom
|
|
|
- // const yo = point[1] * zoom
|
|
|
- // const gxo = xo > 0 ? xo % s : s + (xo % s)
|
|
|
- // const gyo = yo > 0 ? yo % s : s + (yo % s)
|
|
|
- // const opacity = zoom < mid ? modulate(zoom, [min, mid], [0, 1]) : 1
|
|
|
- // pattern.canvas.width = s
|
|
|
- // pattern.canvas.height = s
|
|
|
- // pattern.beginPath()
|
|
|
- // pattern.arc(gxo, gyo, 1.5, 0, 2 * Math.PI)
|
|
|
- // pattern.fillStyle = transparentize(1 - opacity, fillColor)
|
|
|
- // pattern.fill()
|
|
|
- // pattern.closePath()
|
|
|
- // ctx.fillStyle = ctx.createPattern(pattern.canvas, 'repeat')!
|
|
|
- // ctx.fillRect(0, 0, width, height)
|
|
|
- // }
|
|
|
- })
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }, [point[0], point[1], zoom, bounds.width, bounds.height])
|
|
|
-
|
|
|
- return <canvas ref={ref} width={bounds.width} height={bounds.height} className="tl-grid-canvas" />
|
|
|
-})
|
|
|
-
|
|
|
export const Grid = observer(function Grid({ size }: TLGridProps) {
|
|
|
- if (isSafari()) {
|
|
|
- return <CanvasGrid size={size} />
|
|
|
- }
|
|
|
return <SVGGrid size={size} />
|
|
|
})
|