react konva 在舞台上放大时保持一层固定

问题描述

我正在 Konva 中开发地图(绿色矩形)和在其上绘制的路径(黑线):

enter image description here

地图具有固定尺寸,而路径是从 API 调用获取的。

我希望能够使用鼠标滚动或单击我创建的按钮 + o 来缩放地图。

我按照这个例子 how to react-konva zooming on scroll 来实现缩放,但是当我滚动时,按钮也会改变它们的位置,见下图。

enter image description here

我想让按钮固定在地图的底部

这是我的一段代码,我定义了一些自定义组件为MapGroundWholePathGroundButtons em> 和 按钮

export const Map = ( props ) => {
    const [mouseScale,setMouseScale] = useState(1);
    const [x0,setX0] = useState(0);
    const [y0,setY0] = useState(0);

    const scaleBy = 1.02;
    const handleWheel = (e)  => {
      const group = e.target.getStage();
      e.evt.preventDefault();
      const mousePointTo = {
        x: group.getPointerPosition().x / mouseScale - group.x() / mouseScale,y: group.getPointerPosition().y / mouseScale - group.y() / mouseScale
      };
      const newScale = e.evt.deltaY < 0 ? mouseScale * scaleBy : mouseScale / scaleBy;
      setMouseScale(newScale);
      setX0(-(mousePointTo.x - group.getPointerPosition().x / newScale) * newScale );
      setY0(-(mousePointTo.y - group.getPointerPosition().y / newScale) * newScale );
    };

    const SimulateMouseWheel = (e,BtnType,mScale = scaleBy) => {
      const newScale = BtnType > 0 ? mouseScale * mScale : mouseScale / mScale;
      setMouseScale(newScale);
    };

    const onClickPlus = (e) => {
        SimulateMouseWheel(e,+1,1.08);
    };

    const onClickMinus = (e) => {
        SimulateMouseWheel(e,-1,1.08);
    };

    return (
        <Stage
            width={800}
            height={400}
            draggable={true}
            onWheel={handleWheel}
            scaleX={mouseScale}
            scaleY={mouseScale}
            x={x0}
            y={y0}
        >
            <Layer>
                <Ground pitch={props.pitch}/>
                <WholePath path={props.path}/>
            </Layer>
            <Layer>
                <GroundButtons reference={props.reference} onClickMinus={onClickMinus} onClickPlus={onClickPlus} />
            </Layer>
        </Stage>
    )
}


const GroundButtons = ( props ) => {
    return (
        <Group>
            <Button xText={10} yText={5} text={"+"} x={790} y={360}  side={30} onClick={props.onClickPlus}/>
            <Button xText={12} yText={5} text={"-"} x={790} y={360}  side={30} onClick={props.onClickMinus}/>
        </Group>
    )
}

const Button = props => {
    return (
            <Group x={props.x} y={props.y} onClick={props.onClick}>
                <Rect
                    width={props.side}
                    height={props.side}
                    fill='#f2f1f0'
                    stroke='#777'
                    strokeWidth={1}
                />
                <Text
                  x={props.xText}
                  y={props.yText}
                  fontSize={20}
                  text={props.text}
                  stroke='#777'
                  align="center"
                  strokeWidth={1}
                />
            </Group>
    )
}

这是我实施的解决方案: 感谢 Ondolin 的回答。

export const Map = ( props ) => {
    const [mouseScale,1.08);
    };

    return (
        <div>
        <Stage
            width={800}
            height={400}
            draggable={true}
            onWheel={handleWheel}
            scaleX={mouseScale}
            scaleY={mouseScale}
            x={x0}
            y={y0}
        >
            <Layer>
                <Ground pitch={props.pitch}/>
                <WholePath path={props.path}/>
            </Layer>
            <Layer>
                <GroundButtons reference={props.reference} onClickMinus={onClickMinus} onClickPlus={onClickPlus} />
            </Layer>
        </Stage>
            <button className="ground_controls" onClick={onClickPlus}><i className="fa fa-plus" aria-hidden="true"></i></button>
            <button className="ground_controls" onClick={onClickMinus}><i className="fa fa-minus" aria-hidden="true"></i></button>
        </div>
    )
}

解决方法

我强烈建议您不要使用在画布(舞台)上绘制的按钮。您应该使用标准的 HTML 按钮。您可以使用 css (Positon absolute) 将它们放置在舞台顶部。

如果你这样做,对你有很多好处。例如。您可以更轻松、更好地设计它。另外,效率更高,也解决了这个问题。