首先,这不是所有其他试图为 svgs 实现拖放的问题的重复,而回答者告诉他们不能 - 不知何故,我正在阅读的这段代码已经做到了,但我不知道如何做到这一点.
我正在开发一个名为react-hexgrid 的项目。 它是一个使用各种函数使用 svg 绘制六边形的库。 该库有拖放代码,但我不知道如何使用它。
这个例子使用一些旧的类...扩展了react语法来实现拖放,以及一个名为“react-scripts”的库。 您可以在here查看拖放道具/功能的一些实现。 如果您要克隆、安装并运行该示例,您会发现拖放确实有效。
但是,我尝试编写一些这样的代码:
import React from 'react';
import { Hexagon, HexGrid, Layout } from 'react-hexgrid';
function App() {
return (
<HexGrid width="100%" height="100%">
<Layout>
{/* drag and drop the colors! }
{/* the drag source */}
<Hexagon
q={0}
r={0}
s={0}
style={{ fill: 'red' }}
onDrop={() => {
console.log('drag');
}}
onDragStart={() => {
console.log('drag');
}}
onDrag={() => {
console.log('drag');
}}
></Hexagon>
</Layout>
</HexGrid>
);
}
export default App;
无论我在任何元素上单击、鼠标悬停或拖动多少次,此代码都不起作用。我不明白为什么这不起作用,但上面链接的旧代码可以。 有什么想法吗?
这里有一个普通的 JavaScript 示例。在示例中,可拖动元素不是 SVG,而是 HTML 元素。
const board = document.querySelector('section');
board.querySelectorAll('div').forEach(positionHex);
function positionHex(elm){
let q = parseInt(elm.dataset.q);
let r = parseInt(elm.dataset.r);
let s = parseInt(elm.dataset.s);
let elm_box = elm.getBoundingClientRect();
let section = elm.closest('section');
let section_box = section.getBoundingClientRect();
let zero = {
left: section_box.width / 2 - elm_box.width / 2,
top: section_box.height / 2 - elm_box.height / 2
};
elm.style.left = `${zero.left + q * elm_box.width * .75}px`;
elm.style.top = `${zero.top + -s * elm_box.height / 2 + r * elm_box.height / 2}px`;
}
board.addEventListener('dragstart', e => {
e.dataTransfer.setData('text/plain', e.target.dataset.cat);
});
board.addEventListener('dragover', e => {
e.preventDefault();
});
board.addEventListener('drop', e => {
e.preventDefault();
let target = e.target.closest('.hex');
if(!target || target.dataset.cat) return;
let cat_id = e.dataTransfer.getData('text/plain');
let board = target.closest('section');
let source = board.querySelector(`div[data-cat = "${cat_id}"]`);
source.draggable = false;
delete source.dataset.cat;
target.dataset.cat = cat_id;
target.draggable = true;
});
body {
background-color: DarkCyan;
}
section {
position: relative;
border: solid thin black;
width: 500px;
height: 500px;
box-sizing: border-box;
}
.hex {
position: absolute;
width: 100px;
aspect-ratio: 40/34.64;
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="-22 -19.32 44 38.64"><path d="M-10-17.32 10-17.32 20 0 10 17.32-10 17.32-20 0Z" fill="MediumTurquoise" stroke="PaleTurquoise" stroke-width="1" /></svg>');
background-size: cover;
font-size: small;
align-content: center;
text-align: center;
}
.hex::before {
content: attr(data-q)','attr(data-r)','attr(data-s);
}
.hex[data-cat] {
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="-22 -19.32 44 38.64"><path d="M-10-17.32 10-17.32 20 0 10 17.32-10 17.32-20 0Z" fill="skyblue" stroke="PaleTurquoise" stroke-width="1" /></svg>');
}
.hex[data-cat]::before {
content: 'Cat #'attr(data-cat);
}
<section>
<div data-q="-1" data-r="0" data-s="1" data-cat="1" class="hex" draggable="true"></div>
<div data-q="0" data-r="0" data-s="0" class="hex"></div>
<div data-q="-1" data-r="1" data-s="0" class="hex"></div>
<div data-q="1" data-r="0" data-s="-1" data-cat="2" class="hex" draggable="true"></div>
<div data-q="0" data-r="-1" data-s="1" class="hex"></div>
<div data-q="1" data-r="-1" data-s="0" class="hex"></div>
<div data-q="2" data-r="-1" data-s="-1" class="hex"></div>
<div data-q="2" data-r="-2" data-s="0" class="hex"></div>
<div data-q="1" data-r="-2" data-s="1" class="hex"></div>
</section>