借鉴《疑犯追踪》二号AI “撒玛利亚人” 的交互效果,实现一个可视化分析项目里 引导动画 + 主体标注 的功能。

功能点:

  • 引导用户了解分析工具的功能
  • 标注当前分析页面的主体对象

设计

  • 引导动画

    原版“撒玛利亚人”的红色三角形像跳动的光标,表示分析加载过程,紧接着便是文字输出,挺极简科技范儿。不过,这动画实在不会画,直接在下面的代码实现部分展示吧。

  • 默认状态:

    原版“撒玛利亚人”是向上的红色三角形箭头,但这个案例中,我把三角形箭头改为向下。 三角形标识的对象可以向下展开,用户阅读的顺序是从对象标题,向下到对象内容。箭头向下在视觉上更统一。 另一个原因其实是避免对象展开、折叠时,三角形被反复渲染。

默认状态

  • 悬停、点击 等高亮状态

    最初的想法是默认对象都是 暗黑色 ,分析主体 给一个 淡绿色 ,显眼又简单。不过,后续设计 对象的交互时,用颜色标注 悬停、点击、被命中等状态时,状态颜色与主体标识颜色 是 覆盖 还是 共存?这是个问题。索性,把颜色单拎出来指示状态。红色三角形剪头用来标识主体,且不被交互状态影响。

悬停、点击 等高亮状态

  • 拓展:因“状态颜色与主体标识颜色?”这个问题,而联想到的个另一个困惑却有了灵感,那就是 “一个对象被多个规则命中时如何展示”。目前用的方法是共存。

    • 草稿:对象自身的颜色分割和关联边的颜色分割。 图 7

    • 效果图大概这样:

    图 5

    不过还有一些疑问:颜色很多时怎么办?怎么跟外部操作面板交互等

实现

  • 引导动画

    可以参考 G6 官网 Demo ,先后定义 矩形、文本框 等公共元素,然后 自定义一个独立的倒三角组件。在 draw 绘制函数中,按需调用倒三角组件,传入当前 group 信息,计算并绘制倒三角图形,并在组建内定义呼气跳动动画。

展开/折叠 “红色倒三角组件” 代码 :
const addMainTag = (group,width)=> {
  // 计算 倒三角顶点
  let point_1 = [width/2-4,-10]
  let point_2 = [width/2+4,-10]
  let point_3 = [width/2,-3]

  const main_tag = group.addShape('path', {
    attrs: {
      path: [
        ['M', point_1[0], point_1[1]], 
        ['L', point_2[0], point_2[1]], // 倒三角 顶部
        ['L',point_3[0], point_3[1]], // 倒三角 右侧顶点 到 下顶点
        ['Z'], // 封闭
      ], 
      fill:'#F56A6A', //'#D53434',
      stroke:'#F05454',
    },
    name: 'main_tag',
    draggable: false,
  });
  main_tag.animate(
    (ratio) => {
      const diff = ratio <= 0.5 ? ratio * 10 : (1 - ratio) * 10;
      let point_1 = [width/2-4,-10-diff]
      let point_2 = [width/2+4,-10-diff]
      let point_3 = [width/2,-3-diff]
      return {
        path: [
          ['M', point_1[0], point_1[1]], 
          ['L', point_2[0], point_2[1]], // 倒三角 顶部
          ['L',point_3[0], point_3[1]], // 倒三角 右侧顶点 到 下顶点
          ['Z'], // 封闭
        ]
        
      };
    },
    {
      
      repeat: true,
      duration: 3000,
      easing: 'easeLinear',
    },
  ); // 一次动画持续的时长为 3000,动画效果为 'easeCubic'
}
export default addMainTag

最后定义引导动画时,边框、背景色需要透明,根据上方 红色倒三角 的动画周期,计算引导文字的切换。

展开/折叠 “引导动画” 代码 :
empty_text.animate(
            (ratio) => {
              let text_flag = true
              let tmp_x = width/2-35
              let tmp_font_size = 10
              if (ratio>0.5) {
                text_flag = false
              }  
              let text = '👈              👉'
              if (text_flag) {
                text = '<- 选择对象'
                // console.log(text_flag)
              } else {
                text = '    逐层分析 ->'
              }
              let text_opacity = 0
              
                if(ratio <= 0.25) {
                  text_opacity = ratio*2
                  tmp_x=tmp_x+5-ratio*7
                }
                if (ratio > 0.25 && ratio <= 0.5) {
                  text_opacity = 1-ratio*2
                  tmp_x=tmp_x+5-ratio*7
                }
                if (ratio > 0.5 && ratio <= 0.75) {
                  text_opacity = 1-(1-ratio)*2
                  tmp_x=tmp_x-5+ratio*7
                }    
                if (ratio > 0.75 && ratio <= 1) {
                  text_opacity = (1-ratio)*2
                  tmp_x=tmp_x-5+ratio*7
                }

                if (ratio>0.9) {
                  text = '<- 选择对象 逐层分析 ->'
                  text_opacity = ratio-0.95
                  tmp_x = width/2-57-ratio*12
                  tmp_font_size=tmp_font_size+ratio*2
                  
                }

              return {
                text:text,
                opacity:text_opacity+0.1,
                x:tmp_x,
                fontSize: tmp_font_size,
              };
            },
            {
              
              repeat: false,
              duration: 6000,
              delay:1000,
              easing: 'easeLinear',
            },
          );
          return group

效果:

  • 分析主体标识

    在加载实际分析对象时,复用 ”引导动画“ 中的红色倒三角组件即可。在分析数据反复变化时,我们的 “撒玛利亚人” 就会牢牢锁定分析主体。

可优化点:

  • 分析对象很多时,画布内的元素缩小,红色三角也会缩小后不够明显?
    • 按比例保持自身大小?(可借鉴 G6 toolbar 不跟随页面缩放的思路)
    • 增加辐射波动画,做全画布的视觉聚焦指引?