简单时钟
介绍
本示例通过使用[@ohos.display]接口以及canvas组件来实现一个简单的时钟应用。
效果预览
| 主页 | 
|---|
|  | 
使用说明
1.界面通过setinterval实现周期性实时刷新时间,使用canvas绘制时钟,指针旋转角度通过计算得出。
例如:"2 * math.pi / 60 * second"是秒针旋转的角度。
鸿蒙开发应用知识已更新gitee.com/li-shizhen-skin/harmony-os/blob/master/readme.md参考前往。
 

具体实现
鸿蒙学习文档前往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函数。
 
             我要评论
我要评论 
                                             
                                             
                                             
                                             
                                            
发表评论