Guest User

Untitled

a guest
Jun 24th, 2018
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.14 KB | None | 0 0
  1. <template>
  2. <div class='carousel'>
  3. <svg width="100%" viewBox="0 0 100vw 100vh">
  4. <transition-group tag='g'
  5. appear
  6. appear-class="reveal"
  7. ref='svg'
  8. name='blinds'
  9. @after-enter='afterEnter'
  10. @after-leave='afterLeave'>
  11. <template v-if="showBlinds">
  12. <rect v-for='i in blindsCount'
  13. height='100%'
  14. :key='i'
  15. :x="`${(width / blindsCount) * (i - 1)}px`"
  16. :width="`${(width / blindsCount)}px`"></rect>
  17. </template>
  18. </transition-group>
  19. </svg>
  20. <picture>
  21. <img :src='images[currentImage]' />
  22. </picture>
  23. </div>
  24. </template>
  25.  
  26. <script>
  27. import ResizeObserver from "resize-observer-polyfill";
  28.  
  29. export default {
  30. name: "AcneCarousel",
  31. props: {
  32. images: {
  33. type: Array,
  34. default: () => []
  35. },
  36. maxBlindWidth: {
  37. type: Number | String,
  38. default: 24
  39. }
  40. },
  41. data() {
  42. return {
  43. currentImage: 0,
  44. showBlinds: true,
  45. offsetWidth: 0,
  46. width: 0,
  47. resizeObserver: false
  48. };
  49. },
  50. methods: {
  51. next() {
  52. if (this.currentImage === this.images.length - 1) {
  53. this.currentImage = 0;
  54. } else {
  55. this.currentImage = this.currentImage + 1;
  56. }
  57. this.showBlinds = true;
  58. },
  59. afterEnter() {
  60. setTimeout(() => {
  61. this.showBlinds = false;
  62. }, 4800)
  63. },
  64. afterLeave(e) {
  65. if(!this.showBlinds) {
  66. this.next()
  67. }
  68. }
  69. },
  70. computed: {
  71. blindsCount() {
  72. return Math.floor(this.width / this.maxBlindWidth);
  73. },
  74. blindWidth() {
  75. return Math.floor(100 / this.blindsCount);
  76. }
  77. },
  78. mounted() {
  79. this.width = this.$el.offsetWidth;
  80.  
  81. this.resizeObserver = new ResizeObserver(entries => {
  82. for (const entry of entries) {
  83. const { width } = entry.contentRect;
  84. this.$nextTick(() => {
  85. this.width = width;
  86. });
  87. }
  88. });
  89.  
  90. this.resizeObserver.observe(this.$el);
  91. }
  92. };
  93. </script>
  94.  
  95. <style scoped lang='scss'>
  96. .carousel {
  97. width: 100%;
  98. height: 100%;
  99. max-height: 100vh;
  100. position: relative;
  101. display: flex;
  102. justify-content: center;
  103. }
  104.  
  105. picture {
  106. height: 100%;
  107. display: flex;
  108. justify-content: center;
  109. z-index: -1;
  110. }
  111.  
  112. picture img {
  113. object-fit: contain;
  114. -webkit-filter: grayscale(100%);
  115. filter: grayscale(100%);
  116. }
  117.  
  118. svg {
  119. width: 100%;
  120. height: 100%;
  121. max-height: 100vh;
  122. z-index: 10000;
  123. position: absolute;
  124. perspective: 500px;
  125. }
  126.  
  127. svg rect {
  128. --width: 25px;
  129. fill: #2c82e1;
  130. stroke: #2c82e1;
  131. height: 100%;
  132. transform: scale(0, 1);
  133. transform-box: fill-box;
  134. transform-style: preserve-3d;
  135. transform-origin: left top;
  136. }
  137.  
  138. svg.reveal rect {
  139. transform: scale(1, 1) translateZ(0);
  140. -webkit-backface-visibility: hidden;
  141. }
  142.  
  143. .blinds-enter-active {
  144. animation: blinds-in 2s linear ;
  145. }
  146. .blinds-leave-active {
  147. animation: blinds-in 2s linear reverse;
  148. }
  149.  
  150. @keyframes blinds-in {
  151. 0% {
  152. transform: scale(1,1);
  153. transform-box: fill-box;
  154. }
  155. 100% {
  156. transform: scale(0, 1);
  157. transform-box: fill-box;
  158. stroke: none;
  159. }
  160. }
  161. </style>
Add Comment
Please, Sign In to add comment