已开启
钟表-集美大学-蔡昱钦-罗方芳 #417
钟表-集美大学-蔡昱钦-罗方芳 #417
已开启
caiyuqin创建于 6月30日
2 个文件变更+111-16
@@ -12,6 +12,8 @@ import std.time.*
12import std.sync.*12import std.sync.*
13import std.format.*13import std.format.*
14 14 
15+let timezoneList = [("本地", 0.0), ("东京", 1.0), ("伦敦", -8.0), ("纽约", -13.0)]
16+ 
15@Entry17@Entry
16@Component18@Component
17class EntryView {19class EntryView {
@@ -20,13 +22,23 @@ class EntryView {
20 var settings: RenderingContextSettings = RenderingContextSettings(antialias: true)22 var settings: RenderingContextSettings = RenderingContextSettings(antialias: true)
21 var context: CanvasRenderingContext2D = CanvasRenderingContext2D(this.settings)23 var context: CanvasRenderingContext2D = CanvasRenderingContext2D(this.settings)
22 var timer: ?Timer = None24 var timer: ?Timer = None
25+ @State var currentThemeIndex: Int64 = 0
26+ @State var currentTimezoneIndex: Int64 = 0
27+ var clock: ?Clock = None
23 28 
24 protected override func onPageShow() {29 protected override func onPageShow() {
25- let clock = Clock(context, width)30+ let c = Clock(context, width)
31+ c.theme = themes[currentThemeIndex]
32+ c.timezoneOffset = timezoneList[currentTimezoneIndex][1]
33+ c.timezoneLabel = timezoneList[currentTimezoneIndex][0]
34+ this.clock = c
26 this.timer = Timer.repeat(Duration.Zero, Duration.second, { =>35 this.timer = Timer.repeat(Duration.Zero, Duration.second, { =>
27 launch {36 launch {
28 context.clearRect(0.0, 0.0, width, height)37 context.clearRect(0.0, 0.0, width, height)
29- clock.draw(DateTime.now())38+ match (this.clock) {
39+ case let clk: Clock => clk.draw(DateTime.now())
40+ case _ => ()
41+ }
30 }42 }
31 }, style: CatchupStyle.Skip)43 }, style: CatchupStyle.Skip)
32 }44 }
@@ -44,9 +56,33 @@ class EntryView {
44 }56 }
45 }57 }
46 58 
59+ func switchTheme(): Unit {
60+ currentThemeIndex = (currentThemeIndex + 1) % themes.size
61+ match (this.clock) {
62+ case let c: Clock => c.theme = themes[currentThemeIndex]
63+ case _ => ()
64+ }
65+ }
66+ 
67+ func switchTimezone(): Unit {
68+ currentTimezoneIndex = (currentTimezoneIndex + 1) % timezoneList.size
69+ match (this.clock) {
70+ case let c: Clock =>
71+ c.timezoneOffset = timezoneList[currentTimezoneIndex][1]
72+ c.timezoneLabel = timezoneList[currentTimezoneIndex][0]
73+ case _ => ()
74+ }
75+ }
76+ 
47 func build() {77 func build() {
48 Column {78 Column {
49- Canvas(this.context).padding(top: 76).width(width).height(height)79+ Row {
80+ Text("[ 主题 ]").fontSize(14.px).fontColor(0x0055FF)
81+ .onClick({ => this.switchTheme() })
82+ Text("[ 时区 ]").fontSize(14.px).fontColor(0x0055FF)
83+ .onClick({ => this.switchTimezone() })
84+ }.width(100.percent).justifyContent(FlexAlign.SpaceEvenly).padding(top: 24)
85+ Canvas(this.context).padding(top: 10).width(width).height(height)
50 }.width(100.percent).height(100.percent)86 }.width(100.percent).height(100.percent)
51 }87 }
52}88}
@@ -8,17 +8,73 @@ import ohos.component.*
8import std.math.*8import std.math.*
9import std.time.DateTime9import std.time.DateTime
10 10 
11+public struct ThemeColors {
12+ var bgInner: UInt32
13+ var bgMid: UInt32
14+ var bgOuter: UInt32
15+ var frameColor: UInt32
16+ var numberColor: UInt32
17+ var majorTickColor: UInt32
18+ var minorTickColor: UInt32
19+ var hourHandColor: UInt32
20+ var minuteHandColor: UInt32
21+ var secondHandColor: UInt32
22+ var centerColor: UInt32
23+ var textColor: UInt32
24+}
25+ 
26+public let lightTheme = ThemeColors(
27+ bgInner: 0xFFFFFF, bgMid: 0xEEEEEE, bgOuter: 0xFFFFFF,
28+ frameColor: 0xFFFFFF, numberColor: 0x000000,
29+ majorTickColor: 0x000000, minorTickColor: 0xCCCCCC,
30+ hourHandColor: 0x000000, minuteHandColor: 0x000000,
31+ secondHandColor: 0x0055FF, centerColor: 0x0055FF,
32+ textColor: 0x000000
33+)
34+ 
35+public let darkTheme = ThemeColors(
36+ bgInner: 0x2D2D2D, bgMid: 0x1A1A1A, bgOuter: 0x2D2D2D,
37+ frameColor: 0x444444, numberColor: 0xFFFFFF,
38+ majorTickColor: 0xFFFFFF, minorTickColor: 0x666666,
39+ hourHandColor: 0xFFFFFF, minuteHandColor: 0xFFFFFF,
40+ secondHandColor: 0x00CCFF, centerColor: 0x00CCFF,
41+ textColor: 0xFFFFFF
42+)
43+ 
44+public let oceanTheme = ThemeColors(
45+ bgInner: 0x1A3A5C, bgMid: 0x0D2137, bgOuter: 0x1A3A5C,
46+ frameColor: 0x2A5A8C, numberColor: 0xFFFFFF,
47+ majorTickColor: 0x88CCFF, minorTickColor: 0x446688,
48+ hourHandColor: 0x88CCFF, minuteHandColor: 0x88CCFF,
49+ secondHandColor: 0xFF8844, centerColor: 0xFF8844,
50+ textColor: 0x88CCFF
51+)
52+ 
53+public let sunsetTheme = ThemeColors(
54+ bgInner: 0xFF6B35, bgMid: 0xCC4400, bgOuter: 0xFF6B35,
55+ frameColor: 0xFF8855, numberColor: 0xFFFFFF,
56+ majorTickColor: 0xFFDDAA, minorTickColor: 0x995522,
57+ hourHandColor: 0xFFDDAA, minuteHandColor: 0xFFDDAA,
58+ secondHandColor: 0xFFFF00, centerColor: 0xFFFF00,
59+ textColor: 0xFFDDAA
60+)
61+ 
62+public let themes = [lightTheme, darkTheme, oceanTheme, sunsetTheme]
63+ 
11public class Clock {64public class Clock {
12 var hour: Float64 = 0.065 var hour: Float64 = 0.0
13 var minute: Float64 = 0.066 var minute: Float64 = 0.0
14 var second: Float64 = 0.067 var second: Float64 = 0.0
15 let radius: Float6468 let radius: Float64
69+ public var theme: ThemeColors = lightTheme
70+ public var timezoneOffset: Float64 = 0.0
71+ public var timezoneLabel: String = "本地"
16 72 
17 public Clock(let context: CanvasRenderingContext2D,73 public Clock(let context: CanvasRenderingContext2D,
18 let width: Float64) { radius = width / 2.0 }74 let width: Float64) { radius = width / 2.0 }
19 75 
20 public func draw(time: DateTime) {76 public func draw(time: DateTime) {
21- hour = Float64(time.hour)77+ hour = (Float64(time.hour) + timezoneOffset + 24.0) % 24.0
22 minute = Float64(time.minute)78 minute = Float64(time.minute)
23 second = Float64(time.second)79 second = Float64(time.second)
24 80 
@@ -35,9 +91,9 @@ public class Clock {
35 // 绘制渐变背景91 // 绘制渐变背景
36 func background() {92 func background() {
37 let grad = context.createRadialGradient(radius, radius, radius - 32.0, radius, radius, radius)93 let grad = context.createRadialGradient(radius, radius, radius - 32.0, radius, radius, radius)
38- grad.addColorStop(0.0, Color.WHITE)94+ grad.addColorStop(0.0, theme.bgInner)
39- grad.addColorStop(0.9, 0xEEEEEE)95+ grad.addColorStop(0.9, theme.bgMid)
40- grad.addColorStop(1.0, Color.WHITE)96+ grad.addColorStop(1.0, theme.bgOuter)
41 context.fillStyle(grad)97 context.fillStyle(grad)
42 context.fillRect(0.0, 0.0, width, width)98 context.fillRect(0.0, 0.0, width, width)
43 }99 }
@@ -48,7 +104,7 @@ public class Clock {
48 // 边框104 // 边框
49 context.lineWidth(6.0)105 context.lineWidth(6.0)
50 context.beginPath()106 context.beginPath()
51- context.strokeStyle(0xffffff)107+ context.strokeStyle(theme.frameColor)
52 context.arc(0.0, 0.0, radius - 5.0, 0.0, 2.0 * Float64.PI, anticlockwise: false)108 context.arc(0.0, 0.0, radius - 5.0, 0.0, 2.0 * Float64.PI, anticlockwise: false)
53 context.stroke()109 context.stroke()
54 110 
@@ -56,7 +112,7 @@ public class Clock {
56 context.font(size: 40.px)112 context.font(size: 40.px)
57 context.textAlign(TextAlignStyle.Center)113 context.textAlign(TextAlignStyle.Center)
58 context.textBaseline(TextBaseline.Middle)114 context.textBaseline(TextBaseline.Middle)
59- context.fillStyle(0x000000)115+ context.fillStyle(theme.numberColor)
60 for (hour in 1..=12) {116 for (hour in 1..=12) {
61 let rad = 2.0 * Float64.PI / 12.0 * Float64(hour - 3)117 let rad = 2.0 * Float64.PI / 12.0 * Float64(hour - 3)
62 let x = cos(rad) * (radius - 38.0)118 let x = cos(rad) * (radius - 38.0)
@@ -74,13 +130,13 @@ public class Clock {
74 if (i % 5 == 0) {130 if (i % 5 == 0) {
75 let x = cos(rad) * (radius - 20.0)131 let x = cos(rad) * (radius - 20.0)
76 let y = sin(rad) * (radius - 20.0)132 let y = sin(rad) * (radius - 20.0)
77- context.strokeStyle(0x000000)133+ context.strokeStyle(theme.majorTickColor)
78 context.lineWidth(2.0)134 context.lineWidth(2.0)
79 context.lineTo(x, y)135 context.lineTo(x, y)
80 } else {136 } else {
81 let x = cos(rad) * (radius - 18.0)137 let x = cos(rad) * (radius - 18.0)
82 let y = sin(rad) * (radius - 18.0)138 let y = sin(rad) * (radius - 18.0)
83- context.strokeStyle(0xCCCCCC)139+ context.strokeStyle(theme.minorTickColor)
84 context.lineWidth(1.0)140 context.lineWidth(1.0)
85 context.lineTo(x, y)141 context.lineTo(x, y)
86 }142 }
@@ -94,9 +150,9 @@ public class Clock {
94 let hourAngle = 2.0 * Float64.PI / 12.0 * (hour + minute / 60.0)150 let hourAngle = 2.0 * Float64.PI / 12.0 * (hour + minute / 60.0)
95 let minuteAngle = 2.0 * Float64.PI / 60.0 * minute151 let minuteAngle = 2.0 * Float64.PI / 60.0 * minute
96 let secondAngle = 2.0 * Float64.PI / 60.0 * second152 let secondAngle = 2.0 * Float64.PI / 60.0 * second
97- for (params in [(8.0, hourAngle, 0u32, 0.5),153+ for (params in [(8.0, hourAngle, theme.hourHandColor, 0.5),
98- (5.0, minuteAngle, 0u32, 0.8),154+ (5.0, minuteAngle, theme.minuteHandColor, 0.8),
99- (2.0, secondAngle, 0x0055FFu32, 0.9)]) {155+ (2.0, secondAngle, theme.secondHandColor, 0.9)]) {
100 context.save()156 context.save()
101 context.beginPath()157 context.beginPath()
102 context.lineWidth(params[0])158 context.lineWidth(params[0])
@@ -114,7 +170,7 @@ public class Clock {
114 func center() {170 func center() {
115 context.save()171 context.save()
116 context.beginPath()172 context.beginPath()
117- context.fillStyle(0x0055ff)173+ context.fillStyle(theme.centerColor)
118 context.arc(0.0, 0.0, 4.0, 0.0, 2.0 * Float64.PI, anticlockwise: false)174 context.arc(0.0, 0.0, 4.0, 0.0, 2.0 * Float64.PI, anticlockwise: false)
119 context.fill()175 context.fill()
120 context.restore()176 context.restore()
@@ -127,8 +183,11 @@ public class Clock {
127 context.font(size: 90.px)183 context.font(size: 90.px)
128 context.textAlign(TextAlignStyle.Center)184 context.textAlign(TextAlignStyle.Center)
129 context.textBaseline(TextBaseline.Middle)185 context.textBaseline(TextBaseline.Middle)
130- context.fillStyle(0x000)186+ context.fillStyle(theme.textColor)
131 context.fillText(time, 0.0, radius + 80.0)187 context.fillText(time, 0.0, radius + 80.0)
188+ context.font(size: 28.px)
189+ context.fillStyle(theme.secondHandColor)
190+ context.fillText(timezoneLabel, 0.0, radius + 98.0)
132 context.restore()191 context.restore()
133 }192 }
134}193}