【发布时间】:2021-02-11 16:19:14
【问题描述】:
array_groups 是一个数组数组。内部数组中的对象是规则圆的坐标,它们都是近端的,想法是这些圆的内部数组都应该一起被剪辑路径。这个想法是,当我将鼠标移到近端圆圈的每个区域上时,矩形仅显示在该区域中。
function Hoverpicture() {
const [image, setimage] = useState("");
const [mousepos, setmousepos] = useState({ x: 0, y: 0 });
const [radius, setradius] = useState(20)
const [label, setlabel] = useState("");
const [region, setregion] = useState([]);
const [input, setinput] = useState("");
const [mode, setmode] = useState(1);
const [mousemove, setmousemove] = useState(()=>onmousemove);
function onlabelclick(e) {
setlabel("clicked label")
}
function onmouseclick(e) {
let newregion = region.concat({ x: e.nativeEvent.offsetX, y: e.nativeEvent.offsetY, r: radius, label: input});
setregion(newregion);
}
function checkregion(pos) {
for (let reg of region) {
let xs = pos.x - reg.x;
let ys = pos.y - reg.y;
xs*=xs;
ys*=ys;
console.log(reg);
if (reg.r-Math.sqrt( xs + ys ) > 0) {
return reg.label;
}
}
return false;
}
function onmousemove(e) {
setmousepos({ x: e.nativeEvent.offsetX, y: e.nativeEvent.offsetY });
let displaylabel = checkregion({x: e.nativeEvent.offsetX, y: e.nativeEvent.offsetY});
if (displaylabel) {
setlabel(displaylabel);
} else {
setlabel("");
}
}
function handleinput(e) {
setinput(e.target.value);
}
function myreducer(accum,next) {
accum[next.label] = accum[next.label] || [];
accum[next.label].push(next);
return accum;
}
var grouped_region = region.reduce(function (accum,next) {
accum[next.label] = accum[next.label] || [];
accum[next.label].push(next);
return accum;
},{});
var array_groups = [];
for (let area in grouped_region) {
array_groups.push(grouped_region[area]);
}
if (mode===1)
{
return (
<div>
<div className="img-overlay-wrap">
<img src={image} alt="table with coffee"/>
<svg onMouseMove={onmousemove} viewBox="0 0 auto auto">
<circle cx={mousepos.x} cy={mousepos.y} r={radius} fill-opacity="0"/>
{array_groups.map((ar,i) =>(
<clipPath id="shape">
{ar.map(reg =>(<circle onClick={onlabelclick} cx={reg.x} cy={reg.y} r={reg.r} fill="orange"/>))}
</clipPath>
<rect x={0} y={0} width="100%" height="100%" clipPath="url(#shape)" class="label" fill-opacity="0"/>
))}
</svg>
</div>
<div>
<h1>{ label }</h1>
<button onClick={()=>{setmode(1)}}>✏</button>
</div>
</div>
)}
CSS 看起来像这样..
.img-overlay-wrap {
position: relative;
display: inline-block; /* <= shrinks container to image size */
transition: transform 150ms ease-in-out;
}
.img-overlay-wrap img { /* <= optional, for responsiveness */
display: block;
max-width: 100%;
height: auto;
}
.img-overlay-wrap svg {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
}
.label:hover {
fill-opacity:.5;
fill:red;
}
【问题讨论】:
-
有问题吗?你在问什么?似乎您已经映射了内部
ar数组。 -
啊,好吧,预期的结果是我在相应剪切区域上的 onmousemove 将填充为红色,但这不会发生。在较早的尝试中,我已经成功让所有区域在 onmousemove 上填充为红色。在该尝试中,我只有一个地图,原始结构只是对象数组,而不是对象数组数组..似乎我无法让嵌套地图与相应的clipPaths正常工作..它总是抱怨需要父母的“相邻JSX元素”..但是我放置一些包装器的任何地方都没有功能跨度>这对我来说是一个新的警告/错误,请注意用更多Minimal, Complete, and Reproducible 组件代码示例更新您的问题(这样我们就可以看到处理程序等)和那个警告/错误消息?codepen.io/mchielouis/pen/gOwXrpY?editors=0010 这是我的密码笔,如果你想看的话..
标签: javascript reactjs jsx clip-path