HarmonyOS - 基于ArkUI(JS)實(shí)現(xiàn)信件彈出效果
??想了解更多關(guān)于開源的內(nèi)容,請?jiān)L問:??
前言
自從大家使用QQ、微信、郵件等網(wǎng)絡(luò)平臺交流以后,大家對紙這種介質(zhì)和書信這種通訊方式可能都比較陌生了??蓜e覺得書信是一個過時(shí)的東西,它可是80后的情懷,90后的回憶,00后的新寵,是經(jīng)典的代名詞。今天就想實(shí)現(xiàn)把這些古老的元素融入到新時(shí)代的產(chǎn)物當(dāng)中。
項(xiàng)目說明
- 工具:DevEc Studio 3.0 Beta3
- 主要用到知識:animation,Options,keyframes
- 官方API鏈接:??動畫效果??
效果展示
實(shí)現(xiàn)原理
信件由信封上部分、信封主體和信紙三部分組成,首先通過css實(shí)現(xiàn)將三個部分組合成信封的樣式,接下來根據(jù)animation組件方法中的播放或取消方法來實(shí)現(xiàn)信件彈出或收回的動畫效果,并在信件展開的同時(shí),使用定時(shí)器實(shí)現(xiàn)模擬讀取文字的效果。
實(shí)現(xiàn)步驟
- 調(diào)整信封上下兩個部分的位置,并調(diào)整信封和信紙三個部分的層級。
- 在點(diǎn)擊信件之后,通過id屬性標(biāo)識獲取組件對象并調(diào)用animate組件方法,給不同id對象調(diào)用對應(yīng)的動畫方法。
- 對信封兩個部分傳入展開后的新位置,同時(shí)傳入信紙新的height值和bottom值。
- 使用定時(shí)器實(shí)現(xiàn)模擬讀文字效果
- 判斷是折疊信封時(shí),調(diào)用animate組件的cancel()方法,實(shí)現(xiàn)信封收回的效果。
使用到的官方 API
Options屬性說明。
參數(shù) | 類型 | 默認(rèn)值 | 說明 |
duration | number | 0 | 指定當(dāng)前動畫的運(yùn)行時(shí)長(單位毫秒)。 |
easing | string | linear | 描述動畫的時(shí)間曲線,支持類型見表4 easing有效值說明。 |
delay | number | 0 | 設(shè)置動畫執(zhí)行的延遲時(shí)間(默認(rèn)值表示無延遲)。 |
iterations | number | string | 1 | 設(shè)置動畫執(zhí)行的次數(shù)。<br />number表示固定次數(shù),Infinity枚舉表示無限次數(shù)播放。 |
direction | string | normal | 指定動畫的播放模式:<br />normal:動畫正向循環(huán)播放;<br />reverse:動畫反向循環(huán)播放;<br />alternate:動畫交替循環(huán)播放,奇數(shù)次正向播放,偶數(shù)次反向播放;<br />alternate-reverse:動畫反向交替循環(huán)播放,奇數(shù)次反向播放,偶數(shù)次正向播放。 |
fill | string | none | 指定動畫開始和結(jié)束的狀態(tài):<br />none:在動畫執(zhí)行之前和之后都不會應(yīng)用任何樣式到目標(biāo)上。<br />forwards:在動畫結(jié)束后,目標(biāo)將保留動畫結(jié)束時(shí)的狀態(tài)(在最后一個關(guān)鍵幀中定義)。<br />backwards6+:動畫將在animation-delay期間應(yīng)用第一個關(guān)鍵幀中定義的值。當(dāng)animation-direction為"normal"或"alternate"時(shí)應(yīng)用from關(guān)鍵幀中的值,當(dāng)animation-direction為"reverse"或"alternate-reverse"時(shí)應(yīng)用to關(guān)鍵幀中的值。<br />both:動畫將遵循forwards和backwards的規(guī)則,從而在兩個方向上擴(kuò)展動畫屬性。 |
keyframes 屬性說明。
屬性 | 類型 | 說明 |
frames | Array<Style> | 用于設(shè)置動畫樣式的對象列表。Style類型說明請見變2 Style類型說明。 |
Style類型說明。
參數(shù) | 類型 | 默認(rèn)值 | 說明 |
width | number | - | 動畫執(zhí)行過程中設(shè)置到組件上的寬度值 |
height | number | - | 動畫執(zhí)行過程中設(shè)置到組件上的高度值 |
backgroundColor | <color> | none | 動畫執(zhí)行過程中設(shè)置到組件上的背景顏色 |
opacity | number | 1 | 設(shè)置到組件上的透明度(介于0到1之間)。 |
backgroundPosition | string | - | 格式為”x y“,單位為百分號或者px。<br />第一個值是水平位置,第二個值是垂直位置<br />如果僅規(guī)定了一個值,另一個值為50%。 |
transformOrigin | string | ‘center center’ | 變換對象的中心點(diǎn)。<br />第一個參數(shù)表示x軸的值,可以設(shè)置為left、center、right、長度值或百分比值。<br />第二個參數(shù)表示y軸的值,可以設(shè)置為top、center、bottom、長度值或百分比值。 |
transform | Transform | - | 設(shè)置到變換對象上的類型 |
offset | number | - | -offset值(如果提供)必須在0.0到1.0(含)之間,并以升序排列。<br />-若只有兩幀,可以不填offset。<br />-若超過兩幀,offset必填。 |
animation對象方法說明。
方法 | 參數(shù) | 說明 |
play | - | 組件播放動畫 |
finish | - | 組件完成動畫 |
pause | - | 組件暫停動畫 |
cancel | - | 組件取消動畫 |
reverse | - | 組件倒播動畫 |
代碼實(shí)現(xiàn)
1、html 部分
<div class="wrap" >
<div class="letter">
<image class="envelopeHead" id="envelopeHead" src="common/images/before.png" style="bottom: {{headerBottom}}px"></image>
<image class="envelope" id="envelope" src="common/images/after.png" style="bottom: {{envelopeBottom}}px"></image>
<div class="paper" id="paper" onclick="fold" style="bottom: {{paperBottom}}px;height:{{paperHeight}}px">
<text class="title">{{ title }}</text>
<text class="content">{{content}}</text>
</div>
</div>
</div>
2、css 部分
.wrap {
justify-content: center;
align-items: center;
flex-direction: column;
width: 100%;
height: 100%;
background-color: #dce6f2;
}
.letter{
height: 450px;
position: relative;
top: 0px;
}
/*信封口樣式*/
.envelopeHead {
position: absolute;
bottom: 250px;
left: 15px;
width: 330px;
height: 200px;
z-index: 1;
}
/*信封樣式*/
.envelope{
bottom: 150px;
position: absolute;
left: 15px;
width: 330px;
height: 200px;
z-index: 3;
}
/*信紙樣式*/
.paper{
position: absolute;
width: 290px;
left: 35px;
justify-content: flex-start;
background-color: #f7f2ec;
bottom: 150px;
z-index: 2;
flex-direction: column;
padding: 0 10px;
}
/* 稱呼*/
.title{
font-size: 26px;
text-shadow: 0 1px 0 #ede8d9;
height:60px;
width: 100%;
}
/*信件內(nèi)容*/
.content{
font-size: 26px;
text-shadow: 0 1px 0 #ede8d9;
width: 100%;
line-height:40px;
}
3、js 部分
import prompt from '@system.prompt';
export default {
data: {
title: "致各位小伙伴:",
content: "",
message: "展信悅!歡迎大家來到Harmony OS社區(qū)!",
headerBottom: 240,
paperBottom: 150,
envelopeBottom: 150,
paperHeight: 170,
animation: '',
animation2: '',
animation3: '',
number: 1
},
onInit() {
},
onShow() {
var options = {
duration: 150,
easing: 'ease-in-out',
delay: 0,
fill: 'forwards',
iterations: 2,
direction: 'normal',
};
var frames = [
{
transform: {
translate: '0px 120px'
},
opacity: 1.0,
offset: 1.0,
height: '350px',
'bottom': 0
}];
var framesHead = [
{
transform: {
translate: '0px 120px'
},
opacity: 1.0,
offset: 1.0,
}];
var framesEnvelope = [
{
transform: {
translate: '0px 120px'
},
opacity: 1.0,
offset: 1.0,
}
];
this.animationPaper = this.$element('paper').animate(frames, options);
this.animationHead = this.$element('envelopeHead').animate(framesHead, options);
this.animationEnvelope = this.$element('envelope').animate(framesEnvelope, options);
},
fold() {
// 判斷是否是展開信紙
if (this.number % 2 === 1) {
// 展開信紙
this.animationPaper.play();
this.animationHead.play();
this.animationEnvelope.play();
for (var index = 0; index < 8; index++) {
this.content += " "
}
var num = 0
var timer = setInterval(() => {
if (num < this.message.length) {
this.content += this.message[num]
num++
}else{
this.timer = null;
}
}, 150)
} else {
// 收回信紙
this.animationPaper.cancel();
this.animationHead.cancel();
this.animationEnvelope.cancel();
this.content = "";
}
this.number++
}
}
總結(jié):
該篇是通過鴻蒙動畫實(shí)現(xiàn)的一個小練習(xí),目前我們已經(jīng)可以借助各種特效功能把實(shí)體產(chǎn)品的操作體驗(yàn)?zāi)M到網(wǎng)頁上,使得頁面看起來更加人性化,更具親和力。