一、前言
在跟需求方对接研发的需求,人家说要做一个悬浮在页面的图标,点击完截图然后进入一个新页面,填完一些数据,提交给接口。那么问题来了,怎么制作一个悬浮框,还是可拖拽的悬浮框,还是可拖拽的H5悬浮框?于是,就开始了研发之旅。
制作之后的效果:
二、总代码
InformErrorHover.tsx悬浮图标总代码:
const InformErrorHover: FC<InformErrorHoverProps> = (props) => {
const { visible = false, location } = props;
const { errorFileList, imgBase64 } = useSelector((state) => state['informError']);
const dispatch = useDispatch();
const divRef = useRef<any>();
const [itemHeight, setItemHeight] = useState<number>(80);
const [itemWidth, setItemWidth] = useState<number>(80);
const [left, setLeft] = useState<number>(0);
const [top, setTop] = useState<number>(0);
const [clientWidth, setClientWidth] = useState<number>(0);
const [clientHeight, setClientHeight] = useState<number>(0);
const [gapWidth, setGapWidth] = useState<number>(30);
useEffect(() => {
setClientWidth(document.documentElement.clientWidth);
setClientHeight(document.documentElement.clientHeight);
setLeft(document.documentElement.clientWidth - clientWidth - gapWidth);
setTop(document.documentElement.clientHeight * 0.8);
}, []);
const dragStart = (e: any) => {
divRef!.current!.style.transition = 'none';
};
const dragEnd = (e: any) => {
divRef!.current!.style.transition = 'all 0.3s';
if (left > clientWidth / 2) {
setLeft(clientWidth - itemWidth - gapWidth);
} else {
setLeft(gapWidth);
}
};
const touchmove = (e: any) => {
if (e.targetTouches.length === 1) {
let touch = e.targetTouches[0];
setLeft(touch.clientX - itemWidth / 2);
setTop(touch.clientY - itemHeight / 2);
}
};
const dataURLtoFile = (dataurl: any, filename: any) => {
var arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, { type: mime });
};
const generateImage = async () => {
Toast.loading('正在截图中...');
await html2canvas(document.body).then((canvas) => {
let url = canvas.toDataURL('image/png');
let files = dataURLtoFile(url, '文件1');
dispatch!({
type: 'informError/save',
payload: {
errorFileList: [files],
imgBase64: url,
},
});
Toast.hide();
history.push({ pathname: '/informError' });
});
};
return (
<div
className={styles.informErrorHoverStyle}
style={{ top: `${itemHeight}px` }}
>
<div
className={styles.imgDiv}
ref={divRef}
style={{
backgroundImage: `url(${require('@/assets/images/inforErrorPng.png')})`,
width: `${itemWidth}px`,
height: `${itemHeight}px`,
left: `${left}px`,
top: `${top}px`,
}}
onClick={() => {
generateImage();
}}
onTouchStart={(e) => {
dragStart(e);
}}
onTouchEnd={(e) => {
dragEnd(e);
}}
onTouchMove={(e) => {
touchmove(e);
}}
>
</div>
</div>
);
};
less样式代码:
.informErrorHoverStyle{
.imgDiv{
position: fixed;
right: 20px;
z-index: 9999;
width: 40px;
height: 40px;
white-space: nowrap;
background-size: 100% 100%;
transition: all 0.3s;
}
.imgStyle{
width: 40px;
height: 40px;
}
}
三、详解:
1、需要定义的数据
const divRef = useRef<any>();
const [itemHeight, setItemHeight] = useState<number>(80);
const [itemWidth, setItemWidth] = useState<number>(80);
const [left, setLeft] = useState<number>(0);
const [top, setTop] = useState<number>(0);
const [clientWidth, setClientWidth] = useState<number>(0);
const [clientHeight, setClientHeight] = useState<number>(0);
const [gapWidth, setGapWidth] = useState<number>(30);
2、需要定义的方法
const dragStart = (e: any) => {
divRef!.current!.style.transition = 'none';
};
const dragEnd = (e: any) => {
divRef!.current!.style.transition = 'all 0.3s';
if (left > clientWidth / 2) {
setLeft(clientWidth - itemWidth - gapWidth);
} else {
setLeft(gapWidth);
}
};
const touchmove = (e: any) => {
if (e.targetTouches.length === 1) {
let touch = e.targetTouches[0];
setLeft(touch.clientX - itemWidth / 2);
setTop(touch.clientY - itemHeight / 2);
}
};
3、dom节点内容
return (
<div
className={styles.informErrorHoverStyle}
style={{ top: `${itemHeight}px` }}
>
<div
className={styles.imgDiv}
ref={divRef}
style={{
backgroundImage: `url(${require('@/assets/images/inforErrorPng.png')})`,
width: `${itemWidth}px`,
height: `${itemHeight}px`,
left: `${left}px`,
top: `${top}px`,
}}
onClick={() => {
generateImage();
}}
onTouchStart={(e) => {
dragStart(e);
}}
onTouchEnd={(e) => {
dragEnd(e);
}}
onTouchMove={(e) => {
touchmove(e);
}}
>
{}
</div>
</div>
);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)