|
@@ -10,17 +10,17 @@ import HumanSvg from '@/assets/imgs/VirtualHuman/human.svg';
|
|
|
|
|
|
|
|
|
|
|
|
|
interface HumanBodySvgProps {
|
|
interface HumanBodySvgProps {
|
|
|
- // 容器样式(覆盖默认的 .human-container)
|
|
|
|
|
- containerStyle?: React.CSSProperties;
|
|
|
|
|
-
|
|
|
|
|
- // SVG 样式(覆盖默认的 .human-svg)
|
|
|
|
|
- svgStyle?: React.CSSProperties;
|
|
|
|
|
-
|
|
|
|
|
- // 自定义类名(追加到默认类名)
|
|
|
|
|
- className?: string;
|
|
|
|
|
-
|
|
|
|
|
- // 完全自定义的内联样式
|
|
|
|
|
- style?: React.CSSProperties;
|
|
|
|
|
|
|
+ // 容器样式(覆盖默认的 .human-container)
|
|
|
|
|
+ containerStyle?: React.CSSProperties;
|
|
|
|
|
+
|
|
|
|
|
+ // SVG 样式(覆盖默认的 .human-svg)
|
|
|
|
|
+ svgStyle?: React.CSSProperties;
|
|
|
|
|
+
|
|
|
|
|
+ // 自定义类名(追加到默认类名)
|
|
|
|
|
+ className?: string;
|
|
|
|
|
+
|
|
|
|
|
+ // 完全自定义的内联样式
|
|
|
|
|
+ style?: React.CSSProperties;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@@ -45,32 +45,27 @@ const HumanBody: React.FC<HumanBodySvgProps> = ({
|
|
|
(state: RootState) => state.selection.selected
|
|
(state: RootState) => state.selection.selected
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
- const bringToFront = (el: SVGElement) => {
|
|
|
|
|
- const parent = el.parentNode;
|
|
|
|
|
- if (!parent) return;
|
|
|
|
|
- parent.appendChild(el);
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- const handleMouseOver = (e: React.MouseEvent<SVGSVGElement>) => {
|
|
|
|
|
- const target = e.target as Element;
|
|
|
|
|
- const partEl = target.closest('[data-part]') as SVGElement | null;
|
|
|
|
|
- if (partEl) {
|
|
|
|
|
- bringToFront(partEl);
|
|
|
|
|
- }
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
/**
|
|
/**
|
|
|
* SVG 统一点击入口(事件委托)
|
|
* SVG 统一点击入口(事件委托)
|
|
|
*/
|
|
*/
|
|
|
const handleSvgClick = (e: React.MouseEvent<SVGSVGElement>) => {
|
|
const handleSvgClick = (e: React.MouseEvent<SVGSVGElement>) => {
|
|
|
const target = e.target as Element;
|
|
const target = e.target as Element;
|
|
|
|
|
+ let serverName;
|
|
|
|
|
+ // 情况 1:点在 image 上(少数浏览器)
|
|
|
|
|
+ if (target.tagName === 'image') {
|
|
|
|
|
+ console.log((target as SVGImageElement).dataset.part);
|
|
|
|
|
+ serverName= (target as SVGImageElement).dataset.part;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // 从当前节点向上找 data-part
|
|
|
|
|
- const partEl = target.closest('[data-part]') as SVGElement | null;
|
|
|
|
|
-
|
|
|
|
|
- if (!partEl) return;
|
|
|
|
|
|
|
+ // 情况 2:点在 g 上
|
|
|
|
|
+ if (target.tagName === 'g') {
|
|
|
|
|
+ const image = target.querySelector('image[data-part]');
|
|
|
|
|
+ if (image) {
|
|
|
|
|
+ console.log((image as SVGImageElement).dataset.part);
|
|
|
|
|
+ serverName= (image as SVGImageElement).dataset.part;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- const serverName = partEl.getAttribute('data-part');
|
|
|
|
|
if (!serverName) return;
|
|
if (!serverName) return;
|
|
|
|
|
|
|
|
console.log('点击身体部位:', serverName);
|
|
console.log('点击身体部位:', serverName);
|
|
@@ -137,12 +132,21 @@ const HumanBody: React.FC<HumanBodySvgProps> = ({
|
|
|
opacity: 0.95;
|
|
opacity: 0.95;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+.human-svg g[data-part] {
|
|
|
|
|
+ pointer-events: bounding-box;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ //transition: opacity 0.2s ease, filter 0.2s ease;
|
|
|
|
|
+ outline: 1px solid red;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
/* 默认状态 */
|
|
/* 默认状态 */
|
|
|
- .human-svg [data-part] {
|
|
|
|
|
- cursor: pointer;
|
|
|
|
|
- // opacity: 0.35;
|
|
|
|
|
- transition: opacity 0.2s ease, filter 0.2s ease;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // .human-svg image[data-part] {
|
|
|
|
|
+ // cursor: pointer;
|
|
|
|
|
+ // pointer-events: all;
|
|
|
|
|
+ // // opacity: 0.35;
|
|
|
|
|
+ // transition: opacity 0.2s ease, filter 0.2s ease;
|
|
|
|
|
+ // outline: 1px solid red;
|
|
|
|
|
+ // }
|
|
|
|
|
|
|
|
/* hover */
|
|
/* hover */
|
|
|
.human-svg [data-part]:hover {
|
|
.human-svg [data-part]:hover {
|
|
@@ -168,8 +172,7 @@ const HumanBody: React.FC<HumanBodySvgProps> = ({
|
|
|
<HumanSvg
|
|
<HumanSvg
|
|
|
className="human-svg"
|
|
className="human-svg"
|
|
|
style={svgStyle}
|
|
style={svgStyle}
|
|
|
- onMouseOver={handleMouseOver}
|
|
|
|
|
- onClick={handleSvgClick}
|
|
|
|
|
|
|
+ onMouseDown={handleSvgClick}
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
|
</>
|
|
</>
|