prodViewImages.vue 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. <!-- 商品图片组件 -->
  2. <template>
  3. <div class="products-pic-panel">
  4. <div class="products-pic-all-box" id="PicZoom">
  5. <div class="products-pic-show-box" id="BigPic">
  6. <div
  7. class="middle-box"
  8. :style="{width: `${boxWidth}px`, height: `${boxHeight}px`}"
  9. @mouseenter="isShow = true"
  10. @mouseleave="isShow = false"
  11. @mousemove="move($event)">
  12. <img :src="middleImage[curIndex].proImgSrc" :alt="middleImage[curIndex].proImgAlt">
  13. <div
  14. class="move"
  15. :style="{width: `${this.glassWidth}px`,height: `${this.glassHeight}px`,top: `${this.glassTop}px`,left: `${this.glassLeft}px`}"
  16. v-if="isShow"
  17. ></div>
  18. </div>
  19. </div>
  20. <div class="products-pic-small-box">
  21. <span id="products-pic-pre" v-if="smallImage.length>4" @click="goPre"></span>
  22. <span id="products-pic-next" v-if="smallImage.length>4" @click="goNext"></span>
  23. <div
  24. id="SmallPicList"
  25. class="products-pic-list-box"
  26. :style="{width: `${SmallPicListWidth}px`}"
  27. >
  28. <ul :style="{width: `${this.ulWidth}px`,marginLeft: `${this.ulMarginLeft}px`}">
  29. <li
  30. v-for="(image,index) in smallImage"
  31. :key="index"
  32. :class="{picCur: curIndex == index}"
  33. @mouseenter="curIndex = index"
  34. >
  35. <img :src="image.proImgSrc" :alt="image.proImgAlt">
  36. </li>
  37. </ul>
  38. </div>
  39. </div>
  40. <div class="b_box" v-if="isShow">
  41. <img
  42. :src="bigImage[curIndex].proImgSrc"
  43. :style="{left: `${bigLeft}px`, top: `${bigTop}px`,width: `${this.bigWidth}px`,height: `${this.bigHeight}px`}"
  44. >
  45. </div>
  46. </div>
  47. </div>
  48. </template>
  49. <script>
  50. export default {
  51. //组件名称
  52. name: "prodViewImages",
  53. props: {
  54. bigImage: Array,
  55. middleImage: Array,
  56. smallImage: Array,
  57. },
  58. data() {
  59. return {
  60. //当前选中商品
  61. curIndex: 0,
  62. //是否显示大图
  63. isShow: false,
  64. //显示盒子的宽度和高度
  65. boxWidth: 500,
  66. boxHeight: 500,
  67. //显示盒子相对于浏览器窗口的偏移
  68. boxOffsetLeft: 0,
  69. boxOffsetTop: 0,
  70. //放大镜的宽度和高度
  71. glassWidth: 100,
  72. glassHeight: 100,
  73. //放大镜的位置
  74. glassLeft: 0,
  75. glassTop: 0,
  76. //大图的宽度和高度
  77. bigWidth: 1000,
  78. bigHeight: 1000,
  79. //大图的位置
  80. bigLeft: 0,
  81. bigTop: 0,
  82. //小图列表盒子的宽度
  83. SmallPicListWidth: 460,
  84. //小图列表li的宽度(加外边距)
  85. liOuterWidth: 120,
  86. //小图列表ul宽度
  87. ulWidth: 460,
  88. //小图列表ul的marginleft
  89. ulMarginLeft: 0,
  90. };
  91. },
  92. //初始化
  93. mounted() {
  94. this.$nextTick(() => {
  95. //显示盒子到浏览器窗口最左端的距离
  96. this.boxOffsetLeft = this.getElementLeft(
  97. document.querySelector(".middle-box")
  98. );
  99. //显示盒子到浏览器窗口最顶部的距离
  100. this.boxOffsetTop = this.getElementTop(
  101. document.querySelector(".middle-box")
  102. );
  103. //小图列表ul宽度
  104. if (this.smallImage.length > 4) {
  105. this.ulWidth = this.liOuterWidth * this.smallImage.length - 20;
  106. }
  107. });
  108. },
  109. methods: {
  110. //放大镜移动
  111. move(event) {
  112. //计算放大镜的位置
  113. //位置= 鼠标指针位置 - 显示盒子在浏览器上的偏移 - 放大镜宽高的一半
  114. this.glassLeft = event.pageX - this.boxOffsetLeft - this.glassWidth / 2;
  115. this.glassTop = event.pageY - this.boxOffsetTop - this.glassHeight / 2;
  116. //放大镜在水平方向上的最大距离
  117. var maxLeft = this.boxWidth - this.glassWidth;
  118. //放大镜在竖直方向上移动的最大距离
  119. var maxTop = this.boxHeight - this.glassHeight;
  120. //限制放大镜在水平方向的距离
  121. if (this.glassLeft < 0) {
  122. this.glassLeft = 0;
  123. } else if (this.glassLeft > maxLeft) {
  124. this.glassLeft = maxLeft;
  125. }
  126. //限制放大镜在竖直方向上的范围
  127. if (this.glassTop < 0) {
  128. this.glassTop = 0;
  129. } else if (this.glassTop > maxTop) {
  130. this.glassTop = maxTop;
  131. }
  132. //计算大图的移动位置
  133. this.bigLeft =
  134. -(this.glassLeft / maxLeft) * (this.bigWidth - this.boxWidth);
  135. this.bigTop =
  136. -(this.glassTop / maxTop) * (this.bigHeight - this.boxHeight);
  137. },
  138. //元素最左端到网页最左端的距离
  139. getElementLeft(element) {
  140. var actualLeft = element.offsetLeft;
  141. var current = element.offsetParent;
  142. while (current !== null) {
  143. actualLeft += current.offsetLeft;
  144. current = current.offsetParent;
  145. }
  146. return actualLeft;
  147. },
  148. //元素最顶端到网页最顶端的距离
  149. getElementTop(element) {
  150. var actualTop = element.offsetTop;
  151. var current = element.offsetParent;
  152. while (current !== null) {
  153. actualTop += current.offsetTop;
  154. current = current.offsetParent;
  155. }
  156. return actualTop;
  157. },
  158. //下一个点击按钮
  159. goNext() {
  160. if (
  161. this.SmallPicListWidth - this.ulMarginLeft >=
  162. this.smallImage.length * this.liOuterWidth -
  163. (this.smallImage.length - 1) * 8
  164. ) {
  165. return;
  166. }
  167. this.ulMarginLeft = -this.liOuterWidth + this.ulMarginLeft;
  168. },
  169. //上一个点击按钮
  170. goPre() {
  171. if (this.ulMarginLeft > -this.liOuterWidth) {
  172. this.ulMarginLeft = 0;
  173. return;
  174. } else {
  175. this.ulMarginLeft = this.ulMarginLeft + this.liOuterWidth;
  176. }
  177. },
  178. },
  179. };
  180. </script>
  181. <style scoped>
  182. .products-pic-panel {
  183. width: 100%;
  184. height: 100%;
  185. }
  186. .products-pic-all-box {
  187. position: relative;
  188. width: 100%;
  189. height: 100%;
  190. }
  191. .products-pic-show-box {
  192. position: relative;
  193. overflow: hidden;
  194. width: 100%;
  195. height: 500px;
  196. background: #f2f2f2;
  197. }
  198. .products-pic-show-box img {
  199. width: 100%;
  200. height: 100%;
  201. }
  202. .move {
  203. position: absolute;
  204. background: #fff;
  205. z-index: 99;
  206. filter: alpha(opacity=40);
  207. opacity: 0.4;
  208. cursor: move;
  209. }
  210. .b_box {
  211. position: absolute;
  212. top: 0;
  213. left: 501px;
  214. width: 500px;
  215. height: 500px;
  216. overflow: hidden;
  217. background: #fff;
  218. }
  219. .b_box img {
  220. position: absolute;
  221. top: 0;
  222. left: 0;
  223. }
  224. .products-pic-small-box {
  225. position: relative;
  226. overflow: hidden;
  227. width: 100%;
  228. height: auto;
  229. margin-top: 10px;
  230. }
  231. .products-pic-list-box {
  232. overflow: hidden;
  233. width: 460px;
  234. height: 102px;
  235. margin: 0 auto;
  236. }
  237. .products-pic-list-box ul {
  238. overflow: hidden;
  239. width: 100%;
  240. height: 100%;
  241. }
  242. .products-pic-list-box ul li {
  243. float: left;
  244. overflow: hidden;
  245. width: 100px;
  246. height: 100px;
  247. margin-right: 20px;
  248. background: #f2f2f2;
  249. border: 1px solid transparent;
  250. box-sizing: border-box;
  251. cursor: pointer;
  252. }
  253. .products-pic-list-box ul li:last-child {
  254. margin-right: 0;
  255. }
  256. .products-pic-list-box ul li.picCur {
  257. border: 1px solid #000;
  258. }
  259. .products-pic-list-box ul li img {
  260. width: 100%;
  261. height: 100%;
  262. }
  263. span#products-pic-pre {
  264. position: absolute;
  265. top: 0;
  266. left: 0;
  267. display: block;
  268. width: 20px;
  269. height: 100px;
  270. cursor: pointer;
  271. background: #f2f2f2 url('~assets/images/index/banner-btn-pre.png') center center
  272. no-repeat;
  273. }
  274. span#products-pic-next {
  275. position: absolute;
  276. top: 0;
  277. right: 0;
  278. display: block;
  279. width: 20px;
  280. height: 100px;
  281. cursor: pointer;
  282. background: #f2f2f2 url('~assets/images/index/banner-btn-next.png') center
  283. center no-repeat;
  284. }
  285. span#products-pic-pre:hover {
  286. background: #f2f2f2 url('~assets/images/products/banner-btn-pre-cur.png') center
  287. center no-repeat;
  288. }
  289. span#products-pic-next:hover {
  290. background: #f2f2f2 url('~assets/images/products/banner-btn-next-cur.png')
  291. center center no-repeat;
  292. }
  293. </style>