使用视图宽度和高度定位的问题

问题描述 投票:0回答:0

我正在尝试解决 React 挑战。挑战是当你点击屏幕上的某个地方时,你点击的地方会出现一个圆圈。您还有一个重做和撤消按钮。问题发生在以下限制条件下:

  1. 圆圈必须响应(圆圈总是圆的)。
  2. 必须在光标所在的位置创建一个圆,因此光标位于圆的中心,具有任意屏幕宽度和高度。
  3. 当您单击靠近撤消/重做按钮或边框时,将跳过第二条规则,因为您需要圆圈完全位于屏幕内。

它应该是这样的:

我解决了第一个,宽度和高度等于 vw 中的相同值。 我还解决了第二个从位置减去圆宽度的一半。 但是对于最后一个,我在顶部和底部边界上遇到了问题。当屏幕宽度改变时,圆圈会移动。

顶部和底部的圆圈应该分别粘在按钮和底部边框上,但它们不是。

这是我的代码:

App.tsx

const pointSize = 5

export const App: FC = () => {
    const [points, setPoints] = useState<IPoint[]>([])

    const controlsRef = useRef<HTMLDivElement>(null)

    const handlePlacePoint = (e: React.MouseEvent) => {
        const offsetX = pointSize / 2
        const offsetY = pointSize / 2
        let x = (e.clientX / window.innerWidth) * 100
        let y = (e.clientY / window.innerHeight) * 100

        const controlsHeight =
            (controlsRef.current?.offsetHeight! / window.innerHeight) * 100

        if (x <= offsetX) {
            x = offsetX
        } else if (x >= 100 - offsetX) {
            x = 100 - offsetX
        }

        if (y <= controlsHeight + offsetY) {
            y = controlsHeight + offsetY
        } else if (y >= 100 - offsetY) {
            y = 100 - offsetY
        }

        const newPoint: IPoint = {
            x,
            y,
            color: generateColor(),
            size: pointSize
        }

        setPoints([...points, newPoint])
    }

    return (
        <main>
            <div className='controls' ref={controlsRef}>
                <button>Undo ↺</button>
                <button>Redo ↻</button>
            </div>
            <div
                className='points-panel'
                onClick={handlePlacePoint}
                style={{ backgroundColor: '#8b3ae0' }}
            >
                {points.map(point => (
                    <Point key={Math.random()} {...point} />
                ))}
            </div>
        </main>
    )
}

Point.tsx

export const Point: FC<IPoint> = ({ x, y, size, color }) => {
    return (
        <div
            className='point'
            style={{
                backgroundColor: color,
                top: `calc(${y}vh - ${size / 2}vw)`,
                left: `calc(${x}vw - ${size / 2}vw)`,
                width: `${size}vw`,
                height: `${size}vw`
            }}
        />
    )
}

App.css

.controls {
    position: absolute;
    z-index: 1;
    width: 100vw;
    height: 5vh;
    display: flex;
}

.controls button {
    flex-grow: 1;
    font-size: 25px;
}

.pointsPanel {
    position: relative;
    height: 100vh;
    width: 100vw;
}

.point {
    position: absolute;
    border-radius: 100%;
    border: 2px solid #000;
}

index.css

html,
body, 
* {
    margin: 0;
    box-sizing: border-box;
}

body {
    overflow: hidden;
}

我尝试了很多不同的方法,但我想我错过了 vh 中的 Point top 值减去 vw 中的值。我不知道如何改变它而不是破坏已经有效的东西。你能告诉我如何修复它以便它满足所有 3 个要求吗?或者也许有更干净的方法?

css reactjs responsive-design position responsive
© www.soinside.com 2019 - 2024. All rights reserved.