ProductLeft.vue 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. <template>
  2. <div class="product-left">
  3. <div class="media">
  4. <div class="big" v-show="bigShow">
  5. <img :src="$utils.generateResizedImageUrl(comInfo.mergeImages[currentPre],1800)" alt="" ref="big" />
  6. </div>
  7. <el-carousel
  8. :interval="5000"
  9. arrow="always"
  10. height="578px"
  11. indicator-position="none"
  12. :autoplay="false"
  13. ref="carousel"
  14. @change="changeCarousel "
  15. >
  16. <el-carousel-item v-for="item in comInfo.mergeImages" :key="item">
  17. <!-- <div class="banner" :style="{backgroundImage: 'url(' + item + ')'}"></div> -->
  18. <zoom :imgUrl="$utils.generateResizedImageUrl(comInfo.mergeImages[currentPre],1800)" @sendStyle="getStyle" @handleViwer="handleViwer"></zoom>
  19. </el-carousel-item>
  20. <el-carousel-item v-if="comInfo.video">
  21. <video controls width="100%" height="100%" ref="video">
  22. <source
  23. :src="comInfo.video">
  24. Your browser does not support the video tag.
  25. </video>
  26. </el-carousel-item>
  27. </el-carousel>
  28. </div>
  29. <div class="smImgUl">
  30. <ul>
  31. <li
  32. @click="changeCarousel (index)"
  33. :class="currentPre == index ? 'slip' : ''"
  34. v-for="(item, index) of comInfo.mergeImages"
  35. :key="index"
  36. class="banner">
  37. <el-image
  38. :src="$utils.generateResizedImageUrl(item,100)"
  39. class="card-img-1"
  40. fit="cover"
  41. style="width: 100%; height: 100%"
  42. ></el-image>
  43. </li>
  44. <li
  45. @click="changeCarousel (comInfo.mergeImages?.length)"
  46. :class="currentPre == comInfo.mergeImages?.length ? 'slip' : ''"
  47. v-if="comInfo.video">
  48. <video width="100%" height="100%" :src="comInfo.video" />
  49. <div class="playMask">
  50. <img src="@/assets/img/play.png" alt="" />
  51. </div>
  52. </li>
  53. </ul>
  54. </div>
  55. <ElImageViewer
  56. v-if="showViewer" :initial-index="currentPre"
  57. :on-close="closeViewer"
  58. :url-list="comS3Img"
  59. />
  60. </div>
  61. </template>
  62. <script>
  63. import { mapMutations } from 'vuex'
  64. import ElImageViewer from "element-ui/packages/image/src/image-viewer";
  65. import Zoom from "@/components/Zoom";
  66. export default {
  67. components: { Zoom,ElImageViewer },
  68. props: {
  69. pageData: {
  70. type: Object,
  71. default: () => {
  72. return {};
  73. },
  74. },
  75. id: {
  76. type: Number,
  77. default: 0
  78. },
  79. },
  80. data() {
  81. return {
  82. indexBanner: [],
  83. btnObj: ["View larger", "3D Preview"],
  84. current3D: 0, // 3D图序号
  85. btnShow: true, // 所有按钮显示
  86. bigShow: false,
  87. showViewer: false,
  88. };
  89. },
  90. computed: {
  91. currentPre(){
  92. return this.$store.state.product.smImgUlIdx
  93. },
  94. comInfo(){
  95. const temp = this.pageData.main
  96. const a = temp.image_color.map((i)=>i.image)
  97. temp.mergeImages = [...temp.images,...a]
  98. return temp
  99. },
  100. comS3Img(){
  101. return this.comInfo.mergeImages.map(url => this.$utils.repaceDomain(url));
  102. }
  103. },
  104. watch:{
  105. currentPre(newVal){
  106. this.$refs.carousel.setActiveItem(newVal);
  107. }
  108. },
  109. mounted(){
  110. if(this.comInfo.video){
  111. this.$refs.video.volume = 0.5;
  112. }
  113. },
  114. methods: {
  115. ...mapMutations({ setSmImgUlIdx: 'product/setSmImgUlIdx' }),
  116. changeCarousel (val) {
  117. this.setSmImgUlIdx(val);
  118. if (val === this.comInfo.mergeImages?.length) {
  119. this.btnShow = false;
  120. this.comInfo.video && this.$refs.video.play();
  121. } else {
  122. this.btnShow = true;
  123. this.comInfo.video && this.$refs.video.pause();
  124. }
  125. },
  126. selectCurrent3D(val) {
  127. this.current3D = val;
  128. },
  129. goDesign(template_id, goods_id) {
  130. this.$axios
  131. .get("/bxh/design", { params: { template_id, goods_id } })
  132. .then((res) => {
  133. const { href } = this.$router.resolve({
  134. name: "design-id",
  135. params: { id: res.result },
  136. });
  137. window.open(href, "_black");
  138. });
  139. },
  140. getStyle(val) {
  141. const bigImg = this.$refs.big;
  142. bigImg.style.left = -2 * val.left + "px";
  143. bigImg.style.top = -2 * val.top + "px";
  144. this.bigShow = val.bigShow;
  145. },
  146. closeViewer() {
  147. this.showViewer = false;
  148. },
  149. handleViwer(){
  150. this.showViewer = true;
  151. }
  152. }
  153. };
  154. </script>
  155. <style lang="scss" scoped>
  156. .product-left {
  157. padding-right: 20px;
  158. .media {
  159. border: 1px solid rgba(74, 89, 108, 0.2);
  160. position: relative;
  161. width: 578px;
  162. height: 578px;
  163. .banner {
  164. width: 100%;
  165. height: 100%;
  166. background-size: cover;
  167. background-repeat: no-repeat;
  168. background-position: center;
  169. }
  170. video {
  171. object-fit: contain;
  172. }
  173. .design_list_img {
  174. padding: 10px;
  175. // display: flex;
  176. // flex-wrap: wrap;
  177. // justify-content:space-around;
  178. display: grid;
  179. grid-template-columns: repeat(4, 1fr);
  180. gap: 10px;
  181. li {
  182. cursor: pointer;
  183. // width: 192px;
  184. // height:192px;
  185. }
  186. }
  187. .switch-wrap {
  188. position: absolute;
  189. left: 50%;
  190. bottom: 20px;
  191. transform: translate(-50%, 0);
  192. z-index: 2;
  193. font-family: ProximaNova-Regular;
  194. }
  195. .switch-btn {
  196. text-align: center;
  197. &:nth-child(1) {
  198. margin-bottom: 20px;
  199. }
  200. .primary_button {
  201. display: inline-block;
  202. cursor: pointer;
  203. width: 140px;
  204. background: rgba(255, 255, 255);
  205. box-shadow: 0 2px 4px 1px rgba(0, 0, 0, 0.2);
  206. padding: 10px 0;
  207. color: #00213b;
  208. transition: all 0.2s ease-out 0s;
  209. }
  210. .primary_checked {
  211. background: #00213b !important;
  212. color: #fff !important;
  213. }
  214. }
  215. }
  216. .smImgUl {
  217. ul {
  218. margin-top: 10px;
  219. display: inline-grid;
  220. grid-template-columns: repeat(8, 68px);
  221. gap: 5px;
  222. li {
  223. box-sizing: border-box;
  224. border: 1px solid #eee;
  225. cursor: pointer;
  226. width: 100%;
  227. height: 68px;
  228. background-size: cover;
  229. background-repeat: no-repeat;
  230. background-position: center;
  231. position: relative;
  232. }
  233. .slip {
  234. border-color: #4a596c !important;
  235. }
  236. .playMask {
  237. position: absolute;
  238. top: 0;
  239. width: 100%;
  240. height: 100%;
  241. background-color: rgba(0, 0, 0, 0.3);
  242. display: flex;
  243. align-items: center;
  244. justify-content: center;
  245. }
  246. }
  247. }
  248. }
  249. .big {
  250. width: 100%;
  251. height: 100%;
  252. position: absolute;
  253. top: -1px;
  254. left: 100%;
  255. border: 1px solid rgba(74, 89, 108, 0.2);
  256. overflow: hidden;
  257. z-index: 3;
  258. // display: block;
  259. background: white;
  260. // box-sizing: border-box;
  261. img {
  262. width: 200%;
  263. max-width: 200%;
  264. height: 200%;
  265. position: absolute;
  266. left: 0;
  267. top: 0;
  268. object-fit: cover;
  269. }
  270. }
  271. </style>