flipper.vue 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. <template>
  2. <div class="M-Flipper" :class="[flipType, {'go': isFlipping}]">
  3. <div class="digital front" :class="_textClass(frontTextFromData)"></div>
  4. <div class="digital back" :class="_textClass(backTextFromData)"></div>
  5. </div>
  6. </template>
  7. <script>
  8. export default {
  9. name: 'FlipClock',
  10. data() {
  11. return {
  12. isFlipping: false,
  13. flipType: 'down',
  14. frontTextFromData: 0,
  15. backTextFromData: 1
  16. }
  17. },
  18. props: {
  19. // front paper text
  20. // 前牌文字
  21. frontText: {
  22. type: [Number, String],
  23. default: 0
  24. },
  25. // back paper text
  26. // 后牌文字
  27. backText: {
  28. type: [Number, String],
  29. default: 1
  30. },
  31. // flipping duration, please be consistent with the CSS animation-duration value.
  32. // 翻牌动画时间,与CSS中设置的animation-duration保持一致
  33. duration: {
  34. type: Number,
  35. default: 600
  36. }
  37. },
  38. methods: {
  39. _textClass(number) {
  40. return 'number' + number
  41. },
  42. _flip(type, front, back) {
  43. // 如果处于翻转中,则不执行
  44. if (this.isFlipping) {
  45. return false
  46. }
  47. this.frontTextFromData = front
  48. this.backTextFromData = back
  49. // 根据传递过来的type设置翻转方向
  50. this.flipType = type
  51. // 设置翻转状态为true
  52. this.isFlipping = true
  53. setTimeout(() => {
  54. // 设置翻转状态为false
  55. this.isFlipping = false
  56. this.frontTextFromData = back
  57. }, this.duration)
  58. },
  59. // 下翻牌
  60. flipDown(front, back) {
  61. this._flip('down', front, back)
  62. },
  63. // 上翻牌
  64. flipUp(front, back) {
  65. this._flip('up', front, back)
  66. },
  67. // 设置前牌文字
  68. setFront(text) {
  69. this.frontTextFromData = text
  70. },
  71. // 设置后牌文字
  72. setBack(text) {
  73. this.backTextFromData = text
  74. }
  75. },
  76. created() {
  77. this.frontTextFromData = this.frontText
  78. this.backTextFromData = this.backText
  79. }
  80. }
  81. </script>
  82. <style>
  83. .M-Flipper {
  84. display: inline-block;
  85. position: relative;
  86. width: 90px;
  87. height: 178px;
  88. line-height: 178px;
  89. /* border: solid 1px #000; */
  90. border-radius: 10px;
  91. background: #fff;
  92. font-size: 128px;
  93. color: #131415;
  94. box-shadow: 4px 4px 0px 0px #A2CAEE;
  95. text-align: center;
  96. font-family: 'DINA';
  97. }
  98. /* @media screen and (min-width: 375px) and (max-width: 768px){
  99. .M-Flipper {
  100. width: 35px;
  101. font-size: 40px;
  102. }
  103. }
  104. @media screen and (max-width: 320px){
  105. .M-Flipper {
  106. width: 25px;
  107. font-size: 40px;
  108. }
  109. }
  110. @media screen and (min-width: 320px) and (max-width: 375px){
  111. .M-Flipper {
  112. width: 27px;
  113. font-size: 40px;
  114. }
  115. } */
  116. .M-Flipper .digital:before,
  117. .M-Flipper .digital:after {
  118. content: '';
  119. position: absolute;
  120. left: 0;
  121. right: 0;
  122. background: #fff;
  123. overflow: hidden;
  124. box-sizing: border-box;
  125. }
  126. .M-Flipper .digital:before {
  127. top: 0;
  128. bottom: 50%;
  129. border-radius: 10px 10px 0 0;
  130. border-bottom: solid 2px #fff;
  131. }
  132. .M-Flipper .digital:after {
  133. top: 50%;
  134. bottom: 0;
  135. border-radius: 0 0 10px 10px;
  136. line-height: 0;
  137. }
  138. /*向下翻*/
  139. .M-Flipper.down .front:before {
  140. z-index: 3;
  141. }
  142. .M-Flipper.down .back:after {
  143. z-index: 2;
  144. transform-origin: 50% 0%;
  145. transform: perspective(160px) rotateX(180deg);
  146. }
  147. .M-Flipper.down .front:after,
  148. .M-Flipper.down .back:before {
  149. z-index: 1;
  150. }
  151. .M-Flipper.down.go .front:before {
  152. transform-origin: 50% 100%;
  153. animation: frontFlipDown 0.6s ease-in-out both;
  154. box-shadow: 0 -2px 6px rgba(255, 255, 255, 0.3);
  155. backface-visibility: hidden;
  156. }
  157. .M-Flipper.down.go .back:after {
  158. animation: backFlipDown 0.6s ease-in-out both;
  159. }
  160. /*向上翻*/
  161. .M-Flipper.up .front:after {
  162. z-index: 3;
  163. }
  164. .M-Flipper.up .back:before {
  165. z-index: 2;
  166. transform-origin: 50% 100%;
  167. transform: perspective(160px) rotateX(-180deg);
  168. }
  169. .M-Flipper.up .front:before,
  170. .M-Flipper.up .back:after {
  171. z-index: 1;
  172. }
  173. .M-Flipper.up.go .front:after {
  174. transform-origin: 50% 0;
  175. animation: frontFlipUp 0.6s ease-in-out both;
  176. box-shadow: 0 2px 6px rgba(255, 255, 255, 0.3);
  177. backface-visibility: hidden;
  178. }
  179. .M-Flipper.up.go .back:before {
  180. animation: backFlipUp 0.6s ease-in-out both;
  181. }
  182. @keyframes frontFlipDown {
  183. 0% {
  184. transform: perspective(160px) rotateX(0deg);
  185. }
  186. 100% {
  187. transform: perspective(160px) rotateX(-180deg);
  188. }
  189. }
  190. @keyframes backFlipDown {
  191. 0% {
  192. transform: perspective(160px) rotateX(180deg);
  193. }
  194. 100% {
  195. transform: perspective(160px) rotateX(0deg);
  196. }
  197. }
  198. @keyframes frontFlipUp {
  199. 0% {
  200. transform: perspective(160px) rotateX(0deg);
  201. }
  202. 100% {
  203. transform: perspective(160px) rotateX(180deg);
  204. }
  205. }
  206. @keyframes backFlipUp {
  207. 0% {
  208. transform: perspective(160px) rotateX(-180deg);
  209. }
  210. 100% {
  211. transform: perspective(160px) rotateX(0deg);
  212. }
  213. }
  214. .M-Flipper .number0:before,
  215. .M-Flipper .number0:after {
  216. content: '0';
  217. }
  218. .M-Flipper .number1:before,
  219. .M-Flipper .number1:after {
  220. content: '1';
  221. }
  222. .M-Flipper .number2:before,
  223. .M-Flipper .number2:after {
  224. content: '2';
  225. }
  226. .M-Flipper .number3:before,
  227. .M-Flipper .number3:after {
  228. content: '3';
  229. }
  230. .M-Flipper .number4:before,
  231. .M-Flipper .number4:after {
  232. content: '4';
  233. }
  234. .M-Flipper .number5:before,
  235. .M-Flipper .number5:after {
  236. content: '5';
  237. }
  238. .M-Flipper .number6:before,
  239. .M-Flipper .number6:after {
  240. content: '6';
  241. }
  242. .M-Flipper .number7:before,
  243. .M-Flipper .number7:after {
  244. content: '7';
  245. }
  246. .M-Flipper .number8:before,
  247. .M-Flipper .number8:after {
  248. content: '8';
  249. }
  250. .M-Flipper .number9:before,
  251. .M-Flipper .number9:after {
  252. content: '9';
  253. }
  254. </style>