├── .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 | 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 | 6 | 7 | 198 | 199 | 209 | -------------------------------------------------------------------------------- /src/components/setbox.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 41 | 42 | 102 | -------------------------------------------------------------------------------- /src/components/slider.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 53 | 54 | 87 | -------------------------------------------------------------------------------- /src/components/timePicker.vue: -------------------------------------------------------------------------------- 1 | 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 | --------------------------------------------------------------------------------