5

HarmonyOS - 基于ArkUI(JS)实现信件弹出效果

 1 year ago
source link: https://www.51cto.com/article/719308.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

HarmonyOS - 基于ArkUI(JS)实现信件弹出效果

作者:罗晓纯 2022-09-21 14:51:21
可别觉得书信是一个过时的东西,它可是80后的情怀,90后的回忆,00后的新宠,是经典的代名词。今天就想实现把这些古老的元素融入到新时代的产物当中。
48b6afd66da4c44d2669353e44b22f733bc61a.png

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

自从大家使用QQ、微信、邮件等网络平台交流以后,大家对纸这种介质和书信这种通讯方式可能都比较陌生了。可别觉得书信是一个过时的东西,它可是80后的情怀,90后的回忆,00后的新宠,是经典的代名词。今天就想实现把这些古老的元素融入到新时代的产物当中。

  • 工具:DevEc Studio 3.0 Beta3
  • 主要用到知识:animation,Options,keyframes
  • 官方API链接:​​动画效果​
HarmonyOS - 基于ArkUI(JS)实现信件弹出效果-开源基础软件社区

信件由信封上部分、信封主体和信纸三部分组成,首先通过css实现将三个部分组合成信封的样式,接下来根据animation组件方法中的播放或取消方法来实现信件弹出或收回的动画效果,并在信件展开的同时,使用定时器实现模拟读取文字的效果。

  1. 调整信封上下两个部分的位置,并调整信封和信纸三个部分的层级。
  2. 在点击信件之后,通过id属性标识获取组件对象并调用animate组件方法,给不同id对象调用对应的动画方法。
  3. 对信封两个部分传入展开后的新位置,同时传入信纸新的height值和bottom值。
  4. 使用定时器实现模拟读文字效果
  5. 判断是折叠信封时,调用animate组件的cancel()方法,实现信封收回的效果。

使用到的官方 API

Options属性说明。

duration

number

指定当前动画的运行时长(单位毫秒)。

easing

string

linear

描述动画的时间曲线,支持类型见表4 easing有效值说明。

delay

number

设置动画执行的延迟时间(默认值表示无延迟)。

iterations

number | string

设置动画执行的次数。<br />number表示固定次数,Infinity枚举表示无限次数播放。

direction

string

normal

指定动画的播放模式:<br />normal:动画正向循环播放;<br />reverse:动画反向循环播放;<br />alternate:动画交替循环播放,奇数次正向播放,偶数次反向播放;<br />alternate-reverse:动画反向交替循环播放,奇数次反向播放,偶数次正向播放。

string

指定动画开始和结束的状态:<br />none:在动画执行之前和之后都不会应用任何样式到目标上。<br />forwards:在动画结束后,目标将保留动画结束时的状态(在最后一个关键帧中定义)。<br />backwards6+:动画将在animation-delay期间应用第一个关键帧中定义的值。当animation-direction为"normal"或"alternate"时应用from关键帧中的值,当animation-direction为"reverse"或"alternate-reverse"时应用to关键帧中的值。<br />both:动画将遵循forwards和backwards的规则,从而在两个方向上扩展动画属性。

keyframes 属性说明。

frames

Array<Style>

用于设置动画样式的对象列表。Style类型说明请见变2 Style类型说明。

Style类型说明。

width

number

动画执行过程中设置到组件上的宽度值

height

number

动画执行过程中设置到组件上的高度值

backgroundColor

<color>

动画执行过程中设置到组件上的背景颜色

opacity

number

设置到组件上的透明度(介于0到1之间)。

backgroundPosition

string

格式为”x y“,单位为百分号或者px。<br />第一个值是水平位置,第二个值是垂直位置<br />如果仅规定了一个值,另一个值为50%。

transformOrigin

string

‘center center’

变换对象的中心点。<br />第一个参数表示x轴的值,可以设置为left、center、right、长度值或百分比值。<br />第二个参数表示y轴的值,可以设置为top、center、bottom、长度值或百分比值。

transform

Transform

设置到变换对象上的类型

offset

number

-offset值(如果提供)必须在0.0到1.0(含)之间,并以升序排列。<br />-若只有两帧,可以不填offset。<br />-若超过两帧,offset必填。

animation对象方法说明。

组件播放动画

finish

组件完成动画

pause

组件暂停动画

cancel

组件取消动画

reverse

组件倒播动画

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%;
}
/*信件内容*/
.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社区!",
        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++
    }
}

该篇是通过鸿蒙动画实现的一个小练习,目前我们已经可以借助各种特效功能把实体产品的操作体验模拟到网页上,使得页面看起来更加人性化,更具亲和力。

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​​。

责任编辑:jianghua 来源: 51CTO开源基础软件社区

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK