前言
什么是技术? @,@,@, @安容家,并由官方帐户授权: 授权。
前端早晨阅读课:与您分享“我的”技术愿景
文字从这里开始~~
1。动态效应连接设计和技术1。什么是动态效应连接设计?
随着互联网技术和设计概念的持续发展,动画设计已成为现代UI设计的必不可少的一部分。其中,运动和效率的联系是非常重要的部分。运动效果连接设计是指巧妙的动画设计,不同的UI元素在动画过程中自然而平稳地连接,从而增强了用户的互动体验和视觉体验。在实际应用中,动态效应连接设计主要用于接口过渡,信息提示,状态更改等。通过平稳的连接,用户可以减少在白屏上等待的焦虑。
2。动态和效果连接设计的意义3。什么是技术?
微信系一直用作渲染引擎。它独特的双线架构设计并保持了尽可能兼容的Web规格,并具有很好的开发体验。但是,由于其重大的历史负担和复杂的渲染过程,移动终端中迷你计划的性能能力仍然远离本地应用程序。
为了进一步优化迷你程序的性能,Mini计划在原始渲染引擎之外开发了渲染引擎。它使用了更简化和高效的渲染管道,并且具有许多增强功能,可以使性能体验更接近本地渲染。新的增强功能包括动画系统,手势系统,自定义路由,共享元素动画以及许多常用的组件,例如-View,具有更高的性能实现。
2。实用概念和场景拆卸1。动态和效果连接设计的核心原理
简单清晰的动画设计需要以下原则:
2。概念孵化和使用方案的拆卸
以精致的动态感情为起点,理性的水平使我们具有一般的产品体验感,为构建动态性能概念提供了一个框架。在这方面,我们将继续寻找运动现象,这些现象可以从感觉层面传达真实的感觉,并将它们结合并完善它们。这次,我们在酒店预订链接中使用核心专辑页来执行应用程序方案,并使用技术来进行用户图片的应用程序。
(1)整个过程被拆卸。首先,为了使行动路径在退出时更清晰,进行了响应设计。当接口向右滑动并退出时,专辑图片会减少。在缩放过程中,将根据位移距离控制缩放比率。同时,面膜和磨砂玻璃效果的透明度也会随着手指运动而变化,并在视觉上呈现XY轴与专辑列表页面的上和下层之间的空间关系。将其简化为一定比例时,将触发振动效果,您可以放手并退出专辑列表页面。
(2)在交互结束时,图片返回到专辑列表页面的原始位置。在返回路径的过程中,运动的方向和距离是根据相互作用结束时的定位点来判断运动的,计算运动的加速度,并模拟了运动加速所带来的惯性反弹的方向和角度变化,并增强了动作定律的模拟运动定律。
结合自然世界中的运动定律,将进入页面的元素与驾驶汽车进行了比较,用户将他们视为在斑马十字路口驾驶的人,并将道路用作页面空间。如果汽车使用缓慢的运动(加速度),路上的行人将看到一辆不断加速他的车辆。由于担心车辆正在高速接近,行人会本能地躲避刹车未及时的情况。实际上,页面也一样。使用加速运动在进入元素中对进入元素的移动感知会在用户体验期间引起不适。
3。对技术开发的实际过程分析1。开发自定义路由
为了实现这种交互,需要自定义路由动画,因为可以自定义渲染引擎的页面跳跃动画。使用自定义路由时,在页面跳跃时指定路由类型,将触发自定义路由动画,而不是从右到左的默认动画。这里的实现可以使页面跳跃无默认路由动画。该页面将以透明的方式直接在屏幕上渲染。开发人员控制页面本身中元素的动画显示方法。具体实现如下:
(1)在图像查看页面配置文件中声明。
{
"backgroundColor": "#00000000",
"backgroundColorContent": "#00000000", // 设置客户端页面背景为透明
"navigationStyle": "custom",
"renderer": "skyline", // skyline渲染引擎
"disableScroll": true,
"usingComponents": {
}
}
(2)在WXSS中,将图像查看页的页面节点设置为透明的背景
page {
background: transparent;
}
(3)在JS中,使用wx ..(,fn)声明自定义路由动画
wx.router.addRouteBuilder('myCustomRoute', function (params) {
const handlePrimaryAnimation = () => {
'worklet';
return {
// 可在此处,根据 params.primaryAnimation.value 的值,来设置页面的动画效果
backgroundColor: `rgba(0,0,0,${ params.primaryAnimation.value })`
};
};
return {
opaque: false,
handlePrimaryAnimation,
barrierColor: '',
barrierDismissible: false,
transitionDuration: 320,
reverseTransitionDuration: 250,
canTransitionTo: true,
canTransitionFrom: false
};
})
(4)在“图片列表”页面中,使用WX。跳到页面并将其设置为
wx.navigateTo({
url: '/pages/skyline-image-viewer/index?index=0',
routeType: 'myCustomRoute'
})
该页面的渲染引擎需要配置,并且可以在跳跃时使用它,以便该页面在跳跃时没有默认的路由动画。
2。共享元素旅行
当连续页面跳跃时,页面之间的键相同 - 节点将产生LEAP效果,并且还可以自定义插值方法和动画曲线。通常在图片上使用。为了确保动画效果,应尽可能保持前后页的结构。
<share-element key="share-key">
<view> you code here </view> <!-- 需要注意,share-element 内要求只有一个根节点 -->
</share-element>
目前,接口性能就像上面的视频一样,这是一个连续的动画状态。这是完全由 - 控制的,而动画原理如下图所示:
3。连接手势组件以实现图像扩大,还原和翻译
图片上查看的页面具有以下结构:
<scale-gesture-handle worklet:ongesture="onScaleGestureHandle">
<share-element key="{{ shareKey }}" class="current-item">
<image src="{{ src }}"/>
</share-element>
</scale-gesture-handle>
在这里,我们使用渲染引擎中提供的手势组件来实现手势相互作用,例如图像的增大,减少和翻译。
请注意,所有方法称为指令在UI线程上运行。请勿在方法中修改普通变量,因为跨线程关系只能使用WX声明的变量修改。
const GestureState = {
POSSIBLE: 0, // 此时手势未识别
BEGIN: 1, // 手势已识别
ACTIVE: 2, // 连续手势活跃状态
END: 3, // 手势终止
CANCELLED: 4 // 手势取消
};
Component({
attached() {
this.shareX = wx.worklet.shared(0);
this.shareY = wx.worklet.shared(0);
this.sharScale = wx.worklet.shared(1);
// 声明共享变量,并且给需要变化的dom,绑定动画
this.applyAnimatedStyle('.current-item', () => {
'worklet';
return {
transform: `translate3d(${this.shareX.value}px, ${this.shareY.value}px, 0) scale(${this.sharScale.value})`
}
});
// 页面所需的数据,需要在 attached 事件里初始化完毕,使其可以参与首帧渲染
this.setData({ src: '...', shareKey: '...' });
},
methods: {
// 当手势组件识别到手势时,触发此回调
onScaleGestureHandle(e) {
'worklet';
const { state } = e;
// 在worklet函数里,不要使用 const {} = this 对this解构
const shareX = this.shareX;
const shareY = this.shareY;
const sharScale = this.sharScale;
if (state === GestureState.BEGIN) {
// 手势已经识别,此时,可以获取到手势的初始值
} else if (state === GestureState.ACTIVE) {
// 手势活跃状态,此时,可以获取到手势的变化值,如平移的距离、缩放的比例等
// 将当前变化的值,设置到 `shared` 变量,就可以改变元素的样式,类似于vue3的数据驱动
shareX.value += e.focalDeltaX;
shareY.value += e.focalDeltaY;
sharScale.value = e.scale;
} else if (state === GestureState.END || state === GestureState.CANCELLED) {
// 手势终止或取消,此时,可以获取到手势的最终值
}
}
}
})
4。手势谈判(解决手势冲突)
上面的演示简单地说明了如何使用手势组件与图像进行交互,但是在“图像查看”页面中,我们还有其他手势交互,例如图片的左右滑动切换等。通常,我们使用组件来实现它们。但是,组件和组件的内部实现将听取手势事件。手势组件的事件不支持气泡,这将导致以下结构水平:
<scale-gesture-handle worklet:ongesture="onScaleGestureHandle">
<swiper>
<swiper-item wx:for="{{ imgs }}">
<share-element key="{{ item.shareKey }}" class="current-item">
<image src="{{ item.src }}"/>
</share-element>
</swiper-item>
</swiper>
</scale-gesture-handle>
当使用手势水平滑动时,将首先触发水平切换事件,而手势事件将不会触发,当图像放大时水平滑动图像时,这会造成冲突。目前,需要手势谈判来解决手势冲突。
什么是手势谈判?
手势谈判是指页面同时具有多个手势交互的何时,有必要确定应执行哪些手势事件,并且需要通过某些协议忽略哪些手势事件。
解决手势冲突的方法主要是通过手势组件的标签来实现的,
<!-- <scale-gesture-handle> 缩放手势 -->
<!-- <horizontal-drag-gesture-handler> 横向拖动手势 -->
<!-- 通过 simultaneous-handlers=tag 来声明多个手势应该同时触发 -->
<scale-gesture-handle tag="scale"
simultaneous-handlers="{{['swiper']}}"
worklet:ongesture="onScaleGestureHandle">
<!-- 此处使用 native-view=swiper 代理内部的手势组件 -->
<!-- 通过 should-response-on-move=fn 来参与`事件派发`过程,决定手势的事件是否应该派发 -->
<horizontal-drag-gesture-handler tag="swiper"
native-view="swiper"
simultaneous-handlers="{{['scale']}}"
worklet:should-response-on-move="shouldResponseOnMove">
<swiper>
<swiper-item wx:for="{{ imgs }}">
<share-element key="{{ item.shareKey }}" class="current-item">
<image src="{{ item.src }}"/>
</share-element>
</swiper-item>
</swiper>
</horizontal-drag-gesture-handler>
</scale-gesture-handle>
const GuestureMode = {
INIT: 0,
SCALE: 1,
SWIPE: 2,
MOVE: 3
// ...
};
Component({
attached() {
this.GuestureModeShared = wx.worklet.shared(GuestureMode.INIT);
this.shareX = wx.worklet.shared(0);
this.shareY = wx.worklet.shared(0);
this.shareScale = wx.worklet.shared(1);
// 声明共享变量,并且给需要变化的dom,绑定动画
this.applyAnimatedStyle('.current-item', () => {
'worklet';
return {
transform: `translate3d(${this.shareX.value}px, ${this.shareY.value}px, 0) scale(${this.shareScale.value})`
}
});
// ...
},
methods: {
onScaleGestureHandle(e) {
'worklet';
const { state } = e;
if (state === GestureState.BEGIN) {
this.GuestureModeShared.value = GuestureMode.INIT;
} else if (state === GestureState.ACTIVE) {
if(this.GuestureModeShared.value === GuestureMode.INIT) {
this.gestureBefore(e); // 手势类型未知时,判断手势类型
} else {
this.gestureHandle(e); // 手势类型已知时,处理手势事件
}
} else if (state === GestureState.END || state === GestureState.CANCELLED) {
this.GuestureModeShared.value = GuestureMode.INIT;
}
},
// 判断手势类型
gestureBefore(e) {
'worklet';
const { focalDeltaX, focalDeltaY, scale } = e;
if (Math.abs(focalDeltaX) > Math.abs(focalDeltaY)) {
this.GuestureModeShared.value = GuestureMode.SWIPE;
} else if (scale > 1) {
this.GuestureModeShared.value = GuestureMode.SCALE;
} else {
this.GuestureModeShared.value = GuestureMode.MOVE;
}
},
// 处理手势事件
gestureHandle(e) {
'worklet';
if (this.GuestureModeShared.value === GuestureMode.SCALE) {
this.shareScale.value = e.scale;
} else if (this.GuestureModeShared.value === GuestureMode.SWIPE) {
// swiper 切换模式时,这里什么都不用做
} else if (this.GuestureModeShared.value === GuestureMode.MOVE) {
this.shareX.value += e.focalDeltaX;
this.shareY.value += e.focalDeltaY;
}
},
// 用于判断手势事件是否应该派发
shouldResponseOnMove(e) {
'worklet';
return this.GuestureModeShared.value === GuestureMode.SWIPE; // 当模式为SWIPE时,才响应手势事件
}
}
})
通过上述代码,我们实施手势谈判。当用户在图片上滑动时,始终将触发手势事件。通过判断图片的当前状态,我们决定应触发哪种手势。通过这次谈判,我们让手势在正确的时间触发以避免手势冲突。
5。有些事情要注意使用时
作为一种新的渲染引擎,在使用时,您需要注意一些事情以确保渲染效果和性能。
(1)自定义路由时的第一帧渲染和第一帧性能优化
渲染引擎的第一帧渲染对于共享元素动画非常重要。如果共享元素节点的键错过了第一个帧设置,则可能会丢失LEAP动画。因此,当使用渲染引擎时,共享元素的密钥应在以前或之前设置在页面上,当渲染第一帧时,应尽可能将UI层的渲染效果最小化:
功能的使用
函数的使用存在一些限制,主要是因为它在UI线程中执行,因此在函数中,这不是页面的此实例。其中使用的变量还通过特殊插件将UI线程转换为UI线程。所有需要与逻辑层共享的变量都需要将其声明为共享变量。在UI线程中调用逻辑层的函数需要使用X。
(2)与Web规格的差异
尽管它与Web规范一样一致,但在基础渲染引擎的局限性上仍然存在一些差异,例如:
在非操作环境中的性能是什么?
在非运行环境中,组件将被视为一个组件,并且需要结构良好和兼容。
6。何时使用渲染引擎
在开发过程中,请确保Mini 开发人员工具版本是最新版本,而SDK版本为2.30.2+。有关具体限制,请参考快速体验|微信打开文件:
这些新功能的引入使迷你程序开发的优势更加明显,开发人员可以更方便地实现各种复杂的交互作用,并获得接近本地应用程序的体验。
未来的前景
1。个性化产品表格:根据不同的用户需求和方案,将设计一个更符合用户偏好和习惯的动画效果连接,并将进行组件调用。
2。更自然和真实的动画效果连接:动画效应连接将更接近自然定律和真实的物理效果,从而增强动画的现实主义和用户体验。
3。更智能和自适应的动态效果连接:动态效应连接将根据用户的操作行为和使用习惯自适应调整动画效果,从而改善用户体验和产品效果。
4.扩大产品,设计和开发的协作效果:仅通过控制设计的动态效果,对用户的产品洞察力以及开发应用于新技术的动态效果,我们才能最大程度地提高协作效果。
附录
1。相册代码段:
2。ue标记
3。AB实验效应:AB实验明显赢得0.23%。
关于这篇文章