Skip to content

按键动画

恰当的按键动画可以让键盘交互更加生动和有趣。元书输入法支持多种类型的动画效果,包括缩放、卡通和物理动画。

缩放动画是在按键被按下时产生缩小效果,释放时恢复原状。

scaleAnimation:
animationType: scale
isAutoReverse: true
scale: 0.95
pressDuration: 850
releaseDuration: 100
  • isAutoReverse:是否区分按键状态自动反转动画。默认为 false
    • 当设置为 true 时,按键动画会使用 pressDuration 的时间播放缩小动画,随后使用 releaseDuration 的时间播放放大动画。动画是连贯的,由按键按下状态触发。
    • 当设置为 false 时:按键按下状态使用 pressDuration 的时间播放缩小动画;按键释放状态使用 releaseDuration 的时间播放放大动画。动画是不连贯的,按键按下和释放状态分别触发。
  • scale:按键缩放比例,默认为 0.95,表示按下时按键缩小到原来的 95%。
  • pressDuration:按键按下状态时,动画持续时间,单位为毫秒。
  • releaseDuration:按键释放状态时,动画持续时间,单位为毫秒。

图片播放动画通过一系列图片帧来实现动画效果,适用于需要展示复杂动画的场景。

cartoonAnimation:
animationType: cartoon
fps: 30
targetScale: 0.3
zPosition: 'above'
images:
- "frame1.png"
- "frame2.png"
  • fps:动画播放的帧率,默认为 30 帧每秒。表示一张图片显示的时间为 1/30 秒。
  • targetScale:图片缩放比例,默认为 nil,即不进行缩放,建议按效果设置,图片如果不缩放,会占用较多的内存。
  • zPosition:图片的显示层级,默认为 above,表示图片显示在按键之上。可选值有 above(按键上方)、below(按键下方)。
  • images:帧图片文件名数组,按顺序列出所有用于动画的图片文件名。

物理动画提供对图片移动、旋转、透明度变化的效果。

physicsAnimation:
animationType: physics
duration: 600
randomImage: true
targetScale: 0.3
images:
- "01.png"
- "02.png"
startPosition: { x: 0, y: 0 }
startRandomPosition: { x: 0, y: 0 }
endPosition: { x: 0, y: -10 }
endRandomPosition: { x: 100, y: 0 }
# randomPosition 已删除
randomPosition: { x: 0, y: 0 }
useOpacity: true
startOpacity: 1.0
endOpacity: 0.1
useRotation: true
startAngle: 0
endAngle: 360
randomAngle: 50
  • duration:动画持续时间,单位为毫秒。
  • randomImage:是否从 images 图片列表中随机选择图片,默认为 false
  • targetScale:图片缩放比例,默认为 nil,即不进行缩放,建议按效果设置,图片如果不缩放,会占用较多的内存。
  • images:图片文件名数组,按顺序列出所有用于动画的图片文件名。
  • startPosition:图片移动位置的起始点
    • x: 表示起始点的横向位置,默认为当前按键横向中间点。
    • y: 表示起始点的纵向位置,默认为当前按键纵向最低点。
  • startRandomPosition:为 startPosition 添加一个随机变量
    • x: 表示为起始点的横向位置添加一个随机值,随机值在 [-x,x] 之间,即 x = startPosition.x + random(-x, x),
    • y: 表示为起始点的纵向位置添加一个随机值,随机值在 [-y,y] 之间,即 y = startPosition.y + random(-y, y),
    • 注意:需 tf >= 428,商店 >= 1.6.27
  • endPosition:图片移动位置的结束点
    • x: 表示结束点的横向位置,默认为当前按键横向中间点。
    • y: 表示结束点的纵向位置,默认为当前按键纵向最高点。
  • endRandomPosition: 为 endPosition 添加一个随机变量
    • x: 表示为结束点的横向位置添加一个随机值,随机值在 [-x,x] 之间,即 x = startPosition.x + random(-x, x),
    • y: 表示为结束点的纵向位置添加一个随机值,随机值在 [-y,y] 之间,即 y = startPosition.y + random(-y, y),
    • 注意:需 tf >= 428,商店 >= 1.6.27
  • randomPosition:为动画的起始位置和结束位置添加随机偏移
    • x: 横向随机偏移范围
    • y: 纵向随机偏移范围
    • 注意:tf >= 428,商店 >= 1.6.27 删除了这个属性,请使用 startRandomPositionendRandomPosition 代替
  • useOpacity:是否启用透明度变化效果,默认为 false
  • startOpacity:动画开始时图片的透明度,范围为 0.0 到 1.0,默认为 1.0。仅当 useOpacity 设置为 true 时生效。
  • endOpacity:动画结束时图片的透明度,范围为 0.0 到 1.0,默认为 0.8。仅当 useOpacity 设置为 true 时生效。
  • useRotation: 是否启用旋转效果,默认为 false
  • startAngle:图片的开始角度,单位为度。
  • endAngle:图片的结束角度,单位为度。
  • randomAngle:开始角度的随机偏移范围,单位为度。

scale 只能整键缩小,physics 只能新建图层播放图片。若想让按键已有的某一层 (键帽、字形、角标)位移、绕指定锚点缩放或旋转,用 transform

badgeFloatUp:
animationType: transform
target: qButtonBadgeForegroundStyle # 只动这一层;不写则整个按键一起动
trigger: press
duration: 200
delay: 0
timing: easeOut
repeatCount: 1
autoreverses: false
restoreOnFinish: true
holdUntilRelease: false
releaseDuration: 120
anchorPoint: { x: 0.5, y: 1.0 }
positionUnit: point
startPosition: { x: 0, y: 0 }
endPosition: { x: 0, y: -9 }
startScale: 1.0
endScale: 1.2
useRotation: false
startAngle: 0
endAngle: 0
useOpacity: true
startOpacity: 1.0
endOpacity: 0.0
  • target:要作用的图层,取值为该按键 backgroundStyle / foregroundStyle 里用到的样式名。 不设置时作用于整个按键。样式名在当前按键中不存在时,本次动画跳过。
  • trigger:由哪个按键状态触发。press 按下(默认)、release 抬起、both 两者都触发。 开启 holdUntilRelease 后本属性失效。
  • duration:动画时长,单位为毫秒,默认 200。
  • delay:起播延迟,单位为毫秒,默认 0。
  • timing:缓动曲线。可选 lineareaseIneaseOuteaseInEaseOut(默认)、default。 也可以直接写四个数,表示自定义三次贝塞尔控制点 [c1x, c1y, c2x, c2y], 例如 timing: [0.34, 1.56, 0.64, 1] 是一条带回弹的曲线。
  • repeatCount:播放次数,最少 1 次。
  • autoreverses:播完后是否反向播回起点,默认 false。 开启后 duration单程时间,一个来回共 duration × 2,终点回到起点状态。
  • restoreOnFinish:播完是否恢复原状,默认 true。设为 false 时停在终点状态。
  • holdUntilRelease:按下播到终点后停住,抬起时再反向播回起点,默认 false。 详见下方「按住保持」。
  • releaseDurationholdUntilRelease 抬起回程的时长,单位为毫秒。不写则与 duration 相同。
  • anchorPoint:缩放与旋转围绕的锚点,单位坐标{ x: 0.5, y: 0.5 } 为图层中心(默认), { x: 0, y: 0 } 为左上角,{ x: 0.5, y: 1 } 为底边中点。 取值可以超出 0~1,例如 { x: 0.05, y: 1.15 } 表示绕图层左下角外侧的一个点缩放, 缩小时图层会朝那个方向”收”过去。 该属性只决定本次变换绕哪个点发生,不会改动图层自身的 anchorPoint,因此不影响布局
  • positionUnit:位移的单位。
    • point(默认):单位为点。
    • layer:按目标图层自身宽 / 高的倍数取值。
    • button:按整个按键宽 / 高的倍数取值。 皮肤里的尺寸本来就都是相对值,位移写死点值换个机型、换个键盘高度就会偏。 装饰图浮出键帽这类效果,视觉参照的是键帽,用 button; 图层自己抖动、缩进这类效果用 layer
  • startPosition / endPosition:位移的起止值,相对图层原位置,单位由 positionUnit 决定。y 负方向朝上。
  • startScale / endScale:缩放的起止倍率,默认均为 1。 写标量表示等比缩放;写 { x: 0.85, y: 0.9 } 表示 x / y 分别缩放。
  • useRotation:是否启用旋转,默认 false
  • startAngle / endAngle:旋转的起止角度,单位为度。仅当 useRotationtrue 时生效。
  • useOpacity:是否启用透明度变化,默认 false
  • startOpacity / endOpacity:透明度的起止值。仅当 useOpacitytrue 时生效。
  • detached:是否脱离按键播放,默认 false。为 true 时把目标图层复制一份浮到 键盘之上,动画挂在副本上,播完自动删除,原图层在此期间隐藏。
# 1. 绕底边缩放,模拟按键被"压下去"
pressDown:
animationType: transform
duration: 80
anchorPoint: { x: 0.5, y: 1.0 }
startScale: 1.0
endScale: 0.9
autoreverses: true
# 2. 只让字形轻微下沉,键帽不动
glyphSink:
animationType: transform
target: qButtonForegroundStyle
duration: 60
endPosition: { x: 0, y: 2 }
autoreverses: true
# 3. 抬起时角标闪一下
badgeBlink:
animationType: transform
target: qButtonBadgeForegroundStyle
trigger: release
duration: 150
useOpacity: true
startOpacity: 0.2
endOpacity: 1.0

分层按压:一个按键挂多条 transform

Section titled “分层按压:一个按键挂多条 transform”

商业皮肤里「按一下键」往往不是整键缩一下,而是键帽、字形、角标、装饰图 各自绕不同的锚点做不同的动作。做法是给同一个按键挂多条 transform, 每条用 target 指向自己那一层。

下面这组还原的是一类常见效果:键帽整体缩小,字形绕偏上的点收缩, 角标朝左下角收,同时一个只在按下时出现的装饰图往上浮并放大。

四条都是一个来回的脉冲——autoreverses: true 让动画播到终点后原路返回, duration单程时间,所以键帽那条总共 160ms。 按住不放也不会停在终点,播完就回到原状;装饰图则一直留在键上,直到抬起才消失。

mButton:
backgroundStyle: mButtonBackgroundStyle
foregroundStyle:
- mButtonForegroundStyle # 字形 m
- mButtonUpForegroundStyle # 角标 ?
- keyDecorationStyle # 只写了 highlightImage 的装饰图
animation:
- capPress
- glyphPress
- badgePress
- decorationPop
# 键帽:绕中心缩到 85% 再弹回,单程 80ms
capPress:
animationType: transform
target: mButtonBackgroundStyle
duration: 80
autoreverses: true
endScale: 0.85
# 字形:绕偏上的点缩到 85% 再弹回
glyphPress:
animationType: transform
target: mButtonForegroundStyle
duration: 80
autoreverses: true
anchorPoint: { x: 0.5, y: 0.4 }
endScale: 0.85
# 角标:绕左下角外侧的点收缩再弹回
badgePress:
animationType: transform
target: mButtonUpForegroundStyle
duration: 80
autoreverses: true
anchorPoint: { x: 0.05, y: 1.15 }
endScale: 0.85
# 装饰图:上浮键高的 16% 并放大到 120%,再原路回到原位原大小,单程 200ms 线性
decorationPop:
animationType: transform
target: keyDecorationStyle
duration: 200
timing: linear
autoreverses: true
positionUnit: button
endPosition: { x: 0, y: -0.16 }
endScale: 1.2

这里几个属性各自解决一个问题: target 让四条动画互不干扰;anchorPoint 决定每层往哪个方向收; autoreverses 让效果播一个来回后回到原状; positionUnit: button 让上浮距离随键盘尺寸缩放,而不是写死点值。

装饰图那一层通常只配 highlightImage,按下才出现、抬起即消失, 它的「留在键上」靠的是按键的高亮状态,不是动画停在终点—— 所以这类效果不要holdUntilRelease,否则会停在放大后的样子不回来。

  • animation: 类型: [String], 用于设置当前按键的动画效果,可以配置多个动画,当按键按下时同时播放。

注意:animation 属性只能配置在按键的属性配置中有效。

qButton:
size:
width: 112.5/1125
backgroundStyle: alphabeticBackgroundStyle
foregroundStyle:
- qButtonForegroundStyle
- qButtonUpForegroundStyle
uppercasedStateForegroundStyle:
- qButtonUppercasedStateForegroundStyle
- qButtonUpForegroundStyle
...
animation:
- scaleAnimation
- cartoonAnimation
- physicsAnimation
scaleAnimation:
animationType: scale
...
cartoonAnimation:
animationType: cartoon
...
physicsAnimation:
animationType: physics
...

在上面的例子中,按键 qButton 配置了三种动画效果:缩放动画、图片播放动画和物理动画。当用户按下该按键时,这些动画将同时播放,增强用户的交互体验。