請幫忙。 我有一個像下圖這樣的圖像顯示在主頁上(一個更大的圖像)。 請注意,「FORGE」房屋的中間有一個白色和藍色標記,並帶有黑色箭頭。
「出租」房屋也是如此。
這些標記中的每一個都將充當互動式按鈕。以下是預期的互動行為:
也希望它能夠響應,如果當螢幕調整大小時,按鈕應保留在這些特定位置。
我正在嘗試使用絕對定位、x、y 座標來嘗試使其工作。但由於我喜歡這類使用者介面的經驗,無法找到可行的解決方案。不確定我是否應該使用畫布或其他方法。
任何幫助將不勝感激。
我的程式碼看起來像這樣,但看起來我沒有走在正確的軌道上:
const ImageComponent = () => { const markers = [ { name: 'Forge', x: 100, y: 200 }, { name: 'Rentals', x: 300, y: 150 }, // Add more ]; const handleMarkerClick = (m) => { // do something with marker }; return ( <div style={{ position: 'relative' }}> <img src="path/to/image.jpg" alt="Image with markers" /> {markers.map((marker, index) => ( <div key={index} className="marker" style={{ left: marker.x, top: marker.y, position: "absolute" }} onClick={() => handleMarkerClick(marker)} /> ))} </div> ); };
P粉4125335252023-09-09 17:37:18
您應該將控制項放置在映像容器的絕對位置。 實現取決於多種因素,例如影像放置的位置、是否全螢幕顯示、影像之前或之後是否有內容等。 但這段程式碼應該要向您展示主要原理。
如果在調整視窗大小時調整影像大小,則應該建立一個與影像完全相同的容器。然後,您可以設定控制項相對於該容器的位置,並使它們固定在各自的點上。
.container { width: 60vw; /* set 100vw to fit image window width*/ position: relative; } .container img { width: 100%; display: block;} .container .control { position: absolute; width: 7.5%; /* size in percents to resize controls with image */ height: 7%; border-radius: 200px; background: red; transition: all 0.2s ease-in-out; } .container .control:hover { width: 20%; } #c1 { left: 50.4%; top: 26%; } /* position in percents, not in pixels */ #c2 { left: 58.5%; top: 76.3%; }
<div class="container"> <img src="https://i.stack.imgur.com/BVaY9.jpg"/> <div class="control" id="c1"></div> <div class="control" id="c2"></div> </div>
使用你的程式碼,它會是這樣的(但我建議在樣式檔案中移動你的樣式,學習如何在react中使用模組樣式):
const ImageComponent = () => { const markers = [ { name: 'Forge', x: 50.4, y: 26 }, { name: 'Rentals', x: 58.5, y: 76.3 }, // Add more ]; const handleMarkerClick = (m) => { // do something with marker }; return ( <div style={{ position: 'relative', width: '100vw' }}> <img style={{ width: '100%', display: 'block'}} src="path/to/image.jpg" alt="Image with markers" /> {markers.map((marker, index) => ( <div key={index} className="marker" style={{ left: `${marker.x}%`, top: `${marker.y}%`, position: "absolute" }} onClick={() => handleMarkerClick(marker)} /> ))} </div> ); };
只需修復位置並新增正常的控制視圖即可。
為了進行控制,您應該製作單獨的元件。以下是如何實現您想要的行為的範例:
.control { background: #08f; padding: 10px; width: 60px; box-sizing: border-box; border-radius: 200px; transition: all 0.2s ease-in-out; display: flex; align-items: center; overflow: hidden; cursor: pointer; } .control:hover { width: 200px; } .text { color: white; font: 30px Arial; margin-left: 16px; opacity: 0; transition: opacity 0.2s ease-in-out; } .control:hover .text { opacity: 1; } .icon { width: 40px; min-width: 40px; height: 40px; border-radius: 50%; box-shadow: 2px 2px 7px #0005; background-color: white; background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIFVwbG9hZGVkIHRvOiBTVkcgUmVwbywgd3d3LnN2Z3JlcG8uY29tLCBHZW5lcmF0b3I6IFNWRyBSZXBvIE1peGVyIFRvb2xzIC0tPgo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8c3ZnIGZpbGw9IiMwMDAwMDAiIGhlaWdodD0iODAwcHgiIHdpZHRoPSI4MDBweCIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiAKCSB2aWV3Qm94PSIwIDAgMjk3IDI5NyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxnPgoJPHBhdGggZD0iTTI5NC4wNzcsMjUxLjE5OWwtNTkuMTA1LTU5LjEwN2w0Mi4xNjctMjQuMzU2YzMuMjk1LTEuOTAzLDUuMjEyLTUuNTIsNC45MzgtOS4zMTVjLTAuMjc0LTMuNzk2LTIuNjkyLTcuMTAxLTYuMjI2LTguNTEKCQlMODcuODIsNzQuOTA1Yy0zLjY4Ni0xLjQ3Mi03Ljg5NS0wLjYwNS0xMC43MDIsMi4yMDFjLTIuODA3LDIuODA4LTMuNjc0LDcuMDE2LTIuMjAzLDEwLjcwMmw3NC45OTQsMTg4LjA1MwoJCWMxLjQxLDMuNTM0LDQuNzE1LDUuOTUzLDguNTExLDYuMjI3YzMuNzk2LDAuMjc2LDcuNDE0LTEuNjQyLDkuMzE2LTQuOTM4bDI0LjM1NC00Mi4xNjdsNTkuMTAxLDU5LjEwNwoJCWMxLjg2MiwxLjg2Myw0LjM5LDIuOTEsNy4wMjMsMi45MWMyLjYzNSwwLDUuMTYxLTEuMDQ3LDcuMDIzLTIuOTFsMjguODQxLTI4Ljg0NUMyOTcuOTU2LDI2MS4zNjYsMjk3Ljk1NiwyNTUuMDc4LDI5NC4wNzcsMjUxLjE5OQoJCXoiLz4KCTxwYXRoIGQ9Ik00My42MSwyOS41NTJjLTMuODc5LTMuODc2LTEwLjE2Ni0zLjg3Ny0xNC4wNDcsMGMtMy44NzgsMy44NzktMy44NzgsMTAuMTY4LDAsMTQuMDQ3bDIyLjA2OSwyMi4wNjkKCQljMS45MzksMS45MzksNC40OCwyLjkwOSw3LjAyMywyLjkwOWMyLjU0MSwwLDUuMDgzLTAuOTcsNy4wMjItMi45MDljMy44NzktMy44NzksMy44NzktMTAuMTY3LDAtMTQuMDQ2TDQzLjYxLDI5LjU1MnoiLz4KCTxwYXRoIGQ9Ik01MS4wODksOTguMjE1YzAtNS40ODQtNC40NDctOS45MzItOS45MzMtOS45MzJIOS45NDZjLTUuNDg1LDAtOS45MzMsNC40NDctOS45MzMsOS45MzJjMCw1LjQ4NSw0LjQ0Nyw5LjkzMyw5LjkzMyw5LjkzMwoJCWgzMS4yMUM0Ni42NDIsMTA4LjE0Nyw1MS4wODksMTAzLjcsNTEuMDg5LDk4LjIxNXoiLz4KCTxwYXRoIGQ9Ik00Ny4wNjMsMTI4Ljg2OWwtMjIuMDcyLDIyLjA3MWMtMy44NzgsMy44NzktMy44NzgsMTAuMTY4LDAsMTQuMDQ2YzEuOTQsMS45MzksNC40ODIsMi45MDksNy4wMjMsMi45MDkKCQljMi41NDEsMCw1LjA4NC0wLjk3LDcuMDIzLTIuOTA5bDIyLjA3MS0yMi4wN2MzLjg3OS0zLjg3OSwzLjg3OS0xMC4xNjgsMC0xNC4wNDdDNTcuMjMsMTI0Ljk5Myw1MC45NDQsMTI0Ljk5Miw0Ny4wNjMsMTI4Ljg2OXoiLz4KCTxwYXRoIGQ9Ik05OC4yMjIsNTEuMDc4YzUuNDg1LDAsOS45MzMtNC40NDcsOS45MzMtOS45MzNWOS45MzJjMC01LjQ4NS00LjQ0Ny05LjkzMi05LjkzMy05LjkzMmMtNS40ODQsMC05LjkzMiw0LjQ0Ni05LjkzMiw5LjkzMgoJCXYzMS4yMTRDODguMjksNDYuNjMxLDkyLjczNyw1MS4wNzgsOTguMjIyLDUxLjA3OHoiLz4KCTxwYXRoIGQ9Ik0xMzUuODk0LDY0LjAwNmMyLjU0MywwLDUuMDg0LTAuOTcsNy4wMjMtMi45MDlsMjIuMDY4LTIyLjA2OWMzLjg3OS0zLjg3OSwzLjg3OS0xMC4xNjgsMC0xNC4wNDcKCQljLTMuODc5LTMuODc3LTEwLjE2OC0zLjg3Ny0xNC4wNDYsMGwtMjIuMDY4LDIyLjA3Yy0zLjg3OSwzLjg3OS0zLjg3OSwxMC4xNjgsMCwxNC4wNDYKCQlDMTMwLjgxMSw2My4wMzYsMTMzLjM1Miw2NC4wMDYsMTM1Ljg5NCw2NC4wMDZ6Ii8+CjwvZz4KPC9zdmc+'); background-size: 60%; background-repeat: no-repeat; background-position: center; }
<div class="control"> <div class="icon"></div> <div class="text">Home</div> </div>