邃芒官网、邃芒慧影、口播(H5) https://m.metavatar.cc
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 

313 rader
7.4 KiB

  1. <template>
  2. <div :class="inPage ? 'page active' : 'page'">
  3. <div class="content" :style="bgStyle" ref="fatherBox">
  4. <!-- 控制框 -->
  5. <!-- <div class="control">
  6. <div @click="controlImg(1)">放大</div>
  7. <div @click="controlImg(2)">缩小</div>
  8. <div @click="controlImg(3)">上移一层</div>
  9. <div @click="controlImg(4)">下移一层</div>
  10. </div> -->
  11. <div
  12. :id="'item' + index"
  13. @touchmove="onMouseMove(index)"
  14. @touchstart="onMouseDown(index)"
  15. @touchend="onMouseUp(index)"
  16. v-for="(item, index) in materialList"
  17. :key="index"
  18. class="material"
  19. :style="{
  20. transform: 'scale(' + item.scale + ') ',
  21. zIndex: item.zIndex,
  22. top: item.y + 'px',
  23. left: item.x + 'px'
  24. }"
  25. >
  26. <div>{{ item.text }}</div>
  27. <img :src="item.url" alt="" />
  28. <!-- 边框 -->
  29. <div :class="domIndex == index ? 'active' : ''"></div>
  30. </div>
  31. </div>
  32. </div>
  33. </template>
  34. <script>
  35. // 组件
  36. import Vue from 'vue'
  37. import { Toast } from 'vant'
  38. import { mapState, mapActions } from 'vuex'
  39. // 工具
  40. import { scrollToID } from '../utils'
  41. Vue.use(Toast)
  42. export default {
  43. props: {
  44. imgUrl: {
  45. default: false
  46. // type: String
  47. },
  48. materialList: {
  49. default: false,
  50. type: Object
  51. }
  52. },
  53. data() {
  54. return {
  55. inPage: false,
  56. dragging: false,
  57. startDistance: 0, //两指起始位置
  58. startX: 0,
  59. startY: 0, // 鼠标位置x y
  60. windowWidth: 0,
  61. windowHeight: 0,
  62. scale: 1,
  63. domIndex: -1 //当前点击的图片
  64. // materialList: [
  65. // {
  66. // text: '小div1',
  67. // url: 'img/BG@2x.b0cf224b.png',
  68. // x: 10, // 相对左上角XY坐标
  69. // y: 190,
  70. // scale: 1, //缩放
  71. // zIndex: 1 //层级
  72. // },
  73. // {
  74. // text: '小div2',
  75. // url: 'img/BG@2x.b0cf224b.png',
  76. // x: 100,
  77. // y: 0,
  78. // scale: 1,
  79. // zIndex: 2
  80. // },
  81. // {
  82. // text: '小div3',
  83. // url: require('../assets/img/bg.png'),
  84. // x: 0,
  85. // y: 100,
  86. // scale: 1,
  87. // zIndex: 3
  88. // },
  89. // {
  90. // text: '小div4',
  91. // url: require('../assets/img/cn.jpeg'),
  92. // x: 100,
  93. // y: 100,
  94. // scale: 1,
  95. // zIndex: 4
  96. // },
  97. // {
  98. // text: '小div5',
  99. // url: require('../assets/img/ft.png'),
  100. // x: 100,
  101. // y: 280,
  102. // scale: 1,
  103. // zIndex: 5
  104. // }
  105. // ]
  106. }
  107. },
  108. computed: {
  109. ...mapState({
  110. characters: (state) => state.publicObj.characters,
  111. //动态计算样式
  112. bgStyle() {
  113. return {
  114. backgroundImage: `url(${this.imgUrl})`,
  115. backgroundSize: 'cover',
  116. backgroundPosition: 'center'
  117. }
  118. }
  119. })
  120. // imageStyles() {
  121. // return this.images.map((image, index) => {
  122. // return {
  123. // zIndex: index,
  124. // width: `${image.width}px`,
  125. // height: `${image.height}px`,
  126. // position: 'absolute',
  127. // top: `${image.y}px`,
  128. // left: `${image.x}px`,
  129. // };
  130. // });
  131. // },
  132. },
  133. methods: {
  134. ...mapActions(['setCharacters']),
  135. // 鼠标按下事件
  136. onMouseDown(index) {
  137. this.dragging = true
  138. this.domIndex = index
  139. //双指缩放初始化
  140. if (event.touches[1]) {
  141. this.startDistance = this.getDistance(
  142. event.touches[0],
  143. event.touches[1]
  144. )
  145. }
  146. // 记录点击瞬间的鼠标坐标
  147. this.startX = event.touches[0].clientX
  148. this.startY = event.touches[0].clientY
  149. },
  150. // 鼠标抬起
  151. onMouseUp(index) {
  152. this.dragging = false
  153. // this.domIndex = -1
  154. },
  155. // 鼠标在父盒子移动时,判断是否按下,然后再走逻辑
  156. onMouseMove(index) {
  157. // 禁止默认事件--下拉
  158. event.preventDefault()
  159. if (!this.dragging) return
  160. if (this.domIndex != index) return
  161. // console.log(event.touches[0])
  162. // 双指缩放
  163. if (event.touches[1]) {
  164. const distance = this.getDistance(event.touches[0], event.touches[1])
  165. const scale = distance / this.startDistance
  166. this.materialList[index].scale = scale
  167. }
  168. const deltaX = event.touches[0].clientX - this.startX
  169. const deltaY = event.touches[0].clientY - this.startY
  170. // console.log(deltaX)
  171. this.materialList[index].x += deltaX
  172. this.materialList[index].y += deltaY
  173. this.startX = event.touches[0].clientX
  174. this.startY = event.touches[0].clientY
  175. // 得到父子盒子信息
  176. const fatherRect = this.$refs.fatherBox.getBoundingClientRect()
  177. // 子盒子信息
  178. const sonRect = document
  179. .getElementById(`item${index}`)
  180. .getBoundingClientRect()
  181. // 限制X轴
  182. // console.log(fatherRect)
  183. // console.log(sonRect)
  184. if (this.materialList[index].x < -sonRect.width) {
  185. this.materialList[index].x = 0
  186. this.exceed()
  187. }
  188. if (this.materialList[index].x > fatherRect.width) {
  189. this.materialList[index].x = 0
  190. this.exceed()
  191. }
  192. // 限制Y轴
  193. if (this.materialList[index].y < -sonRect.height) {
  194. this.materialList[index].y = 0
  195. this.exceed()
  196. }
  197. if (this.materialList[index].y > fatherRect.height) {
  198. this.materialList[index].y = 0
  199. this.exceed()
  200. }
  201. },
  202. // 控制台
  203. controlImg(type) {
  204. if (this.domIndex == -1) {
  205. Toast('请选择素材')
  206. return
  207. }
  208. if (type == 1) {
  209. this.materialList[this.domIndex].scale += 0.1
  210. }
  211. if (type == 2) {
  212. this.materialList[this.domIndex].scale -= 0.1
  213. }
  214. if (type == 3) {
  215. this.materialList[this.domIndex].zIndex += 1
  216. }
  217. if (type == 4) {
  218. this.materialList[this.domIndex].zIndex -= 1
  219. }
  220. },
  221. // 素材超出显示范围
  222. exceed() {
  223. Toast('素材超出显示范围')
  224. },
  225. // 计算双指距离
  226. getDistance(touch1, touch2) {
  227. const dx = touch1.pageX - touch2.pageX
  228. const dy = touch1.pageY - touch2.pageY
  229. return Math.sqrt(dx * dx + dy * dy)
  230. },
  231. go(url) {
  232. this.$router.push(url)
  233. }
  234. },
  235. created() {},
  236. mounted() {
  237. this.inPage = true
  238. scrollToID('top')
  239. }
  240. }
  241. </script>
  242. <style lang="scss" scoped>
  243. * {
  244. box-sizing: content-box !important;
  245. }
  246. .control {
  247. position: absolute;
  248. top: 0;
  249. left: 50%;
  250. transform: translateX(-50%);
  251. display: flex;
  252. justify-content: space-around;
  253. width: 200px;
  254. height: 30px;
  255. text-align: center;
  256. line-height: 30px;
  257. background-color: #fff;
  258. z-index: 999999;
  259. }
  260. .page {
  261. transform: translateX(30%);
  262. opacity: 0;
  263. transition: all 0.5s; // global-transition
  264. &.active {
  265. opacity: 1;
  266. transform: translateX(0);
  267. }
  268. height: 100%;
  269. width: 100%;
  270. position: fixed;
  271. top: 0;
  272. left: 0;
  273. }
  274. .content {
  275. position: relative;
  276. width: 100%;
  277. height: 100%;
  278. background-color: green;
  279. overflow: hidden;
  280. .active {
  281. position: absolute;
  282. top: -10px;
  283. left: -10px;
  284. width: 100%;
  285. height: 100%;
  286. border: 10px solid rgba(0, 0, 0, 0.5);
  287. }
  288. .material {
  289. position: absolute;
  290. top: 0;
  291. left: 0;
  292. // width: 150px;
  293. // height: 140px;
  294. // background-color: red;
  295. img {
  296. width: 150px;
  297. height: 150px;
  298. // background-color: red;
  299. }
  300. }
  301. }
  302. </style>