我正在尝试解决 React 挑战。挑战是当你点击屏幕上的某个地方时,你点击的地方会出现一个圆圈。您还有一个重做和撤消按钮。问题发生在以下限制条件下:
我解决了第一个,宽度和高度等于 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 个要求吗?或者也许有更干净的方法?