写点什么

HarmonyOS 编写教师节贺卡

作者:程序员潘Sir
  • 2025-09-10
    四川
  • 本文字数:3006 字

    阅读完需:约 10 分钟

HarmonyOS编写教师节贺卡

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


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

一、需求设计

1、实现效果


包含动画效果:


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

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

  • 底部爱心不断上下跳跃

2、技术分析

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

二、界面制作

1、布局分析


2、界面制作

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

2.1 制作主界面

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


@Entry@Componentstruct 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 文件,内容如下:


// 爱心组件@Componentexport 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 的值来让心形组件不断进行上下跳动,从而实现不停跳跃的动画效果。


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


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

发布于: 刚刚阅读数: 4
用户头像

相信坚持的力量! 2020-06-22 加入

80后创业者、高级架构师,带你轻松学编程!著有《Node.js全栈开发从入门到项目实战》、《Java企业级软件开发》、《HarmonyOS应用开发实战》等书籍。“自学帮”公众号主。

评论

发布
暂无评论
HarmonyOS编写教师节贺卡_鸿蒙_程序员潘Sir_InfoQ写作社区