react canvas.scale 在设置时似乎表现不正确
react canvas.scale doesn't seem to behaving correctly when being set
我有一个组件可以创建一个 canvas 另一个组件,另一个组件可以控制事件发生在它身上的事情:
const Parent = () => {
const [canvasRef, zoom, setZoom] = useCanvas();
const onMouseWheel = (e) => {
let tmpZoom = zoom + (e.deltaY / 1000);
setZoom(tmpZoom);
}
return (
<canvas
ref={canvasRef}
width={canvasDimentions.width} // 1080
height={canvasDimentions.height} // 1920
onWheelCapture={onMouseWheel}
/>
);
}
const useCanvas = () => {
const [zoom, setZoom] = useState(1);
const canvasRef = useRef(null);
useEffect(() => {
const canvasObj = canvasRef.current;
const ctx = canvasObj.getContext('2d');
ctx.clearRect(0, 0, canvasDimentions.width * zoom, canvasDimentions.height * zoom); // width * height intial 1920, 1080
console.log(zoom);
ctx.scale(zoom, zoom)
drawSquare(); // draws a simple 100 x 100 square
},[zoom])
return [canvasRef, zoom, setZoom];
}
每当我这样做时发生的事情是缩放设置正确(缩放值在我的 console.log(zoom)
内正确地缓慢增加,当我向相反方向滚动时减小。
我在 ctx.scale(zoom, zoom)
中遇到的奇怪行为是假设我缩小:(1, 0.9, 0.8 .. 等) 然后向另一个方向放大 (0.8, 0.9, 1, 1.1 ...等)它会继续缩小而不是以另一种方式(返回)放大,或者它会随机跳到正确的值。
我知道 useState
是异步的,但如果是这样的话,我的 console.log 缩放比例在通过它之前如何每次都是正确的?
这与 reactjs 无关,这就是 2D 上下文 scale
方法的工作方式。
ctx.scale(x, y)
确实采用当前变换矩阵并将其 scaleX
和 scaleY
成员乘以 x
和 y
。
因此,如果您先调用 scale(0.7, 0.7)
,然后再调用 scale(0.8, 0.8)
,即使第二次调用实际上也会使上下文的变换变小:
一开始scaleX和Y是1
,在第一次调用时它们变成了0.7
( 1 x 0.7), 然后它们变成 0.56
(0.7 x 0.8).
也许您更喜欢 setTransform
绝对设置变换矩阵的方法。
使用这种方法你可以做到
ctx.setTransform(zoom, 0, 0, zoom, 0, 0);
这里从 0.7
到 0.8
会产生您预期的放大结果。
我有一个组件可以创建一个 canvas 另一个组件,另一个组件可以控制事件发生在它身上的事情:
const Parent = () => {
const [canvasRef, zoom, setZoom] = useCanvas();
const onMouseWheel = (e) => {
let tmpZoom = zoom + (e.deltaY / 1000);
setZoom(tmpZoom);
}
return (
<canvas
ref={canvasRef}
width={canvasDimentions.width} // 1080
height={canvasDimentions.height} // 1920
onWheelCapture={onMouseWheel}
/>
);
}
const useCanvas = () => {
const [zoom, setZoom] = useState(1);
const canvasRef = useRef(null);
useEffect(() => {
const canvasObj = canvasRef.current;
const ctx = canvasObj.getContext('2d');
ctx.clearRect(0, 0, canvasDimentions.width * zoom, canvasDimentions.height * zoom); // width * height intial 1920, 1080
console.log(zoom);
ctx.scale(zoom, zoom)
drawSquare(); // draws a simple 100 x 100 square
},[zoom])
return [canvasRef, zoom, setZoom];
}
每当我这样做时发生的事情是缩放设置正确(缩放值在我的 console.log(zoom)
内正确地缓慢增加,当我向相反方向滚动时减小。
我在 ctx.scale(zoom, zoom)
中遇到的奇怪行为是假设我缩小:(1, 0.9, 0.8 .. 等) 然后向另一个方向放大 (0.8, 0.9, 1, 1.1 ...等)它会继续缩小而不是以另一种方式(返回)放大,或者它会随机跳到正确的值。
我知道 useState
是异步的,但如果是这样的话,我的 console.log 缩放比例在通过它之前如何每次都是正确的?
这与 reactjs 无关,这就是 2D 上下文 scale
方法的工作方式。
ctx.scale(x, y)
确实采用当前变换矩阵并将其 scaleX
和 scaleY
成员乘以 x
和 y
。
因此,如果您先调用 scale(0.7, 0.7)
,然后再调用 scale(0.8, 0.8)
,即使第二次调用实际上也会使上下文的变换变小:
一开始scaleX和Y是1
,在第一次调用时它们变成了0.7
( 1 x 0.7), 然后它们变成 0.56
(0.7 x 0.8).
也许您更喜欢 setTransform
绝对设置变换矩阵的方法。
使用这种方法你可以做到
ctx.setTransform(zoom, 0, 0, zoom, 0, 0);
这里从 0.7
到 0.8
会产生您预期的放大结果。