邃芒官网、邃芒慧影、口播(H5) https://m.metavatar.cc
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

387 lines
11 KiB

  1. <template>
  2. <div v-if="proportion" :class="inPage ? 'page active' : 'page'" id="pageBody">
  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.scList"
  17. :key="index"
  18. class="material"
  19. :style="{
  20. transformOrigin: 'top left',
  21. transform: 'scale(' + item.w / proportion + ') ',
  22. zIndex: item.z,
  23. top: item.y / proportion + 'px',
  24. left: item.x / proportion + 'px'
  25. }"
  26. >
  27. <div>{{ item.text }}</div>
  28. <img :src="item.material" alt="" />
  29. <!-- 边框 -->
  30. <div :class="domIndex == index ? 'active' : ''"></div>
  31. </div>
  32. <!-- 数字人 -->
  33. <div
  34. id="virtual"
  35. @touchmove="onMouseMove1()"
  36. @touchstart="onMouseDown1()"
  37. @touchend="onMouseUp1()"
  38. class="material"
  39. :style="{
  40. transformOrigin: 'top left',
  41. transform: 'scale(' + materialList.virtual.w / proportion + ') ',
  42. zIndex: materialList.virtual.z,
  43. top: materialList.virtual.y / proportion + 'px',
  44. left: materialList.virtual.x / proportion + 'px'
  45. }"
  46. >
  47. <!-- <div>{{ item.text }}</div> -->
  48. <img :src="materialList.virtual.material" alt="" />
  49. <!-- 边框 -->
  50. <!-- <div :class="domIndex1 == index ? 'active' : ''"></div> -->
  51. </div>
  52. </div>
  53. </div>
  54. </template>
  55. <script>
  56. // 组件
  57. import Vue from 'vue'
  58. import { Toast } from 'vant'
  59. import { mapState, mapActions } from 'vuex'
  60. // 工具
  61. import { scrollToID } from '../utils'
  62. Vue.use(Toast)
  63. export default {
  64. props: {
  65. imgUrl: {
  66. default: false
  67. // type: String
  68. },
  69. materialList: {
  70. default: false,
  71. type: Object
  72. },
  73. videoType: {
  74. default: false
  75. },
  76. proportion: {
  77. default: false
  78. }
  79. },
  80. data() {
  81. return {
  82. inPage: false,
  83. dragging: false,
  84. proportionSon: null,
  85. startDistance: 0, //两指起始位置
  86. startX: 0,
  87. startY: 0, // 鼠标位置x y
  88. windowWidth: 0,
  89. windowHeight: 0,
  90. scale: 1,
  91. domIndex: -1, //当前点击的图片
  92. domIndex1: -1 //当前点击的数字人
  93. }
  94. },
  95. computed: {
  96. ...mapState({
  97. characters: (state) => state.publicObj.characters,
  98. //动态计算样式
  99. bgStyle() {
  100. return {
  101. // width: '1080px',
  102. // height: '1920px',
  103. // transform: 'scale(0.2)',
  104. backgroundImage: `url(${this.materialList.BGI.material})`,
  105. backgroundSize: 'cover',
  106. backgroundPosition: 'center'
  107. }
  108. }
  109. })
  110. },
  111. methods: {
  112. ...mapActions(['setCharacters']),
  113. // 鼠标按下事件
  114. onMouseDown(index) {
  115. this.dragging = true
  116. this.domIndex = index
  117. //双指缩放初始化
  118. if (event.touches[1]) {
  119. this.startDistance = this.getDistance(
  120. event.touches[0],
  121. event.touches[1]
  122. )
  123. }
  124. // 记录点击瞬间的鼠标坐标
  125. this.startX = event.touches[0].clientX
  126. this.startY = event.touches[0].clientY
  127. },
  128. // 鼠标抬起
  129. onMouseUp(index) {
  130. this.dragging = false
  131. // this.domIndex = -1
  132. },
  133. // 鼠标在父盒子移动时,判断是否按下,然后再走逻辑
  134. onMouseMove(index) {
  135. // 禁止默认事件--下拉
  136. event.preventDefault()
  137. if (!this.dragging) return
  138. if (this.domIndex != index) return
  139. // console.log(event.touches[0])
  140. // 双指缩放
  141. if (event.touches[1]) {
  142. const distance = this.getDistance(event.touches[0], event.touches[1])
  143. const scale = (distance / this.startDistance).toFixed(2)
  144. this.materialList.scList[index].w = scale
  145. this.materialList.scList[index].h = scale
  146. }
  147. const deltaX = event.touches[0].clientX - this.startX
  148. const deltaY = event.touches[0].clientY - this.startY
  149. // console.log(deltaX)
  150. this.materialList.scList[index].x += deltaX.toFixed(0) * this.proportion
  151. this.materialList.scList[index].y += deltaY.toFixed(0) * this.proportion
  152. this.startX = event.touches[0].clientX
  153. this.startY = event.touches[0].clientY
  154. // 得到父子盒子信息
  155. const fatherRect = this.$refs.fatherBox.getBoundingClientRect()
  156. // 子盒子信息
  157. const sonRect = document
  158. .getElementById(`item${index}`)
  159. .getBoundingClientRect()
  160. // 限制X轴
  161. // console.log(fatherRect)
  162. // console.log(sonRect)
  163. // if (this.materialList.scList[index].x < -sonRect.width) {
  164. // this.materialList.scList[index].x = 0
  165. // this.exceed()
  166. // }
  167. // if (this.materialList.scList[index].x > fatherRect.width) {
  168. // this.materialList.scList[index].x = 0
  169. // this.exceed()
  170. // }
  171. // // 限制Y轴
  172. // if (this.materialList.scList[index].y < -sonRect.height) {
  173. // this.materialList.scList[index].y = 0
  174. // this.exceed()
  175. // }
  176. // if (this.materialList.scList[index].y > fatherRect.height) {
  177. // this.materialList.scList[index].y = 0
  178. // this.exceed()
  179. // }
  180. },
  181. // 数字人的处理
  182. // 鼠标按下事件
  183. onMouseDown1() {
  184. this.domIndex = -2
  185. this.dragging = true
  186. //双指缩放初始化
  187. if (event.touches[1]) {
  188. this.startDistance = this.getDistance(
  189. event.touches[0],
  190. event.touches[1]
  191. )
  192. }
  193. // 记录点击瞬间的鼠标坐标
  194. this.startX = event.touches[0].clientX
  195. this.startY = event.touches[0].clientY
  196. },
  197. // 鼠标抬起
  198. onMouseUp1() {
  199. this.dragging = false
  200. this.startDistance = 0
  201. },
  202. // 鼠标在父盒子移动时,判断是否按下,然后再走逻辑
  203. onMouseMove1() {
  204. // 禁止默认事件--下拉
  205. event.preventDefault()
  206. if (!this.dragging) return
  207. // console.log(event.touches[0])
  208. // 双指缩放
  209. if (event.touches[1]) {
  210. const distance = this.getDistance(event.touches[0], event.touches[1])
  211. const scale = (distance / this.startDistance).toFixed(2)
  212. this.materialList.virtual.w = scale
  213. this.materialList.virtual.h = scale
  214. }
  215. // 得到父子盒子信息
  216. const fatherRect = this.$refs.fatherBox.getBoundingClientRect()
  217. // 子盒子信息
  218. const sonRect = document.getElementById(`virtual`).getBoundingClientRect()
  219. const deltaX = event.touches[0].clientX - this.startX
  220. const deltaY = event.touches[0].clientY - this.startY
  221. // console.log(deltaX)
  222. this.materialList.virtual.x += deltaX.toFixed(0) * this.proportion
  223. this.materialList.virtual.y += deltaY.toFixed(0) * this.proportion
  224. this.startX = event.touches[0].clientX
  225. this.startY = event.touches[0].clientY
  226. // 限制X轴
  227. // console.log(fatherRect)
  228. // console.log(sonRect)
  229. // if (this.materialList.virtual.x < -sonRect.width) {
  230. // this.materialList.virtual.x = 0
  231. // this.exceed()
  232. // }
  233. // if (this.materialList.virtual.x > fatherRect.width) {
  234. // this.materialList.virtual.x = 0
  235. // this.exceed()
  236. // }
  237. // // 限制Y轴
  238. // if (this.materialList.virtual.y < -sonRect.height) {
  239. // this.materialList.virtual.y = 0
  240. // this.exceed()
  241. // }
  242. // if (this.materialList.virtual.y > fatherRect.height) {
  243. // this.materialList.virtual.y = 0
  244. // this.exceed()
  245. // }
  246. },
  247. // 控制台
  248. controlImg(type) {
  249. if (this.domIndex == -1) {
  250. Toast('请选择素材')
  251. return
  252. }
  253. if (type == 1) {
  254. this.materialList[this.domIndex].scale += 0.1
  255. }
  256. if (type == 2) {
  257. this.materialList[this.domIndex].scale -= 0.1
  258. }
  259. if (type == 3) {
  260. // 如果是点的数字人
  261. if (this.domIndex == -2) {
  262. this.materialList.virtual.z += 1
  263. if (this.materialList.virtual.z >= 10) {
  264. this.materialList.virtual.z = 10
  265. }
  266. return
  267. }
  268. // 点的素材
  269. this.materialList.scList[this.domIndex].z += 1
  270. if (this.materialList.scList[this.domIndex].z >= 10) {
  271. this.materialList.scList[this.domIndex].z = 10
  272. }
  273. }
  274. if (type == 4) {
  275. // 如果是点的数字人
  276. if (this.domIndex == -2) {
  277. this.materialList.virtual.z -= 1
  278. if (this.materialList.virtual.z <= 0) {
  279. this.materialList.virtual.z = 0
  280. }
  281. return
  282. }
  283. // 点的素材
  284. this.materialList.scList[this.domIndex].z -= 1
  285. if (this.materialList.scList[this.domIndex].z <= 0) {
  286. this.materialList.scList[this.domIndex].z = 0
  287. }
  288. }
  289. },
  290. // 素材超出显示范围
  291. exceed() {
  292. Toast('素材超出显示范围')
  293. },
  294. // 计算双指距离
  295. getDistance(touch1, touch2) {
  296. const dx = touch1.pageX - touch2.pageX
  297. const dy = touch1.pageY - touch2.pageY
  298. return Math.sqrt(dx * dx + dy * dy)
  299. },
  300. go(url) {
  301. this.$router.push(url)
  302. }
  303. },
  304. watch: {
  305. // proportion(newValue) {
  306. // this.proportionSon = newValue
  307. // }
  308. },
  309. created() {},
  310. mounted() {
  311. this.inPage = true
  312. scrollToID('top')
  313. // const elementWidth = document.getElementById('pageBody').clientHeight
  314. // this.proportionSon = elementWidth / 1080
  315. // console.log(elementWidth)
  316. }
  317. }
  318. </script>
  319. <style lang="scss" scoped>
  320. * {
  321. box-sizing: content-box !important;
  322. }
  323. .page {
  324. transform: translateX(30%);
  325. opacity: 0;
  326. transition: all 0.5s; // global-transition
  327. &.active {
  328. opacity: 1;
  329. transform: translateX(0);
  330. }
  331. height: 100%;
  332. width: 100%;
  333. position: fixed;
  334. top: 0;
  335. left: 0;
  336. }
  337. .content {
  338. position: relative;
  339. width: 100%;
  340. height: 100%;
  341. // width: 1080px;
  342. // height: 1920px;
  343. // transform: scale(0.3, 0.3);
  344. // transform-origin: top left;
  345. // background-color: green;
  346. overflow: hidden;
  347. .active {
  348. position: absolute;
  349. top: -10px;
  350. left: -10px;
  351. width: 100%;
  352. height: 100%;
  353. border: 10px solid rgba(0, 0, 0, 0.5);
  354. }
  355. .material {
  356. position: absolute;
  357. top: 0;
  358. left: 0;
  359. // width: 150px;
  360. // height: 140px;
  361. // background-color: red;
  362. img {
  363. // width: 216px;
  364. // height: 150px;
  365. // background-color: red;
  366. }
  367. }
  368. }
  369. </style>