0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

鸿蒙HarmonyOS开发实例:【简单时钟】

jf_46214456 来源:jf_46214456 作者:jf_46214456 2024-04-10 09:48 次阅读

简单时钟

介绍

本示例通过使用[@ohos.display]接口以及Canvas组件来实现一个简单的时钟应用。

效果预览

image.png

使用说明

1.界面通过setInterval实现周期性实时刷新时间,使用Canvas绘制时钟,指针旋转角度通过计算得出。

例如:"2 * Math.PI / 60 * second"是秒针旋转的角度。

鸿蒙开发应用知识已更新[gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md]参考前往。

搜狗高速浏览器截图20240326151547.png

具体实现

鸿蒙学习文档前往mau123789是v添加即可
  • 本示例展示简单时钟的方法主要封装在Index中,源码参考:[Index.ets] 。
/*

 * Copyright (c) 2022 Huawei Device Co., Ltd.

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 *

 *     http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */

import display from '@ohos.display'

import Logger from '../model/Logger'



const HOURS: Array< string > = ['3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '1', '2']

const HEIGHT_ADD: number = 150 // 表盘下面需要绘制时间,canvas高度是宽度加150

const TAG: string = 'Index'



@Entry

@Component

struct Clock {

  private settings: RenderingContextSettings = new RenderingContextSettings(true)

  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)

  @State canvasWidth: number = 300 // 300是表盘默认大小

  private radius: number = 150 // 默认表盘半径

  private intervalId: number = 0

  updateTime = () = > {

    this.context.clearRect(0, 0, this.canvasWidth, this.canvasWidth + HEIGHT_ADD)

    let nowTime = new Date()

    let hour = nowTime.getHours()

    let minute = nowTime.getMinutes()

    let second = nowTime.getSeconds()

    let time = `${this.fillTime(hour)}:${this.fillTime(minute)}:${this.fillTime(second)}`

    this.drawBackGround()

    this.drawHour(hour, minute)

    this.drawMinute(minute)

    this.drawSecond(second)

    this.drawDot()

    this.drawTime(time)

    this.context.translate(-this.radius, -this.radius)

  }



  fillTime(time: number) {

    return time < 10 ? `0${time}` : `${time}`

  }



  aboutToAppear() {

    this.getSize()

  }



  // 获取设备宽高计算表盘大小

  async getSize() {

    let mDisplay = await display.getDefaultDisplay()

    Logger.info(TAG, `getDefaultDisplay mDisplay = ${JSON.stringify(mDisplay)}`)

    this.canvasWidth = px2vp(mDisplay.width > mDisplay.height ? mDisplay.height * 0.6 : mDisplay.width * 0.6)

    this.radius = this.canvasWidth / 2

  }



  drawBackGround() {



    // 绘制背景

    let grad = this.context.createRadialGradient(this.radius, this.radius, this.radius - 32, this.radius,

      this.radius, this.radius)

    grad.addColorStop(0.0, 'white')

    grad.addColorStop(0.9, '#eee')

    grad.addColorStop(1.0, 'white')

    this.context.fillStyle = grad

    this.context.fillRect(0, 0, this.canvasWidth, this.canvasWidth)



    // 绘制外圈圆

    this.context.translate(this.radius, this.radius)

    this.context.lineWidth = 6

    this.context.beginPath()

    this.context.strokeStyle = '#fff'

    this.context.arc(0, 0, this.radius - 5, 0, 2 * Math.PI, false)

    this.context.stroke()



    // 绘制时间文字

    this.context.font = '30px'

    this.context.textAlign = "center"

    this.context.textBaseline = "middle"

    this.context.fillStyle = '#000'

    this.context.save()

    HOURS.forEach((num, index) = > {

      let rad = 2 * Math.PI / 12 * index

      let x = Math.cos(rad) * (this.radius - 38)

      let y = Math.sin(rad) * (this.radius - 38)

      this.context.fillText(num, x, y)

    })

    this.context.restore()



    // 绘制刻度

    for (let i = 0; i < 60; i++) {

      let rad = 2 * Math.PI / 60 * i

      let x = Math.cos(rad) * (this.radius - 12)

      let y = Math.sin(rad) * (this.radius - 12)

      this.context.beginPath()

      this.context.moveTo(x, y)

      if (i % 5 == 0) {

        let x1 = Math.cos(rad) * (this.radius - 20)

        let y1 = Math.sin(rad) * (this.radius - 20)

        this.context.strokeStyle = '#000'

        this.context.lineWidth = 2

        this.context.lineTo(x1, y1)

      } else {

        let x1 = Math.cos(rad) * (this.radius - 18)

        let y1 = Math.sin(rad) * (this.radius - 18)

        this.context.strokeStyle = '#ccc'

        this.context.lineWidth = 1

        this.context.lineTo(x1, y1)

      }

      this.context.stroke()

    }

    this.context.restore()

  }



  // 绘制时针

  drawHour(hour: number, minute: number) {

    this.context.save()

    this.context.beginPath()

    this.context.lineWidth = 8

    this.context.lineCap = 'round'

    let rad = 2 * Math.PI / 12 * hour

    let mrad = 2 * Math.PI / 12 / 60 * minute

    this.context.rotate(rad + mrad)

    this.context.moveTo(0, 10)

    this.context.strokeStyle = '#000'

    this.context.lineTo(0, -this.radius / 2)

    this.context.stroke()

    this.context.restore()

  }



  // 绘制分针

  drawMinute(minute: number) {

    this.context.save()

    this.context.beginPath()

    this.context.lineWidth = 5

    this.context.lineCap = 'round'

    let rad = 2 * Math.PI / 60 * minute

    this.context.rotate(rad)

    this.context.moveTo(0, 10)

    this.context.strokeStyle = '#000'

    this.context.lineTo(0, -this.radius + 40)

    this.context.stroke()

    this.context.restore()

  }



  // 绘制秒针

  drawSecond(second: number) {

    this.context.save()

    this.context.beginPath()

    this.context.lineWidth = 2

    this.context.lineCap = 'round'

    let rad = 2 * Math.PI / 60 * second

    this.context.rotate(rad)

    this.context.moveTo(0, 10)

    this.context.strokeStyle = '#05f'

    this.context.lineTo(0, -this.radius + 21)

    this.context.stroke()

    this.context.restore()

  }



  // 绘制中心

  drawDot() {

    this.context.save()

    this.context.beginPath()

    this.context.fillStyle = '#05f'

    this.context.arc(0, 0, 4, 0, 2 * Math.PI, false)

    this.context.fill()

    this.context.restore()

  }



  // 绘制表盘下面时间文本

  drawTime(time: string) {

    this.context.save()

    this.context.beginPath()

    this.context.font = '90px'

    this.context.textAlign = "center"

    this.context.textBaseline = "middle"

    this.context.fillStyle = '#000'

    this.context.fillText(time, 0, this.radius + 80)

    this.context.restore()

  }



  build() {

    Stack({ alignContent: Alignment.Center }) {

      Canvas(this.context)

        .padding({ top: 76 })

        .width(this.canvasWidth)

        .height(this.canvasWidth + HEIGHT_ADD)

        .onReady(() = > {

          this.updateTime()

          this.intervalId = setInterval(this.updateTime, 1000)

        })

    }

    .width('100%')

    .height('100%')

  }



  onPageHide() {

    clearInterval(this.intervalId)

  }



  aboutToDisappear(){

    clearInterval(this.intervalId)

  }

}
  • 设置表盘大小:通过Index中的display.getDefaultDisplay()方法来获取设备宽高计算表盘大小;
  • 获取当前时间:调用updateTime函数,执行new Date().getHours()、new Date().getMinutes()、new Date().getSeconds()获取当前时间。
  • 绘制表盘内容:通过[CanvasRenderingContext2D] 来画表盘背景、时针、分针、秒针、圆心以及表盘下方文本;
  • 启动时钟:添加setInterval定时器,每隔1s执行一次updateTime函数。

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 时钟
    +关注

    关注

    10

    文章

    1713

    浏览量

    131267
  • 鸿蒙
    +关注

    关注

    57

    文章

    2301

    浏览量

    42682
  • HarmonyOS
    +关注

    关注

    79

    文章

    1966

    浏览量

    29960
收藏 人收藏

    评论

    相关推荐

    免费学习鸿蒙HarmonyOS开发,一些地址分享

    国内一流高校。通过鸿蒙班的设立,高校可以为学生提供专业的鸿蒙OS学习环境和丰富的实践机会,培养出更多的鸿蒙开发人才,为鸿蒙OS系统的生态建设
    发表于 01-12 20:48

    HarmonyOS SDK,助力开发者打造焕然一新的鸿蒙原生应用

    的操作整合在一起,用户一处会用,处处会用。 作为支撑鸿蒙原生应用开发的核心,HarmonyOS SDK 发挥着至关重要的作用。通过关键能力底层化,通用能力全局化,HarmonyOS S
    发表于 01-19 10:31

    如何获取HarmonyOS开发板 ?鸿蒙开发板全汇总

    :http://t.elecfans.com/product/116.html润和HarmonyOS鸿蒙开发板 HiSpark IPC DIY开发套件购买地址:http://t.ele
    发表于 09-10 17:16

    首批HarmonyOS系统课程开发者为您详解鸿蒙系统开发与应用

    首批HarmonyOS系统课程开发者。简介:在这里不仅有大神教你如何安装应用,更有实力派讲师带领大家进行u-boot、内核、跟文件系统的移植。鸿蒙开发课程介绍:第一节
    发表于 09-14 14:26

    鸿蒙系统(HarmonyOS)精华问答集锦

    对于鸿蒙系统,各位小伙伴是不是和小编一样,还是有很多问题不解。本期小编就整理了鸿蒙系统首批体验者精选问答。他们从开发者的角度出发,首先介绍了HarmonyOS的体系、内核、系统特色,以
    发表于 10-10 15:13

    【每日精选】鸿蒙大咖HarmonyOS开发资料合集

    的各种开发资料,内容包括:设计参考、程序源码、开发实例、教程笔记等等,为大家节省了大量的资料搜索时间,方便大家轻松下载HarmonyOS相关资料!H
    发表于 10-28 18:43

    鸿蒙HarmonyOS开发学习资料汇总推荐

    `一、鸿蒙IDE下载地址IDE下载 : https://developer.harmonyos.com/cn/develop/deveco-studio?&ha_source=d
    发表于 04-20 11:33

    HarmonyOS资料下载专题

    HarmonyOS资料下载专题:从鸿蒙出世到现在,对于鸿蒙资料查询下载,大家是否有点迷茫-不知去何处查找。为此,本专题汇集了HarmonyOS从入门到精通的各种
    发表于 10-08 14:23
    <b class='flag-5'>HarmonyOS</b>资料下载专题

    华为鸿蒙系统HarmonyOS如何解决音画不同步?

    华为鸿蒙系统HarmonyOS解决音画同步问题,采用了软时钟同步和抗干扰算法以保证生态系统多设备音画流畅。
    的头像 发表于 06-02 20:13 4366次阅读

    华为鸿蒙系统HarmonyOS升级机型

    华为鸿蒙系统HarmonyOS升级机型
    的头像 发表于 06-02 21:30 7114次阅读
    华为<b class='flag-5'>鸿蒙</b>系统<b class='flag-5'>HarmonyOS</b>升级机型

    鸿蒙系统是基于什么开发

    2021年6月2日晚,华为正式发布HarmonyOS 2及多款搭载HarmonyOS 2的新产品。鸿蒙系统是一款全新的面向全场景的分布式操作系统,鸿蒙系统一发布,网络上就
    的头像 发表于 07-05 17:12 1.2w次阅读

    华为开发者分论坛HarmonyOS学生公开课-学习鸿蒙更全面的开发

    2021华为开发者分论坛HarmonyOS学生公开课-学习鸿蒙更全面的开发
    的头像 发表于 10-24 10:37 1977次阅读
    华为<b class='flag-5'>开发</b>者分论坛<b class='flag-5'>HarmonyOS</b>学生公开课-学习<b class='flag-5'>鸿蒙</b>更全面的<b class='flag-5'>开发</b>

    淘宝与华为合作将基于HarmonyOS NEXT启动鸿蒙原生应用开发

    1月25日,淘宝与华为举办鸿蒙合作签约仪式,宣布将基于HarmonyOS NEXT启动鸿蒙原生应用开发
    的头像 发表于 01-26 16:14 1017次阅读

    华为宣布HarmonyOS NEXT鸿蒙星河版开发者预览面向开发者开放申请

    华为宣布HarmonyOS NEXT鸿蒙星河版开发者预览面向开发者开放申请,这意味着鸿蒙生态进入第二阶段,将加速千行百业的应用
    的头像 发表于 01-29 16:42 1339次阅读
    华为宣布<b class='flag-5'>HarmonyOS</b> NEXT<b class='flag-5'>鸿蒙</b>星河版<b class='flag-5'>开发</b>者预览面向<b class='flag-5'>开发</b>者开放申请

    庆科信息获HarmonyOS高级应用开发能力认证!助力品牌快速打造鸿蒙原生应用

    近日,上海庆科信息技术有限公司荣获HarmonyOS应用开发者高级认证,公司在华为鸿蒙生态的开发能力得到进一步拓展,能够帮助客户快速开发基于
    的头像 发表于 07-17 13:24 523次阅读
    庆科信息获<b class='flag-5'>HarmonyOS</b>高级应用<b class='flag-5'>开发</b>能力认证!助力品牌快速打造<b class='flag-5'>鸿蒙</b>原生应用