!!!###!!!title=action——VisActor/VStory 教程文档!!!###!!!!!!###!!!description=请先阅读[dsl 的定义](./DSL)以及[character](./character),然后再阅读本节内容。当我们定义好了`character`数组之后,就可以通过`actions`来定义这些`character`的行为了。action 的定义是在`幕`(`act`)中进行的我们的 acts 定义参考了戏剧的架构:在戏剧中,“幕”和“场面”是两个非常重要的概念,用于划分和组织剧本的结构。1. 幕:在戏剧中,幕(`Act`)是剧本的主要部分,用于划分戏剧的大段落。一部戏剧通常包含两幕或更多,每一幕都有其独特的主题和冲突。幕的划分可以帮助观众理解剧情的发展和角色的变化。在实际表演中,每一幕之间通常会有短暂的休息,以便更换舞台布景或让演员更换服装。2. 场面:场面(`Scene`)是幕的子集,它进一步细化了剧本的结构。一幕通常包含多个场面,每个场面都在特定的时间和地点发生。场面的切换通常意味着角色、地点或时间的变化。在剧本中,场面的划分可以帮助读者或观众更好地理解剧情的流动。我们的 acts 定义也是由幕(`Act`) -> 场面(`Scene`) -> 行为(`action`)这样的定义具体的结构参考[dsl 的定义](./DSL),接下来我们介绍有哪些`action`可以使用。!!!###!!!

action

请先阅读dsl 的定义以及character,然后再阅读本节内容。

当我们定义好了character数组之后,就可以通过actions来定义这些character的行为了。action 的定义是在act)中进行的

我们的 acts 定义参考了戏剧的架构:在戏剧中,“幕”和“场面”是两个非常重要的概念,用于划分和组织剧本的结构。

  • 幕:在戏剧中,幕(Act)是剧本的主要部分,用于划分戏剧的大段落。一部戏剧通常包含两幕或更多,每一幕都有其独特的主题和冲突。幕的划分可以帮助观众理解剧情的发展和角色的变化。在实际表演中,每一幕之间通常会有短暂的休息,以便更换舞台布景或让演员更换服装。
  • 场面:场面(Scene)是幕的子集,它进一步细化了剧本的结构。一幕通常包含多个场面,每个场面都在特定的时间和地点发生。场面的切换通常意味着角色、地点或时间的变化。在剧本中,场面的划分可以帮助读者或观众更好地理解剧情的流动。

我们的 acts 定义也是由幕(Act) -> 场面(Scene) -> 行为(action)这样的定义

具体的结构参考dsl 的定义,接下来我们介绍有哪些action可以使用。

action 使用

action的接口定义如下,包括一个characterId指定这个action作用的元素, 还有一个characterActions数组,里面包含了这个character的具体行为。 characterActions数组的每一项包括一个 action 的类型(action),和一个payloadaction定义了具体的行为,比如appeardisappearstyle等,payload是一个对象,包含了这个action的具体参数,比如动画时长,选择器等。

interface IActions {
  characterId: string | string[]; // 要执行动作的character的id或者数组
  characterActions: IAction<IActionPayload>[];
}

interface IAction<T extends IActionPayload> {
  action: string; // 具体的action,比如appear
  startTime?: number; // 动作开始时间
  payload?: T | T[]; // 动作的参数
}

export interface IActionPayload {
  animation?: IAnimationParams; // 具体的动画参数定义
  selector?: string; // 选择器,用于指定要执行动作的元素,比如图表中,可以通过 bar 选择到柱子
}

export interface IAnimationParams {
  duration: number; // 动画时长
  easing?: EasingType; // 动画曲线
  loop?: number | boolean; // 是否循环,循环几次
  effect?: string | string[]; // 特效,比如appear有fade、bounce等特效
  // 其他参数
  dimensionCount?: number;
  delayPerTime?: number;
  enterPerTime?: number;
  params?: Record<string, any>;
  [key: string]: any;
}

Appear、DisAppear

首先当我们定义好了character数组之后,默认这些character是不可见的,我们需要通过appear来让它们出现。当不需要的时候,我们可以通过disappear来让它们消失。appear有很多种形式,通用的比如fadescalewipe等。如果你使用了一些特殊的character,比如VChart,那么还有更多的appear形式。

通用的 Appear、DisAppear 效果有如下几种:

  • fade 渐入渐出
  • scale 缩放
  • wipe 滑动
  • move 移动

具体的使用用例如下:

Style

style可以让character的样式发生变化,比如fillstroke等。style的使用方式和appeardisappear类似,但是stylepayload中需要包含graphictext等字段。

MoveTo

moveTo可以让character移动到指定的位置。moveTo的使用方式和appeardisappear类似,但是moveTopayload中需要包含destination字段表示移动距离,destination字段包含了xy坐标。

ScaleTo

scaleTo可以让character缩放到指定的大小。scaleTo的使用方式和appeardisappear类似,但是scaleTopayload中需要包含scale字段表示缩放比例,scale字段包含了scaleXscaleY属性。

Bounce

bounce可以让character跳动。只需要配置 action 即可。

VChart 的 Appear、DisAppear 和选择器

上面介绍了一些基本的action内容,VChart由于其内容的复杂性,我们设计了更加复杂的语法,去支持其特殊的Appear或者 DisAppear 的内容。比如图表我们希望柱子做leap动画,其他的走默认的动画。这时我们需要使用selector来选择需要做动画的柱子,来给其配置特殊的动画。同时我们也给VChart设计了默认的Appear动画,其中每个系列和组件都会执行自己的Appear动画

selector 是图表的筛选器,其中可以配置几种格式:

  • * 选择所有的组件
  • def 选择 type 为 abc 的组件,比如bar
  • #abc 选择 name 为 abc 的元素,比如#abc
  • :not(selector) 选择除了 selector 之外的元素,这里的 selector 可以是type也可以是name 多个 selector 可以同时配置在同一个字符串中,使用空格分隔,比如def #abc,表示选择 type 为 def 的组件和 name 为 abc 的元素。
// 同一个Action的payload数组中,项与项之间是覆盖关系,后项覆盖前项
// 不同Action的payload之间是并列关系
[
  {
    action: 'appear',
    startTime: 10, // 开始时间
    payload: [
      {
        selector: '*',
        style: {},
        animation: {
          duration: 10000,
          easing: 'linear'
        } as any
      },
      {
        selector: ':not(label)',
        style: {},
        animation: {
          duration: 10000,
          easing: 'linear'
        } as any
      },
      {
        selector: 'x-axes',
        style: {},
        animation: {
          duration: 10000,
          easing: 'linear'
        } as any
      },
      {
        selector: '#label1',
        style: {},
        animation: {
          duration: 10000,
          easing: 'linear'
        } as any
      }
    ]
  },
  {
    action: 'appear',
    startTime: 100, // 开始时间
    payload: [
      {
        selector: '*', // 选择器 0
        style: {},
        animation: {
          duration: 10000,
          easing: 'linear'
        } as any
      }
    ]
  }
];

这是一个例子,柱子使用leap动画,其他组件使用默认动画