HarmonyOS编写教师节贺卡

简介: 今天是教师节,教师是我最尊敬的职业。感恩一路走来遇到的引路人、一日为师、终身难忘!今天,我来手搓一个教师节贺卡,送给天下所有的老师。

大家好,我是潘Sir,持续分享IT技术,帮你少走弯路。《鸿蒙应用开发从入门到项目实战》系列文章持续更新中,欢迎关注!

今天是教师节,教师是我最尊敬的职业。感恩一路走来遇到的引路人、一日为师、终身难忘!今天,我来手搓一个教师节贺卡,送给天下所有的老师。

一、需求设计

1、实现效果

效果.png

包含动画效果:

  • 顶部一架纸飞机从左到右不断飞行;

  • 中间文字以打字机效果呈现;

  • 底部爱心不断上下跳跃

2、技术分析

整体采用一张图片作为背景;中间文字部分通过定时器输出文字,实现打字机效果;底部爱心是一个自定义图形,通过ArkUI提供的自定义绘制组件Canvas来实现心形绘制,再结合ArkUI提供的动画功能实现心形上下跳动效果。

二、界面制作

1、布局分析

界面布局.png

2、界面制作

使用DevEco Studio创建项目,将teacher_bg.gif 背景图片拷贝到resources/base/media目录下。

2.1 制作主界面

在项目pages目录下新建文件:TeachersDay.ets,内容如下:

@Entry
@Component
struct TeachersDay {
   
  build() {
   
    Stack({
    alignContent: Alignment.Center }) {
   
      //1、 背景图
      Image($r('app.media.teacher_bg'))
        .width('100%')
        .height('120%')

      //2、 文本
      Text("三尺讲台,一柄戒尺\n回首只闻桃李芬芳\n老师,谢谢你的精心教导")
        .fontSize(26)
        .fontWeight(FontWeight.Bold)
        .fontColor(Color.White)
        .lineHeight(40)//行高
        .letterSpacing(2) //字间距

      //3、 心形
      //todo:封装心形组件,减少主文件代码
    }
    .width('100%')
    .height('100%')
    .expandSafeArea([SafeAreaType.SYSTEM]) //去白边
  }
}

这样就实现了界面主体框架,接下来通过Canvas绘制底部的心形图。

2.2 制作心形组件

为了方便代码复用,同时减少主界面代码,讲心形组件单独疯转到自定义组件中。

在ets目录下新建view目录,用于存放自定义组件。在view目录下新建心形组件,HeartCom.ets文件,内容如下:

// 爱心组件
@Component
export struct HeartCom{
   
  private seetings:RenderingContextSettings =new RenderingContextSettings(true)
  private ctx:CanvasRenderingContext2D=new CanvasRenderingContext2D(this.seetings)
  private screenX:number=0 //画布长
  private screenY: number = 0 //画布宽
  startY: number = 0 //爱心区域最低位置Y坐标
  endY: number = 0 //爱心区域最高位置Y坐标
  shortSide: number = 0 //爱心区域边长
  build(){
   
    Flex({
   
      direction: FlexDirection.Column,
      alignItems: ItemAlign.Center,
      justifyContent: FlexAlign.Center
    }){
   
      Canvas(this.ctx)
        .width('100%')
        .height('100%')
        .backgroundColor(Color.Transparent)
        .onReady(() => {
   
          let can = this.ctx
          // 画布赋值
          this.screenX = can.width
          this.screenY = can.height
          this.startY = (this.screenY - this.screenX) / 2
          this.endY = this.screenX + (this.screenY - this.screenX) / 2
          this.shortSide = this.screenX

          // 绘制爱心(控制关键几个点的位置)
          can.fillStyle = "#ff0000"
          can.moveTo(this.screenX / 2, this.startY + this.shortSide / 3)
          can.bezierCurveTo(this.screenX / 6, this.startY, 0, this.screenY / 2, this.screenX / 2,
            this.endY - this.shortSide / 6)

          //立体效果
          let grad = can.createLinearGradient(0, 0, this.screenX, this.endY)
          grad.addColorStop(0.0, '#fd0000')
          grad.addColorStop(1.0, '#ffffff')
          can.fillStyle = grad

          can.fill()
          can.beginPath()
          can.moveTo(this.screenX / 2, this.startY + this.shortSide / 3)
          can.bezierCurveTo(this.screenX * 5 / 6, this.startY, this.screenX, this.screenY / 2, this.screenX / 2,
            this.endY - this.shortSide / 6)
          can.fill()

        })
    }
  }
}

在该组件中,使用Canvas组件完成心形绘制,并通过export导出组件,以便供其它组件使用。

接下来,在主界面中中引入该组件,并将其显示到主界面中。主界面TeachersDay.ets文件做如下修改:

import {
    HeartCom } from '../view/HeartCom'
...

//3、 心形
      //todo:封装心形组件,减少主文件代码
      HeartCom()
        .width(150)
        .height(150)
        .margin({
    top: 400 })
...

至此,完成静态的界面制作。

三、功能实现

1、打字机效果

接下来,将主界面中间的文字添加打字机效果(一个字一个字的输出)。

修改主界面,将显示文本存放到变量,并通过定时器取文本进行显示。文件TeachersDay.ets修改如下:

@State message?: string = "" //打印文本
intervalID?: number //定时器

...
//2、 文本
Text(this.message)
...

onPageShow() {
   
  this.printer() //触发打字
}

// 打字机效果
  private printer() {
   
    let data = "三尺讲台,一柄戒尺\n回首只闻桃李芬芳\n老师,谢谢你的精心教导"
    let position: number = 0
    this.intervalID = setInterval(() => {
   
      position = position + 1
      this.message = data.substring(0, position)
      if (this.message.length >= data.length) {
   
        clearInterval(this.intervalID)
      }
    }, 400)
  }

以上代码将界面显示的文本存放到状态变量message,封装printer函数通过定时器setInterval实现每400毫秒打印一个字符。在页面显示的周期函数onPageShow中触发打字操作。

这样,就实现了文本打字机效果。

2、心形动画

接下来,通过设置动画效果,让底部的心形上下跳动起来。

在TeachersDay.ets文件中,找到心形组件HeartCom,为其设置animation动画属性实现动画效果。TeachersDay.ets文件修改内容如下:

...
@State initSize: number = 400
@State flag: boolean = false
...

//3、 心形
      HeartCom()
        .width(150)
        .height(150)
        .margin({
    top: this.initSize })
        .animation({
   
          iterations: 1,
          duration: 1000,
          curve: this.flag ? Curve.LinearOutSlowIn : Curve.FastOutLinearIn,
          playMode: PlayMode.Alternate,
          onFinish: () => {
   
            if (this.flag) {
   
              this.initSize = 400
              this.flag = false
            } else {
   
              this.initSize = 500
              this.flag = true
            }
          }
        })

...
  onPageShow() {
   
    this.initSize = 500 //触发动画
  }
...

通过initSize记录心形组件初始margin值,在onPageShow周期函数中将其值设置为500,表示初始时心形组件距离顶部400,页面显示时向下移动至500,这就让margin属性产生了变化。而心形组件通过animation属性设置了属性动画,就会让这一变化产生从上往下的动画效果。在属性动画中,通过控制flag的值来让心形组件不断进行上下跳动,从而实现不停跳跃的动画效果。

至此、教师节贺卡动画功能实现。

《鸿蒙应用开发从入门到项目实战》系列文章持续更新中,欢迎关注!

相关文章
|
2天前
|
人工智能 运维 安全
|
5天前
|
SpringCloudAlibaba 负载均衡 Dubbo
微服务架构下Feign和Dubbo的性能大比拼,到底鹿死谁手?
本文对比分析了SpringCloudAlibaba框架下Feign与Dubbo的服务调用性能及差异。Feign基于HTTP协议,使用简单,适合轻量级微服务架构;Dubbo采用RPC通信,性能更优,支持丰富的服务治理功能。通过实际测试,Dubbo在调用性能、负载均衡和服务发现方面表现更出色。两者各有适用场景,可根据项目需求灵活选择。
386 124
微服务架构下Feign和Dubbo的性能大比拼,到底鹿死谁手?
|
7天前
|
人工智能 JavaScript 测试技术
Qwen3-Coder入门教程|10分钟搞定安装配置
Qwen3-Coder 挑战赛简介:无论你是编程小白还是办公达人,都能通过本教程快速上手 Qwen-Code CLI,利用 AI 轻松实现代码编写、文档处理等任务。内容涵盖 API 配置、CLI 安装及多种实用案例,助你提升效率,体验智能编码的乐趣。
702 107
|
2天前
|
算法 Python
【轴承故障诊断】一种用于轴承故障诊断的稀疏贝叶斯学习(SBL),两种群稀疏学习算法来提取故障脉冲,第一种仅利用故障脉冲的群稀疏性,第二种则利用故障脉冲的额外周期性行为(Matlab代码实现)
【轴承故障诊断】一种用于轴承故障诊断的稀疏贝叶斯学习(SBL),两种群稀疏学习算法来提取故障脉冲,第一种仅利用故障脉冲的群稀疏性,第二种则利用故障脉冲的额外周期性行为(Matlab代码实现)
223 152
|
4天前
|
Java 数据库 数据安全/隐私保护
Spring 微服务和多租户:处理多个客户端
本文介绍了如何在 Spring Boot 微服务架构中实现多租户。多租户允许单个应用实例为多个客户提供独立服务,尤其适用于 SaaS 应用。文章探讨了多租户的类型、优势与挑战,并详细说明了如何通过 Spring Boot 的灵活配置实现租户隔离、动态租户管理及数据源路由,同时确保数据安全与系统可扩展性。结合微服务的优势,开发者可以构建高效、可维护的多租户系统。
203 127
|
4天前
|
Web App开发 前端开发 API
在折叠屏应用中,如何处理不同屏幕尺寸和设备类型的样式兼容性?
在折叠屏应用中,如何处理不同屏幕尺寸和设备类型的样式兼容性?
230 124
|
2天前
|
编解码 算法 自动驾驶
【雷达通信】用于集成传感和通信的OFDM雷达传感算法(Matlab代码实现)
【雷达通信】用于集成传感和通信的OFDM雷达传感算法(Matlab代码实现)
172 125
|
2天前
|
JavaScript 关系型数据库 MySQL
基于python的网上外卖订餐系统
本系统基于Python与Flask框架,结合MySQL数据库及Vue前端技术,实现了一个功能完善的网上订餐平台。系统涵盖餐品、订单、用户及评价管理模块,并深入研究订餐系统的商业模式、用户行为与服务质量。技术上采用HTML、PyCharm开发工具,支持移动端访问,助力餐饮业数字化转型。