1e41f4b71Sopenharmony_ci# Development Guidelines on Clock Apps<a name="EN-US_TOPIC_0000001115417926"></a> 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ci## Overview<a name="section11522349121115"></a> 4e41f4b71Sopenharmony_ci 5e41f4b71Sopenharmony_ciThis document describes how to quickly set up a development environment \(using the Hi3516D V300 development board\) and develop a clock app running on OpenHarmony. You can click [here](https://gitee.com/openharmony/applications_app_samples/tree/master/code/Solutions/Tools/JsClock) to obtain the sample code. 6e41f4b71Sopenharmony_ci 7e41f4b71Sopenharmony_ciThe clock app displays the current time, as shown in the following figure. 8e41f4b71Sopenharmony_ci 9e41f4b71Sopenharmony_ci**Figure 1** Clock display effect<a name="fig7763172132019"></a> 10e41f4b71Sopenharmony_ci 11e41f4b71Sopenharmony_ci 12e41f4b71Sopenharmony_ci 13e41f4b71Sopenharmony_ci 14e41f4b71Sopenharmony_ci## Preparations<a name="section6592121861218"></a> 15e41f4b71Sopenharmony_ci 16e41f4b71Sopenharmony_ciDownload and install DevEco Studio. For details, see the [DevEco Studio User Guide](../../application-dev/quick-start/deveco-studio-user-guide-for-openharmony.md). 17e41f4b71Sopenharmony_ci 18e41f4b71Sopenharmony_ci## How to Develop<a name="section19901741111312"></a> 19e41f4b71Sopenharmony_ci 20e41f4b71Sopenharmony_ciThe clock app displays the current time through a clock face and numbers. 21e41f4b71Sopenharmony_ci 22e41f4b71Sopenharmony_ciAs shown in [Figure 1](#fig7763172132019), the UI consists of two parts: 23e41f4b71Sopenharmony_ci 24e41f4b71Sopenharmony_ci- Clock face area: displays a dynamic analog clock whose hands rotate accurately. 25e41f4b71Sopenharmony_ci- Digital time area: displays the current time in numerals. 26e41f4b71Sopenharmony_ci 27e41f4b71Sopenharmony_ciTo build such an app, we can create a page that has a flexible layout with two rows vertically arranged. The development procedure is as follows: 28e41f4b71Sopenharmony_ci 29e41f4b71Sopenharmony_ci1. Add a root component **<div\>** to the **.hml** file. Note that each **.hml** file can contain only one root component. The sample code is as follows: 30e41f4b71Sopenharmony_ci 31e41f4b71Sopenharmony_ci ``` 32e41f4b71Sopenharmony_ci <div class="container"> 33e41f4b71Sopenharmony_ci </div> 34e41f4b71Sopenharmony_ci ``` 35e41f4b71Sopenharmony_ci 36e41f4b71Sopenharmony_ci **class="container"** indicates the style used by the component. The **container** is a style class defined in the **index.css** file. 37e41f4b71Sopenharmony_ci 38e41f4b71Sopenharmony_ci ``` 39e41f4b71Sopenharmony_ci .container { 40e41f4b71Sopenharmony_ci flex-direction: column; 41e41f4b71Sopenharmony_ci justify-content: center; 42e41f4b71Sopenharmony_ci align-items: center; 43e41f4b71Sopenharmony_ci width: 100%; 44e41f4b71Sopenharmony_ci height: 100%; 45e41f4b71Sopenharmony_ci } 46e41f4b71Sopenharmony_ci ``` 47e41f4b71Sopenharmony_ci 48e41f4b71Sopenharmony_ci The height and width of the root component **<div\>** are set in the style class. Note that the height and width must be explicitly specified \(except for some components, such as **<text\>**\). Otherwise, the component may fail to display. In the **container** style class, the **flex-direction** attribute is set to **column**, which means that child components of **<div\>** are vertically arranged from top to bottom for implementing the flexible page layout. 49e41f4b71Sopenharmony_ci 50e41f4b71Sopenharmony_ci2. Implement clock hand rotation using the **<stack\>** component. The **<stack\>** component provides a stack container where child components are successively stacked and the latter one overwrites the previous one. 51e41f4b71Sopenharmony_ci 52e41f4b71Sopenharmony_ci Add a stack container to the root component. The sample code is as follows: 53e41f4b71Sopenharmony_ci 54e41f4b71Sopenharmony_ci ``` 55e41f4b71Sopenharmony_ci <div class="container"> 56e41f4b71Sopenharmony_ci <stack class="stack"> 57e41f4b71Sopenharmony_ci <image src="/common/clock_bg.png" class="clock-bg"></image> <!--Set the clock face image.--> 58e41f4b71Sopenharmony_ci <image src="/common/hour_hand.png" class="clock-hand" 59e41f4b71Sopenharmony_ci style="transform : rotate({{ hour * 30 + minute / 2 }}deg);"></image> <!--Set the hour hand image. (hour * 30) indicates that the hour hand rotates 30 degrees every hour. (minute / 2) indicates the rotation degrees per minute.--> 60e41f4b71Sopenharmony_ci <image src="/common/minute_hand.png" class="clock-hand" 61e41f4b71Sopenharmony_ci style="transform : rotate({{ minute * 6 + second / 10 }}deg);"></image> <!--Set the minute hand image. (minute * 6) indicates that the minute hand rotates 6 degrees every minute. (second / 10) indicates the rotation degrees per second.--> 62e41f4b71Sopenharmony_ci <image src="/common/second_hand.png" class="clock-hand" 63e41f4b71Sopenharmony_ci style="transform : rotate({{ second * 6 }}deg);"></image> <!--Set the second hand image. (second * 6) indicates that the second hand rotates 6 degrees per second.--> 64e41f4b71Sopenharmony_ci </stack> 65e41f4b71Sopenharmony_ci </div> 66e41f4b71Sopenharmony_ci ``` 67e41f4b71Sopenharmony_ci 68e41f4b71Sopenharmony_ci **style="transform: rotate\(\{\{ second \* 6 \}\}deg\)** sets the rotation event of a component. **transform** translates, rotates, or scales an image. **rotate** rotates an image. You can set an image to rotate around its x-axis or y-axis. 69e41f4b71Sopenharmony_ci 70e41f4b71Sopenharmony_ci Set attributes, such as the height, width, and position, of the stack component in the CSS file. The sample code is as follows: 71e41f4b71Sopenharmony_ci 72e41f4b71Sopenharmony_ci ``` 73e41f4b71Sopenharmony_ci .stack { 74e41f4b71Sopenharmony_ci flex-direction: column; 75e41f4b71Sopenharmony_ci justify-content: center; 76e41f4b71Sopenharmony_ci align-items: center; 77e41f4b71Sopenharmony_ci width: 100%; 78e41f4b71Sopenharmony_ci height: 50%; 79e41f4b71Sopenharmony_ci } 80e41f4b71Sopenharmony_ci ``` 81e41f4b71Sopenharmony_ci 82e41f4b71Sopenharmony_ci Set attributes, such as the height and width, of the clock-bg component in the CSS file. The sample code is as follows: 83e41f4b71Sopenharmony_ci 84e41f4b71Sopenharmony_ci ``` 85e41f4b71Sopenharmony_ci .clock-bg { 86e41f4b71Sopenharmony_ci width: 80%; 87e41f4b71Sopenharmony_ci height: 80%; 88e41f4b71Sopenharmony_ci object-fit: scale-down; 89e41f4b71Sopenharmony_ci } 90e41f4b71Sopenharmony_ci ``` 91e41f4b71Sopenharmony_ci 92e41f4b71Sopenharmony_ci Set attributes, such as the height and width of the hour, minute, and second hands, of the clock-hand component in the CSS file. The sample code is as follows: 93e41f4b71Sopenharmony_ci 94e41f4b71Sopenharmony_ci ``` 95e41f4b71Sopenharmony_ci .clock-hand { 96e41f4b71Sopenharmony_ci width: 25%; 97e41f4b71Sopenharmony_ci height: 65%; 98e41f4b71Sopenharmony_ci object-fit: contain; 99e41f4b71Sopenharmony_ci } 100e41f4b71Sopenharmony_ci ``` 101e41f4b71Sopenharmony_ci 102e41f4b71Sopenharmony_ci Add a timer in the **index.js** file to update the hour, minute, and second variables in real time so that the time can be automatically updated on the app UI. The sample code is as follows: 103e41f4b71Sopenharmony_ci 104e41f4b71Sopenharmony_ci ``` 105e41f4b71Sopenharmony_ci export default { 106e41f4b71Sopenharmony_ci timer: undefined, 107e41f4b71Sopenharmony_ci // Define parameters. 108e41f4b71Sopenharmony_ci data: { 109e41f4b71Sopenharmony_ci hour: 0, // Define hours. 110e41f4b71Sopenharmony_ci minute: 0, // Define minutes. 111e41f4b71Sopenharmony_ci second: 0 // Define seconds. 112e41f4b71Sopenharmony_ci }, 113e41f4b71Sopenharmony_ci onInit () { 114e41f4b71Sopenharmony_ci this.updateTime(); 115e41f4b71Sopenharmony_ci this.timer = setInterval(this.updateTime, 1000)// Set the timer to 1 second. 116e41f4b71Sopenharmony_ci }, 117e41f4b71Sopenharmony_ci updateTime: function () { 118e41f4b71Sopenharmony_ci var nowTime = new Date() 119e41f4b71Sopenharmony_ci this.hour = nowTime.getHours() 120e41f4b71Sopenharmony_ci this.minute = nowTime.getMinutes() 121e41f4b71Sopenharmony_ci this.second = nowTime.getSeconds() 122e41f4b71Sopenharmony_ci if (this.hour < 10) { 123e41f4b71Sopenharmony_ci this.hour = '0' + this.hour 124e41f4b71Sopenharmony_ci } 125e41f4b71Sopenharmony_ci if (this.minute < 10) { 126e41f4b71Sopenharmony_ci this.minute = '0' + this.minute 127e41f4b71Sopenharmony_ci } 128e41f4b71Sopenharmony_ci if (this.second < 10) { 129e41f4b71Sopenharmony_ci this.second = '0' + this.second 130e41f4b71Sopenharmony_ci } 131e41f4b71Sopenharmony_ci }, 132e41f4b71Sopenharmony_ci } 133e41f4b71Sopenharmony_ci ``` 134e41f4b71Sopenharmony_ci 135e41f4b71Sopenharmony_ci3. Display the current time in numerals under the analog clock. Add the text component at the end of the root layout. The following example shows the UI structure: 136e41f4b71Sopenharmony_ci 137e41f4b71Sopenharmony_ci ``` 138e41f4b71Sopenharmony_ci <text class="digit-clock"> {{ hour }}:{{ minute }}:{{ second }}</text> 139e41f4b71Sopenharmony_ci ``` 140e41f4b71Sopenharmony_ci 141e41f4b71Sopenharmony_ci class=**"digit-clock"** sets the height, width, and font size of the component. The sample code is as follows: 142e41f4b71Sopenharmony_ci 143e41f4b71Sopenharmony_ci ``` 144e41f4b71Sopenharmony_ci .digit-clock { 145e41f4b71Sopenharmony_ci font-size: 58px; 146e41f4b71Sopenharmony_ci width: 100%; 147e41f4b71Sopenharmony_ci margin-top: 0px; 148e41f4b71Sopenharmony_ci text-align: center; 149e41f4b71Sopenharmony_ci } 150e41f4b71Sopenharmony_ci ``` 151e41f4b71Sopenharmony_ci 152e41f4b71Sopenharmony_ci4. Set the style, animation effect, and dynamic data binding for all components. The complete sample code is as follows: 153e41f4b71Sopenharmony_ci - **index.hml** 154e41f4b71Sopenharmony_ci 155e41f4b71Sopenharmony_ci ``` 156e41f4b71Sopenharmony_ci <div class="container"> 157e41f4b71Sopenharmony_ci <stack class="stack"> 158e41f4b71Sopenharmony_ci <image src="/common/clock_bg.png" class="clock-bg"></image> 159e41f4b71Sopenharmony_ci <image src="/common/hour_hand.png" class="clock-hand" 160e41f4b71Sopenharmony_ci style="transform : rotate({{ hour * 30 + minute / 2 }}deg);"></image> 161e41f4b71Sopenharmony_ci <image src="/common/minute_hand.png" class="clock-hand" 162e41f4b71Sopenharmony_ci style="transform : rotate({{ minute * 6 + second / 10 }}deg);"></image> 163e41f4b71Sopenharmony_ci <image src="/common/second_hand.png" class="clock-hand" 164e41f4b71Sopenharmony_ci style="transform : rotate({{ second * 6 }}deg);"></image> 165e41f4b71Sopenharmony_ci </stack> 166e41f4b71Sopenharmony_ci <text class="digit-clock">{{ hour }}:{{ minute }}:{{ second }}</text> 167e41f4b71Sopenharmony_ci </div> 168e41f4b71Sopenharmony_ci ``` 169e41f4b71Sopenharmony_ci 170e41f4b71Sopenharmony_ci - **index.css** 171e41f4b71Sopenharmony_ci 172e41f4b71Sopenharmony_ci ``` 173e41f4b71Sopenharmony_ci .container { 174e41f4b71Sopenharmony_ci flex-direction: column; 175e41f4b71Sopenharmony_ci justify-content: center; 176e41f4b71Sopenharmony_ci align-items: center; 177e41f4b71Sopenharmony_ci width: 100%; 178e41f4b71Sopenharmony_ci height: 100%; 179e41f4b71Sopenharmony_ci } 180e41f4b71Sopenharmony_ci 181e41f4b71Sopenharmony_ci .stack { 182e41f4b71Sopenharmony_ci flex-direction: column; 183e41f4b71Sopenharmony_ci justify-content: center; 184e41f4b71Sopenharmony_ci align-items: center; 185e41f4b71Sopenharmony_ci width: 100%; 186e41f4b71Sopenharmony_ci height: 50%; 187e41f4b71Sopenharmony_ci } 188e41f4b71Sopenharmony_ci 189e41f4b71Sopenharmony_ci .digit-clock { 190e41f4b71Sopenharmony_ci font-size: 58px; 191e41f4b71Sopenharmony_ci width: 100%; 192e41f4b71Sopenharmony_ci margin-top: 0px; 193e41f4b71Sopenharmony_ci text-align: center; 194e41f4b71Sopenharmony_ci } 195e41f4b71Sopenharmony_ci 196e41f4b71Sopenharmony_ci .clock-bg { 197e41f4b71Sopenharmony_ci width: 80%; 198e41f4b71Sopenharmony_ci height: 80%; 199e41f4b71Sopenharmony_ci object-fit: scale-down; 200e41f4b71Sopenharmony_ci } 201e41f4b71Sopenharmony_ci 202e41f4b71Sopenharmony_ci .clock-hand { 203e41f4b71Sopenharmony_ci width: 25%; 204e41f4b71Sopenharmony_ci height: 65%; 205e41f4b71Sopenharmony_ci object-fit: contain; 206e41f4b71Sopenharmony_ci } 207e41f4b71Sopenharmony_ci ``` 208e41f4b71Sopenharmony_ci 209e41f4b71Sopenharmony_ci - **index.js** 210e41f4b71Sopenharmony_ci 211e41f4b71Sopenharmony_ci A **.js** file is used to implement logic interactions of the clock app. The following **.js** file implements the function of periodically obtaining the system time. 212e41f4b71Sopenharmony_ci 213e41f4b71Sopenharmony_ci ``` 214e41f4b71Sopenharmony_ci export default { 215e41f4b71Sopenharmony_ci timer: undefined, 216e41f4b71Sopenharmony_ci data: { 217e41f4b71Sopenharmony_ci hour: 0, 218e41f4b71Sopenharmony_ci minute: 0, 219e41f4b71Sopenharmony_ci second: 0 220e41f4b71Sopenharmony_ci }, 221e41f4b71Sopenharmony_ci onInit() { 222e41f4b71Sopenharmony_ci this.updateTime() 223e41f4b71Sopenharmony_ci this.timer = setInterval(this.updateTime, 1000) 224e41f4b71Sopenharmony_ci }, 225e41f4b71Sopenharmony_ci updateTime: function () { 226e41f4b71Sopenharmony_ci var nowTime = new Date() 227e41f4b71Sopenharmony_ci this.hour = nowTime.getHours() 228e41f4b71Sopenharmony_ci this.minute = nowTime.getMinutes() 229e41f4b71Sopenharmony_ci this.second = nowTime.getSeconds() 230e41f4b71Sopenharmony_ci if (this.hour < 10) { 231e41f4b71Sopenharmony_ci this.hour = '0' + this.hour 232e41f4b71Sopenharmony_ci } 233e41f4b71Sopenharmony_ci if (this.minute < 10) { 234e41f4b71Sopenharmony_ci this.minute = '0' + this.minute 235e41f4b71Sopenharmony_ci } 236e41f4b71Sopenharmony_ci if (this.second < 10) { 237e41f4b71Sopenharmony_ci this.second = '0' + this.second 238e41f4b71Sopenharmony_ci } 239e41f4b71Sopenharmony_ci }, 240e41f4b71Sopenharmony_ci onDestroy() { 241e41f4b71Sopenharmony_ci clearInterval(this.timer); 242e41f4b71Sopenharmony_ci } 243e41f4b71Sopenharmony_ci } 244e41f4b71Sopenharmony_ci ``` 245e41f4b71Sopenharmony_ci 246e41f4b71Sopenharmony_ci 247e41f4b71Sopenharmony_ci 248e41f4b71Sopenharmony_ci## Signing and Packaging<a name="section10601181101516"></a> 249e41f4b71Sopenharmony_ci 250e41f4b71Sopenharmony_ciAfter finishing writing the app code, you need to sign and package the app before running it on a real device. For details, see [Signing and Packaging Guide](https://developer.harmonyos.com/en/docs/documentation/doc-guides/ohos-debugging-and-running-0000001263040487#section17660437768). 251e41f4b71Sopenharmony_ci 252e41f4b71Sopenharmony_ci## Running on the Real Device<a name="section092721731511"></a> 253e41f4b71Sopenharmony_ci 254e41f4b71Sopenharmony_ciBefore you install the app and run it on the development board, install the DevEco Device Tool by following operations provided in [DevEco Device Tool User Guide](https://device.harmonyos.com/en/docs/ide/user-guides/service_introduction-0000001050166905). Burn OpenHarmony into the development board and run it. For details about how to build, burn, and run an image, see [Getting Started with the Standard System with Hi3516 (IDE Mode)](../quick-start/quickstart-appendix-hi3516-ide.md). After the image is running normally and the system is started properly, perform the following steps to install or uninstall the app: 255e41f4b71Sopenharmony_ci 256e41f4b71Sopenharmony_ci1. Obtain the HDC client from the following path: 257e41f4b71Sopenharmony_ci 258e41f4b71Sopenharmony_ci ``` 259e41f4b71Sopenharmony_ci developtools/hdc_standard/prebuilt/windows/hdc_std.exe 260e41f4b71Sopenharmony_ci ``` 261e41f4b71Sopenharmony_ci 262e41f4b71Sopenharmony_ci Change the HDC client name to **hdc.exe** and add the path above to the system environment variable **path**. 263e41f4b71Sopenharmony_ci 264e41f4b71Sopenharmony_ci2. Open the **cmd** window, and run the following commands to push the HAP file to the device directory, and install it: 265e41f4b71Sopenharmony_ci 266e41f4b71Sopenharmony_ci ``` 267e41f4b71Sopenharmony_ci hdc install clock.hap 268e41f4b71Sopenharmony_ci ``` 269e41f4b71Sopenharmony_ci 270e41f4b71Sopenharmony_ci3. Run the following command to start the app. **ohos.samples.clock** indicates the app package name, and **MainAbility** indicates the ability started by the app. 271e41f4b71Sopenharmony_ci 272e41f4b71Sopenharmony_ci ``` 273e41f4b71Sopenharmony_ci hdc shell aa start -d 123 -a ohos.samples.clock.MainAbility -b ohos.samples.clock 274e41f4b71Sopenharmony_ci ``` 275e41f4b71Sopenharmony_ci 276e41f4b71Sopenharmony_ci4. \(Optional\) Run the following command to uninstall the app. **ohos.samples.clock** indicates the app package name. 277e41f4b71Sopenharmony_ci 278e41f4b71Sopenharmony_ci ``` 279e41f4b71Sopenharmony_ci hdc shell bm uninstall -n ohos.samples.clock 280e41f4b71Sopenharmony_ci ``` 281e41f4b71Sopenharmony_ci 282e41f4b71Sopenharmony_ci 283e41f4b71Sopenharmony_ci## FAQs<a name="section1122413460153"></a> 284e41f4b71Sopenharmony_ci 285e41f4b71Sopenharmony_ci### hdc\_std Fails to Connect to a Device<a name="section1922725151614"></a> 286e41f4b71Sopenharmony_ci 287e41f4b71Sopenharmony_ci- **Symptom** 288e41f4b71Sopenharmony_ci 289e41f4b71Sopenharmony_ci **\[Empty\]** is displayed in the output after the **hdc\_std list targets** command is run. 290e41f4b71Sopenharmony_ci 291e41f4b71Sopenharmony_ci- **Possible Causes and Solutions** 292e41f4b71Sopenharmony_ci - The device fails to be identified. 293e41f4b71Sopenharmony_ci 294e41f4b71Sopenharmony_ci Check whether **HDC Device** exists in the universal serial bus device of the device manager. If **HDC Device** does not exist, the device cannot be connected. In this case, remove and then insert the device or burn the latest image for the device. 295e41f4b71Sopenharmony_ci 296e41f4b71Sopenharmony_ci - hdc\_std works improperly. 297e41f4b71Sopenharmony_ci 298e41f4b71Sopenharmony_ci Run the **hdc kill** or **hdc start -r** command to kill or restart the HDC service, and then run the **hdc list targets** command to check whether device information is obtained. 299e41f4b71Sopenharmony_ci 300e41f4b71Sopenharmony_ci - hdc\_std does not match the device. 301e41f4b71Sopenharmony_ci 302e41f4b71Sopenharmony_ci If the latest image is burnt for the device, hdc\_std must also be of the latest version. As hdc\_std is updated continuously, obtain hdc\_std of the latest version from the **developtools\_hdc\_standard** repository in the **prebuilt** directory. 303e41f4b71Sopenharmony_ci 304e41f4b71Sopenharmony_ci 305e41f4b71Sopenharmony_ci 306e41f4b71Sopenharmony_ci### hdc\_std Fails to Run<a name="section15657547131615"></a> 307e41f4b71Sopenharmony_ci 308e41f4b71Sopenharmony_ci- **Symptom** 309e41f4b71Sopenharmony_ci 310e41f4b71Sopenharmony_ci The **hdc\_std.exe** file does not run after being clicked. 311e41f4b71Sopenharmony_ci 312e41f4b71Sopenharmony_ci- **Possible Causes and Solutions** 313e41f4b71Sopenharmony_ci 314e41f4b71Sopenharmony_ci **hdc\_std.exe** requires no installation and can be directly used on a disk. It can also be added to environment variables. Open the **cmd** window and run the **hdc\_std** command to use **hdc\_std.exe**.