├── .browserslistrc
├── .editorconfig
├── .eslintrc.js
├── .gitignore
├── README.md
├── babel.config.js
├── package-lock.json
├── package.json
├── public
├── favicon.ico
└── index.html
├── src
├── App.vue
├── assets
│ ├── base.less
│ ├── images.less
│ └── logo.png
├── components
│ ├── clock.vue
│ ├── setbox.vue
│ ├── slider.vue
│ └── timePicker.vue
├── main.js
└── utils
│ ├── easeinout.js
│ └── getnum.js
└── vue.config.js
/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 1%
2 | last 2 versions
3 | not dead
4 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | [*.{js,jsx,ts,tsx,vue}]
2 | indent_style = space
3 | indent_size = 2
4 | trim_trailing_whitespace = true
5 | insert_final_newline = true
6 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: {
4 | node: true
5 | },
6 | extends: [
7 | 'plugin:vue/vue3-essential',
8 | '@vue/standard'
9 | ],
10 | parserOptions: {
11 | parser: 'babel-eslint'
12 | },
13 | rules: {
14 | 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
15 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | # local env files
6 | .env.local
7 | .env.*.local
8 |
9 | # Log files
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 | pnpm-debug.log*
14 |
15 | # Editor directories and files
16 | .idea
17 | .vscode
18 | *.suo
19 | *.ntvs*
20 | *.njsproj
21 | *.sln
22 | *.sw?
23 | node_modules
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # timer
2 |
3 | flip clock
4 |
5 | 翻页时钟
6 |
7 | ## demo
8 |
9 | [clock](https://lufunc.github.io/timer/)
10 |
11 | ## Project setup
12 | ```
13 | npm install
14 | ```
15 |
16 | ### Compiles and hot-reloads for development
17 | ```
18 | npm run serve
19 | ```
20 |
21 | ### Compiles and minifies for production
22 | ```
23 | npm run build
24 | ```
25 |
26 | ### Lints and fixes files
27 | ```
28 | npm run lint
29 | ```
30 |
31 | ### Customize configuration
32 | See [Configuration Reference](https://cli.vuejs.org/config/).
33 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "timer",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "core-js": "^3.6.5",
12 | "vue": "^3.0.0"
13 | },
14 | "devDependencies": {
15 | "@vue/cli-plugin-babel": "~4.5.0",
16 | "@vue/cli-plugin-eslint": "~4.5.0",
17 | "@vue/cli-service": "~4.5.0",
18 | "@vue/compiler-sfc": "^3.0.0",
19 | "@vue/eslint-config-standard": "^5.1.2",
20 | "babel-eslint": "^10.1.0",
21 | "eslint": "^6.7.2",
22 | "eslint-plugin-import": "^2.20.2",
23 | "eslint-plugin-node": "^11.1.0",
24 | "eslint-plugin-promise": "^4.2.1",
25 | "eslint-plugin-standard": "^4.0.0",
26 | "eslint-plugin-vue": "^7.0.0-0",
27 | "less": "^3.0.4",
28 | "less-loader": "^5.0.0",
29 | "lint-staged": "^9.5.0"
30 | },
31 | "gitHooks": {
32 | "pre-commit": "lint-staged"
33 | },
34 | "lint-staged": {
35 | "*.{js,jsx,vue}": [
36 | "vue-cli-service lint",
37 | "git add"
38 | ]
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lufunc/timer/73dfbb72268ce741cdd0b2438970bbe594954a93/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Clock
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
{{watching?'Stop':'Start'}}
9 |
click or space
10 |
11 |
12 |
13 |
76 |
80 |
81 |
82 |
83 |
84 |
257 |
258 |
401 |
--------------------------------------------------------------------------------
/src/assets/base.less:
--------------------------------------------------------------------------------
1 | body{
2 | margin: 0;
3 | }
4 | ul{
5 | margin: 0;
6 | padding: 0;
7 | list-style: none;
8 | }
9 | button { border:none; padding:0;margin:0;outline-style:none; }
10 |
--------------------------------------------------------------------------------
/src/assets/images.less:
--------------------------------------------------------------------------------
1 | @set_pic : 'data:image/png;base64,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';
2 |
3 | @tomato: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEnElEQVRYR71XbUybVRR+zi2F0Q/o2IBiyYBg1B+6j8QfOpeJoZhFVuzix0wwDHRZYoiBGRJN/CExxj+aAFGXbJoMfmhEMy3r5hLBrBgCxAwzNkeo24BNwY0NKG35avu+17yFt+v315zvz/c85znPOffcc+8lJPlpTzXXu15q74wH13z3dj5TsM+cmStvwHRiORlqSgYkYbTdjdOeyxN71z46dz2aj/aHpj0EnOLOpSlX169TOP/nwWS4kxaQ823jrGfs7/HVD3v28gqzblUp7JADvPl84XNnytXvE5Dh7h6EcMv5Kvrt3/9nAqSABYcfurnscGkvWu4uFpEyVyY/Xa5GozEfIiN4xv5C2S9Xb/3Gyt5TC6yHbBZHIhFxKyAFXs4Qm0SgefvrBt2cVommk5fw7loOODiO7dTh46fz/DH4mhfOThsGhWJsp03gHA4GtKt8rCOekJgC3FWmes6pjQg6KcATtQbM52SiYOA6bOMKHNlXgIFiVSDB1UE7XhuZwxcZRSFJS0KI+FFNrzVqA0cIkLJeUgptANUHM8kCpEz1HuC2VhkwS//Er/pxmUqQTxkxqs47Nb3WhnBjhABXlclGoGfDgbKAaOzc44PJasfx2XsViYrj3KLtsx4ItoUIcFfVSGU6FO68kMXwZK0Bq1mxsgO4IKJl4A7eGUu0/UMrERDgMta0EuGD8OBLSsIBcxGubM1K1NB++zOTLnwyuIASpxAbz/lRTZ+1XQL4BUjr7s4QJ+WGkz2XM4C6F/QYMmSHrDdl3Vv/aFFI5Kj7w4n6Ky484vBGQKTG1PhYmbQ7/AKilX5RSairLsSFovXg3CvAa5/G6vA15LzyFJCrAhc5lq0j8M0sAL7QjHWc4S2FDi1sC7LAouns0vSerqf1rhcXghF3sxlertHjqi4Tvuk5eOz/wHvtNrZ5gQ6mx/FKA4Ye2+zf+xVfDuNzpkdezO6PvhKBKkj7HaCTMsxarkL3oxpM37yDC/YJGFZE1JAW1UyNPaSCAoRPd2jRtnsrhHk3Wr4ZR4tiS1L9EQniDeQymixE9KJsdHAB7eI8ssFQTWo8zjZF+J0rU+HwvkJ4p2bRdnYGtSwwmVMSwjnvoVj7Ph7TeJ4SlQeLsTYygdPDK9jN4u//WFwcvJ9cxhoHEVJKYUVBePhIKZbO/o7JG1psTnH9ZUH+Me2uquEp1W0DXH7IAPXXQ7jk25aOe8CH3EbTFIhKUmWprsxFyc92HFPoU3UNwvPRtHpAYjih51DPONNuQP9skXog1vxPlNYE90AFgp7iT8UEPB20VGkyc0Y/Jgr4YOy+XeujOM0+uC9RnN/Q9FlLZQHNIGq7L8JUnTdOxMBx/P9WgY9qeq07Jc1B94H9FUTsfKqJpIf37dL0/nQxRIC/F8IOpvTIE3nxhuALasSd8MGKCA0eUQFZu8u4vwJgllTPiJiHDsciIJq1fWds4ZiY74KVCnOpoBRbo11SExU5zN6l9rLmWI+ThG/D9WpQc/CdIUkBXQova822Wabi4RMKkJ39zzSFUMEZmTm4NEB0AG08UPkoBxwEmiKRW1SCwpbMu1Di/hfd0smNt8fdPgAAAABJRU5ErkJggg==';
4 |
5 | @timer: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAADTUlEQVRYR8XXR6glVRAG4G/MoCCKKAZMiIJpM+a4EhMqKujCjaPO4AyDCRUDoohgQlTMgmEnKAbEuBJMiIoLc8KAAbOCCbP8j7rSr+d2376+B692955z6vynqv6/qhdZYFu0wPebK4DbsAW+wCd4BC9P86i5AFgLv4257DVcj7vx1yQwcwGwHn7En/gKm7Uuexdn4PE+EPMB4FtshC1xOE7Cbo1Lby0g46LVWQOrYz+80BHm+B9FYASg+dADcRN2qj9fwr74ox2NrghciXNxPq7oCGEfgBzJI67GmXX+Bpw2BMBeeJ6Z6CxHQjjO1sVP+Bob9+T5QlxW60nRY8297QgE9dvYDs9hf/yDTSqvj7YuSqV/hEt6AOSOp5C0vI8dm6loA1iGcPt3bFX8ju99CtB9OBXfTaJXa30bvFdpSUquG623AXyIrXELVrSc5NDp+AYn4+EpQaQo4zM6ses4ANvjnVrYfYyiRXhexQ61555y+MNAIGHVM7U3EUnqZtEwBXcz4nDDyn3b9y4FLGBiX2LJJLGpvWvg+6Jv0phUzwJwOc4rlAf0vOosXNNav7NqYxWet/a9iET3UlzcBnAXTkQK7biBVd3cFu3IA/rsIRyFO3BKG0D+jIzei+MnONoUb2CDxr6ni2p9R+/HMV0AIhYRjSGOcskReLCold9Ruahdnz1bkpy7Luoqwo+LikOKe08chA8QVkS0uiyUTxGuX+wJ1WcVYfgfHYil2l8fgmCKPXuXxOdI1PCtNoD8jkjsjCEFNcXdM1tvx1J8js1Hh9tKmDxmmvm5pDitdj5sW2RASa8Jhc/uArBmaXb6QKRz5TzcnkemAx5SE1R8pxZmbNw8cDCeqPVj8cAcQVyFc8pHROzapr+ugSRpSDp+wQmIgExr8R26XVAHMzEf2WZKF4BofRrHHnU4Q0l4m044xFJk0YSja/MrNeL92j7cN5SuU+FK44glGjfWuD1DoZaF35kbDkXmirVr/clSv5xfxYZMxYcVkLTrkUUj3sRn1d0yxmUAXa2xJ0NN8p0U/N0VtiEAcjb0SaPKQBKR6rNQOIUbWc/XUq8NBdB0srg6Wj5E8lmWr598mn1aY1vmv0lt+T9//wfApEdNtb7gAP4FyRimIUFX3cMAAAAASUVORK5CYII=';
6 |
7 | @cancel: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEZklEQVRYR8VXW29UVRT+vjOd6YVyDUhSGjNtz21SfVBelCiYELWiQYJoTKg+4A+g+GoilBfji2B8FRMlJF5QkCgCMSY0pg9GfZFmztlzOh1IaSQQikC5zHT2MmecqdPpTGdKCezHc9blW5f9rbWJh3z4kP2jYQCmaTaT0Y2k9AnxNARrAawDmafIJRATEPwmwp9iMePsyMhItpHgGgJgOs4bFH5C8pFGjAL4W0PvDnz/63ry8wLo6upaG422fAZiS9HQVQiOAfgOyKcnJ6Pjq1ZNMwt0NGlaJLeB2A5gZUFecDKXu7NrbGzsUi0gNQGYpvuCYeAIyNUCXIDWH6RS/iEAufmi6u3tjWWz07tAvkeyEyJXtMbOIPDOVNOrCiB0TgOnSBKC77PZ229mMpk79dJZ/j8ej7dEYy1HSG4XEdGULaO+f6rSxhwAtm2vE0TOkVghwMcpPzmwEMeVspaVOEADAyK4RuQfU0pdLJeZA8CyE0MknhWRH1LK21qo5OIOLcc9TnCrCIZSKrmpJgDLcl+jwaMicnHq5nV7YmLiVkVaV2QymWvz4YnH43NkOjo62pa0L1Mk14mWHamU923JxqwMWLY7SrJbC94OVPJwuSPLcvaD3Dmdu7uhVlf/Vz5jSIDPA+XtL9c37cRbBvGFiKRTyuuZA6Cnx10faeLvgGSU73WVKxcj+CsEFxog9MbKWhacMzJM4FERjN6+dePx8fHx2+V2bNtNg+zSeawPguSf4b+ZDNi2uw/kXtE4mEol91SmOeSEpmjzcAEEcIGS31ACUe4cED+XvbupWpZKDQmRQaW8fRUAEj+D2Kzz0hcE3ulqda4GosA3xchD5xD9jFLqSjX9ArdEeBoivyjlbZ4NwHF9gPZ0Tpx02lO1Gq3AjrHmswAdAOcFYJj2es5De93drt0UpQ+IUr4X6v9fAstJTBFo0/nc8iAIrs/X6bZtrwaNX4sgIIIRIv9crchLtkzTXGZEov8AmFJ+sr0yA9cBLp28aiy9fHnk5kIANBJ9aG/Nmt72lav0DUBuKN9bVgnACyOqV4KK6M8jjB+MNwKirAS+8j23VhO+WGtwlNe/dBMW0oSWlXieBs5UbULTdt83yEGIHFDKe3cx17DWTbBt9yOQe7TI3hJRzfCAaSaeNCL4oxoRdXZ2tra2tZ9rlIjCctyauvnEgogojNiyEwGJHg3dH/j+kQoWGxSgvy4VMzIsIofmULHj9BswDtek4tCZaTo7jIjxzWKGUXd39/J0Oh1etZkTZrBtSXsAsEPn9etB4B+tOoyKWThLYqNATqR8b9t9Gce2e4LkK3XHcQjgvi8kTuIggd0NLyQhiB7H6TOEJxe7ksVirV+CeDVcyUQjnDFz9sKGltKQ8zX0h4Hvf/pAltJSgxSn3yGSLxe/XRXgOLQcmzYkFQMmwu+11nIR+XE6d/ede1rLy7v4Xh4mEAwolfxqvpkyi4rrCZY9zV4S4qkH+jSrB24x/xt6Gy7GQT3dfwGYhJY/e5MivQAAAABJRU5ErkJggg==';
8 |
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lufunc/timer/73dfbb72268ce741cdd0b2438970bbe594954a93/src/assets/logo.png
--------------------------------------------------------------------------------
/src/components/clock.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
198 |
199 |
209 |
--------------------------------------------------------------------------------
/src/components/setbox.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
41 |
42 |
102 |
--------------------------------------------------------------------------------
/src/components/slider.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
53 |
54 |
87 |
--------------------------------------------------------------------------------
/src/components/timePicker.vue:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
15 |
16 |
85 |
86 |
148 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import { createApp } from 'vue'
2 | import App from './App.vue'
3 |
4 | console.log = () => {}
5 |
6 | createApp(App).mount('#app')
7 |
--------------------------------------------------------------------------------
/src/utils/easeinout.js:
--------------------------------------------------------------------------------
1 | const easeIn = (curtime, begin, end, duration) => {
2 | const x = curtime / duration
3 | const y = x * x
4 | return begin + (end - begin) * y
5 | }
6 |
7 | const easeOut = (curtime, begin, end, duration) => {
8 | const x = curtime / duration
9 | const y = -x * x + 2 * x
10 | return begin + (end - begin) * y
11 | }
12 |
13 | const easeInout = (curtime, begin, end, duration) => {
14 | if (curtime < duration / 2) {
15 | return easeIn(curtime, begin, (begin + end) / 2, duration / 2)
16 | } else {
17 | const curtime1 = curtime - duration / 2
18 | const begin1 = (begin + end) / 2
19 | return easeOut(curtime1, begin1, end, duration / 2)
20 | }
21 | }
22 |
23 | export default easeInout
24 |
--------------------------------------------------------------------------------
/src/utils/getnum.js:
--------------------------------------------------------------------------------
1 | export const zeroNum = (n) => {
2 | const str = n.toString()
3 | return str[1] ? n : '0' + str
4 | }
5 |
6 | export const getClock = () => {
7 | const t = new Date()
8 | const h = t.getHours()
9 | const m = t.getMinutes()
10 | const s = t.getSeconds()
11 | return { h, m, s }
12 | }
13 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | lintOnSave: false,
3 | publicPath: './'
4 | }
5 |
--------------------------------------------------------------------------------