文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

如何实现react版模拟亚马逊人机交互菜单

2023-06-29 02:30

关注

小编给大家分享一下如何实现react版模拟亚马逊人机交互菜单,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!

需求介绍

本文都是在web端的需求

参考亚马逊和京东商城的首页左侧菜单效果,实现一个react版本的组件,以供业务使用。

我们先看下亚马逊和京东商城的效果:

亚马逊商城

如何实现react版模拟亚马逊人机交互菜单

京东商城

如何实现react版模拟亚马逊人机交互菜单

从上面的效果得出我们的菜单效果需求点:

到目前为止,我们就搞情况了我们的需求。接下来就要去实现我们的方案了。

实现方案

要实现我们的需求,复杂点主要是在如何实现上述的需求3。需求1和需求2 的基本切换效果我就不再说了,直接进入需求3

实现需求3

如果要实现这个需求,我们需要记录鼠标从左往右(从左侧菜单区域移动到右侧菜单区域)的移动轨迹,然后根据它的移动轨迹去判断它是否是在一个三角形的区域之内,如果在的话,就不让它切换菜单。

我们先看一张图:

如何实现react版模拟亚马逊人机交互菜单

从上图我们可以得出:

如果鼠标的起始点是在 P1 的话,当鼠标移动到右侧区域,鼠标可能经过的三角形区域就是 P1-P2-P3所在的三角形,M点是鼠标的结束位置。所以我们判断鼠标的运动轨迹是否在三角形中就可以了。

部分逻辑代码

const [active, setActive] = useState(null) // 选中的菜单  const [showSub, setShowSub] = useState(false) // 是否显示子菜单  let timeout = useRef(null) //  设置延迟定时器,防止鼠标移到tab内容经过菜单时的切换  let mouseLocs = useRef([]) // 记录鼠标移动时的坐标数组  let firstSlope = useRef(null) // 菜单栏的固定点1, 根据菜单栏和内容的位置而改变  let secondSlope = useRef(null) // 菜单栏的固定点2, 根据菜单栏和内容的位置而改变  const refNavigation = useRef(null)  const refNav = useRef(null)  const refSubnav = useRef(null)    function proPosInTriangle(p1, p2, p3, m) {    // 结束时鼠标坐标位置    let x = m.x,      y = m.y,      // 开始鼠标坐标位置      x1 = p1.x,      y1 = p1.y,      // 菜单栏包裹层右上角坐标      x2 = p2.x,      y2 = p2.y,      // 右下角坐标      x3 = p3.x,      y3 = p3.y,      // (y2 - y1) / (x2 - x1)为两坐标连成直线的斜率      // 因为直线的公式为y=kx+b;当斜率相同时,只要比较      // b1和b2的差值就可以知道该点是在      // (x1,y1),(x2,y2)的直线的哪个方向      // 当r1大于0,说明该点在直线右侧,其它以此类推      r1 = y - y1 - ((y2 - y1) / (x2 - x1)) * (x - x1),      r2 = y - y2 - ((y3 - y2) / (x3 - x2)) * (x - x2),      r3 = y - y3 - ((y1 - y3) / (x1 - x3)) * (x - x3),      compare    compare = r1 * r2 * r3 < 0 && r1 > 0    // 返回是否在三角形内的结果    return compare  }    function LocFromdoc(element) {    const { x, y, width, height } = element.getBoundingClientRect()    return {      x: x,      y: y,      width,      height,    }  }    function getInfo(element) {    const location = LocFromdoc(element)    return {      top: location.y,      topAndHeight: location.y + element.offsetHeight, // offsetHeight 元素的像素高度, 高度包含该元素的垂直内边距和边框,且是一个整数      left: location.x,      leftAndWidth: location.x + element.offsetWidth,    }  }    function ensureTriangleDots() {    // 获取菜单栏的位置    const info = getInfo(refNav.current)    const x1 = info.leftAndWidth    const y1 = info.top    const x2 = x1    const y2 = info.topAndHeight    firstSlope.current = {      x: x1,      y: y1,    }    secondSlope.current = {      x: x2,      y: y2,    }  }  const onMouseOver = useCallback(    obj => {      let diff      try {        // 是否在指定三角形内        diff = proPosInTriangle(          mouseLocs.current[0],          firstSlope.current,          secondSlope.current,          mouseLocs.current[2]        )      } catch (ex) {}      // 是就启动延迟显示,      // 否则不延迟      if (diff) {        timeout.current = setTimeout(() => {          setActive(obj.key)          setShowSub(true)        }, 300)      } else {        setActive(obj.key)        setShowSub(true)      }    },    [mouseLocs, timeout]  )  const onMouseEnter = () => {    // 计算位置    if (refNav.current) {      ensureTriangleDots()    }    setShowSub(true)  }  // 移出菜单所在区域  const onMouseLeave = () => {    if (refSubnav.current) {      setActive(null)      setShowSub(false)    }  }  // 记录鼠标在菜单栏中移动的最后三个坐标位置  const onMousemove = event => {    mouseLocs.current.push({      x: event.pageX,      y: event.pageY,    })    if (mouseLocs.current.length > 3) {      // 移除超过三项的数据      mouseLocs.current.shift()    }  }  // 鼠标移出的时候,清除延时器  const onMouseout = () => {    if (timeout.current) {      clearTimeout(timeout.current)    }  }

实现效果

如何实现react版模拟亚马逊人机交互菜单

看完了这篇文章,相信你对“如何实现react版模拟亚马逊人机交互菜单”有了一定的了解,如果想了解更多相关知识,欢迎关注编程网行业资讯频道,感谢各位的阅读!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯