知識(shí)
不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價(jià)值,我們在追求其視覺表現(xiàn)的同時(shí),更側(cè)重于功能的便捷,營銷的便利,運(yùn)營的高效,讓網(wǎng)站成為營銷工具,讓軟件能切實(shí)提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序?yàn)楹笃谏?jí)提供便捷的支持!
您當(dāng)前位置>首頁 » 新聞資訊 » 小程序相關(guān) >
小程序與動(dòng)畫的故事
發(fā)表時(shí)間:2021-4-13
發(fā)布人:葵宇科技
瀏覽次數(shù):66
一、故事序幕
時(shí)間一分一秒地流逝,小程序已伴隨我們?nèi)d有余,今天要講的是關(guān)于小程序與動(dòng)畫的故事:從前...
二、故事開頭
一提小程序與動(dòng)畫,首先想到的是什么?嗯,微信小程序獨(dú)創(chuàng)了一套動(dòng)畫玩法,官方支持3種動(dòng)畫方案,分別是 createAnimation
、 this.animate
和 CSS3動(dòng)畫
。
1. createAnimation
與 Animation
創(chuàng)建一個(gè)動(dòng)畫實(shí)例animation。調(diào)用實(shí)例的方法來描述動(dòng)畫。最后通過動(dòng)畫實(shí)例的export方法導(dǎo)出動(dòng)畫數(shù)據(jù)傳遞給組件的animation屬性。
var animation = wx.createAnimation({
transformOrigin: "50% 50%",
duration: 1000,
timingFunction: "ease",
delay: 0
})
// step() 表示一組動(dòng)畫的完成,可以在一組動(dòng)畫中調(diào)用任意多個(gè)動(dòng)畫方法
// 一組動(dòng)畫中的所有動(dòng)畫會(huì)同時(shí)開始,一組動(dòng)畫完成后才會(huì)進(jìn)行下一組動(dòng)畫
animation.translate(150, 0).rotate(180).step()
animation.opacity(0).scale(0).step()
this.setData({
animationData: animation.export()
})
2. 關(guān)鍵幀動(dòng)畫 this.animate
接口
從小程序基礎(chǔ)庫 2.9.0 開始支持一種更友好的動(dòng)畫創(chuàng)建方式,用于代替舊的 wx.createAnimation 。它具有更好的性能和更可控的接口。在頁面或自定義組件中,當(dāng)需要進(jìn)行關(guān)鍵幀動(dòng)畫時(shí),可以使用 this.animate 接口。
this.animate(selector, keyframes, duration, callback)
官方給出的例子:
this.animate('#container', [
{ opacity: 1.0, rotate: 0, backgroundColor: '#FF0000' },
{ opacity: 0.5, rotate: 45, backgroundColor: '#00FF00'},
{ opacity: 0.0, rotate: 90, backgroundColor: '#FF0000' },
], 5000, function () {
this.clearAnimation('#container', { opacity: true, rotate: true }, function () {
console.log("清除了#container上的opacity和rotate屬性")
})
}.bind(this))
3. css3動(dòng)畫
這是界面動(dòng)畫的常見方式,CSS 動(dòng)畫運(yùn)行效果良好,甚至在低性能的系統(tǒng)上。渲染引擎會(huì)使用跳幀或者其他技術(shù)以保證動(dòng)畫表現(xiàn)盡可能的流暢。
利用樣式實(shí)現(xiàn)小程序動(dòng)畫,用法和css用法相似,定義好指定的動(dòng)畫類名后給元素加上即可。
這是一個(gè)模仿心跳的動(dòng)畫:
@keyframes heartBeat {
0% {
transform: scale(1);
}
14% {
transform: scale(1.3);
}
28% {
transform: scale(1);
}
42% {
transform: scale(1.3);
}
70% {
transform: scale(1);
}
}
.heartBeat {
animation-name: heartBeat;
animation-duration: 1.3s;
animation-timing-function: ease-in-out;
}
三、故事發(fā)展
故事的設(shè)定是這樣子的:需要支持多種預(yù)設(shè)的動(dòng)畫效果配置,且實(shí)現(xiàn)進(jìn)場動(dòng)畫、強(qiáng)調(diào)動(dòng)畫、退場動(dòng)畫按順序運(yùn)行。
如下,“3件5折/2件7折/1件9折”的文本 設(shè)置了 進(jìn)場動(dòng)畫-從小到大 以及 強(qiáng)調(diào)動(dòng)畫-脈沖 的動(dòng)畫效果:
生成的小程序效果:
Taro 是小程序的好伙伴,而且基于故事的設(shè)定,H5 還是要點(diǎn)飯吃的。
要想快速進(jìn)入故事高潮,不得不采用一些取巧的手段了,決定采用市面上常見的 Animate.css 動(dòng)畫庫來支持多種預(yù)設(shè)的動(dòng)畫效果!
1. 支持多種動(dòng)畫配置
Animate.css是一個(gè)可在您的Web項(xiàng)目中使用的即用型跨瀏覽器動(dòng)畫庫,預(yù)設(shè)了抖動(dòng)(shake)、閃爍(flash)、彈跳(bounce)、翻轉(zhuǎn)(flip)、旋轉(zhuǎn)(rotateIn/rotateOut)、淡入淡出(fadeIn/fadeOut)等97種動(dòng)畫效果。 官網(wǎng) 首頁即可查看所有動(dòng)畫效果。
要支持多種動(dòng)畫配置,考慮將 animate.css 這個(gè)非常棒的css庫引入到小程序內(nèi)使用。
從 https://github.com/animate-cs... 下載源碼,將 .css 文件 改名為 .wxss 或者.scss 文件,在頁面或組件中引入樣式文件即可。
import './animate.scss'
Animate.css 的使用非常簡單,因?yàn)樗前巡煌膭?dòng)畫類型綁定到了不同的類里,所以想用哪種動(dòng)畫,只需要把相應(yīng)的類添加到元素上就可以盡情享用了。
由于小程序?qū)Υa包的大小限制,因此可刪除 animate.css 中所有 @-webkit-
等前綴的樣式減少一半體積,甚至直接使用 @keyframes
的代碼,即去掉類名的方式調(diào)用。
2. 執(zhí)行完一個(gè)動(dòng)畫后接著執(zhí)行另一個(gè)動(dòng)畫 ?
從上文可知,采用的是CSS3的動(dòng)畫方案,基本決定了故事的下一個(gè)發(fā)展階段。
如果要實(shí)現(xiàn)進(jìn)場動(dòng)畫、強(qiáng)調(diào)動(dòng)畫、退場動(dòng)畫按順序運(yùn)行,那么需要監(jiān)聽上一個(gè)動(dòng)畫結(jié)束,緊接著運(yùn)行下一個(gè)動(dòng)畫。
動(dòng)畫過程中,微信小程序可以使用 bindtransitionend
、 bindanimationstart
、 bindanimationiteration
、 bindanimationend
來監(jiān)聽動(dòng)畫事件。
在 Taro 中內(nèi)置組件的事件依然是以 on 開頭的,即 onTransitionEnd
、 onAnimationStart
、 onAnimationIteration
、 onAnimationEnd
。
注意:監(jiān)聽動(dòng)畫事件都不是冒泡事件,需要綁定在真正發(fā)生了動(dòng)畫的節(jié)點(diǎn)上才會(huì)生效。
要實(shí)現(xiàn)進(jìn)場之前不可見,退場后不可見,設(shè)置 animation-fill-mode: both
即可,且不可移除樣式,因?yàn)橥藞鰟?dòng)畫的效果效果 會(huì)失效,元素又顯示出來了。
可能還得處理其他行為,比如 消失的元素 實(shí)際可能還占位,交互點(diǎn)擊的行為最好解綁。
<View
onAnimationEnd={this.onAnimationEnd}
>
{this.props.children}
</View>
四、故事高潮
故事都鋪墊好了,終于來到了高潮。
眼尖的人兒也發(fā)現(xiàn)了,上文GIF圖 “生成的小程序效果” 還實(shí)現(xiàn)了滾動(dòng)到可視區(qū)域才開始執(zhí)行動(dòng)畫的效果。
這是老生常談的話題了,那怎么在小程序側(cè)實(shí)現(xiàn)呢?
方案一:頁面滾動(dòng)模式
- 小程序利用
onPageScroll
的 API 監(jiān)聽用戶滑動(dòng)頁面事件,可獲取scrollTop
:頁面在垂直方向已滾動(dòng)的距離(單位px)。 Taro.createSelectorQuery
獲取元素在顯示區(qū)域的豎直滾動(dòng)位置。- 基上計(jì)算是否在可視區(qū)域來判斷是否要開始動(dòng)畫。
方案二:觀察者模式
- 不支持
onPageScroll
的情況下,則需要使用Taro.createIntersectionObserver
獲取目標(biāo)節(jié)點(diǎn)與參照區(qū)域的相交比例觸發(fā)相關(guān)的回調(diào)函數(shù),即觀察者模式。
代碼奉上
(1) Taro獲取當(dāng)前頁面的方式
首先我們要知道如何獲取當(dāng)前頁面棧,數(shù)組中第一個(gè)元素為首頁,最后一個(gè)元素為當(dāng)前頁面:
getCurrentPage () {
const pages = Taro.getCurrentPages ? Taro.getCurrentPages() : [{}]
const currentPage = pages[pages.length - 1]
return currentPage
}
(2) 初始化頁面滾動(dòng)
判斷使用頁面滾動(dòng)模式還是觀察者模式:
initPageScroll () {
const env = Taro.getEnv()
const currentPage = this.getCurrentPage()
// 獲取onPageScroll方法
const onPageScroll = currentPage.onPageScroll
// 頁面滾動(dòng)模式:h5 或「小程序頁面有onPageScroll鉤子」使用統(tǒng)一的代碼
const isPageScroll =
env === Taro.ENV_TYPE.WEB ||
(env !== Taro.ENV_TYPE.WEB && onPageScroll !== undefined)
// 觀察者模式:小程序頁面沒有 onPageScroll 鉤子,使用 Taro.createIntersectionObserver 監(jiān)聽
const isObserver = env !== Taro.ENV_TYPE.WEB && Taro.createIntersectionObserver
if (isPageScroll) {
this.listenPageScroll(currentPage)
} else if (isObserver) {
this.observePageScroll()
}
}
(3) 頁面滾動(dòng)模式
首先在類外頭定義一個(gè)多環(huán)境的 pageScroll 鉤子,支持小程序和H5:
const createPageScroll = function(page) {
const env = Taro.getEnv()
let onPageScroll = () => {}
if (env !== Taro.ENV_TYPE.WEB) {
// 小程序
const prevOnPageScroll = page.onPageScroll.bind(page)
page.onPageScroll = e => {
prevOnPageScroll(e)
onPageScroll(e)
}
} else if (env === Taro.ENV_TYPE.WEB) {
// H5
window.addEventListener("scroll", () => {
onPageScroll({ scrollTop: window.scrollY })
})
}
return nextOnPageScroll => {
onPageScroll = nextOnPageScroll
}
}
使用上述定義的createPageScroll方法,開始監(jiān)聽滾動(dòng):
listenPageScroll (currentPage) {
const pageScroll = createPageScroll(currentPage)
pageScroll(this.onScroll)
}
獲取距離頁面頂部高度來判斷是否要開始動(dòng)畫:
知識(shí)點(diǎn):
- 在 Taro 的頁面和組件類中,
this
指向的是 Taro 頁面或組件的實(shí)例,而通過this.$scope
獲取 Taro 的頁面和組件所對應(yīng)的小程序原生頁面和組件的實(shí)例。 Taro.createSelectorQuery
返回一個(gè) SelectorQuery 對象實(shí)例。在自定義組件或包含自定義組件的頁面中,應(yīng)使用 this.createSelectorQuery() 來代替。- SelectorQuery對象實(shí)例可進(jìn)一步查詢節(jié)點(diǎn)信息,提供
select
、in
、exec
等方法。 - NodesRef 的
boundingClientRect
用于查詢節(jié)點(diǎn)的布局位置,相對于顯示區(qū)域,以像素為單位,其功能類似于 DOM 的 getBoundingClientRect。
onScroll = () => {
const query = Taro.createSelectorQuery().in(this.$scope)
query
.select(`.animation-${this.uniq}`)
.boundingClientRect(res => {
if (!res) return
let resTop = res.top
const distance = res.height / 2
const isStartAnimation = resTop + distance < this.windowHeight
if (isStartAnimation && !this.isAnimated) {
this.startAnimation()
// 動(dòng)畫只出現(xiàn)一次
this.isAnimated = true
}
})
.exec()
}
(4) 觀察者模式:
知識(shí)點(diǎn):
Taro.createIntersectionObserver
創(chuàng)建并返回一個(gè) IntersectionObserver 對象實(shí)例。在自定義組件或包含自定義組件的頁面中,應(yīng)使用 this.createIntersectionObserver([options]) 來代替。- IntersectionObserver 對象,用于推斷某些節(jié)點(diǎn)是否可以被用戶看見、有多大比例可以被用戶看見。
- IntersectionObserver 的
relativeToViewport
方法 指定頁面顯示區(qū)域作為參照區(qū)域之一。 - IntersectionObserver 的
observe
指定目標(biāo)節(jié)點(diǎn)并開始監(jiān)聽相交狀態(tài)變化情況,其中res.intersectionRatio
指相交區(qū)域占目標(biāo)節(jié)點(diǎn)的布局區(qū)域的比例。
observePageScroll () {
const navObserver = Taro.createIntersectionObserver(this.$scope, {
initialRatio: 0.5,
thresholds: [0.5]
})
navObserver.relativeToViewport()
navObserver.observe(`.animation-${this.uniq}`, res => {
const isStartAnimation = !this.isAnimated && res.intersectionRatio > 0.5
if (isStartAnimation) {
this.startAnimation()
// 動(dòng)畫只出現(xiàn)一次
this.isAnimated = true
}
})
}
五、故事結(jié)尾
小程序與動(dòng)畫的故事遠(yuǎn)遠(yuǎn)沒有結(jié)束,縱使故事有了開頭,你看到的只是故事的萬種可能的其中一種。
故事就要告一段落了,小程序的故事還在持續(xù)奔跑,感謝 微信小程序 和 taro 的文檔。
歡迎關(guān)注凹凸實(shí)驗(yàn)室博客: aotu.io
或者關(guān)注凹凸實(shí)驗(yàn)室公眾號(hào)(AOTULabs),不定時(shí)推送文章。
相關(guān)案例查看更多
相關(guān)閱讀
- 云南網(wǎng)站建設(shè)服務(wù)公司
- 云南小程序開發(fā)
- 云南衛(wèi)視小程序
- php網(wǎng)站
- 云南省城鄉(xiāng)建設(shè)廳網(wǎng)站
- 云南小程序開發(fā)公司
- .net網(wǎng)站
- 網(wǎng)絡(luò)公司哪家好
- 汽車報(bào)廢軟件
- 云南手機(jī)網(wǎng)站建設(shè)
- typescript
- 大理小程序開發(fā)
- 云南網(wǎng)站建設(shè)首選公司
- 云南建設(shè)廳網(wǎng)站首頁
- 網(wǎng)站建設(shè)首頁
- 跳轉(zhuǎn)小程序
- 河南小程序制作
- 汽車報(bào)廢管理系統(tǒng)
- 云南小程序定制
- 汽車報(bào)廢回收軟件
- 服務(wù)器
- 報(bào)廢車拆解回收管理系統(tǒng)
- 網(wǎng)站優(yōu)化公司
- 云南網(wǎng)站建設(shè)哪家好
- 云南小程序開發(fā)哪家好
- 前端技術(shù)
- 網(wǎng)站建設(shè)招商
- 國內(nèi)知名網(wǎng)站建設(shè)公司排名
- 手機(jī)網(wǎng)站建設(shè)
- 云南網(wǎng)站維護(hù)