邃芒官网、邃芒慧影、口播(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.
 
 
 
 

398 regels
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 + ') ',
  22. zIndex: item.z,
  23. top: item.y + 'px',
  24. left: item.x + '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. if (this.videoType == 1) {
  101. return {
  102. // width: '1080px',
  103. // height: '1920px',
  104. // transform: 'scale(0.2)',
  105. backgroundImage: `url(${this.materialList.BGI.material})`,
  106. backgroundSize: 'cover',
  107. backgroundPosition: 'center'
  108. }
  109. }
  110. if (this.videoType == 2) {
  111. return {
  112. // width: '1920px',
  113. // height: '1080px',
  114. // transform: 'scale(0.2)',
  115. backgroundImage: `url(${this.materialList.BGI.material})`,
  116. backgroundSize: 'cover',
  117. backgroundPosition: 'center'
  118. }
  119. }
  120. }
  121. })
  122. },
  123. methods: {
  124. ...mapActions(['setCharacters']),
  125. // 鼠标按下事件
  126. onMouseDown(index) {
  127. this.dragging = true
  128. this.domIndex = index
  129. //双指缩放初始化
  130. if (event.touches[1]) {
  131. this.startDistance = this.getDistance(
  132. event.touches[0],
  133. event.touches[1]
  134. )
  135. }
  136. // 记录点击瞬间的鼠标坐标
  137. this.startX = event.touches[0].clientX
  138. this.startY = event.touches[0].clientY
  139. },
  140. // 鼠标抬起
  141. onMouseUp(index) {
  142. this.dragging = false
  143. // this.domIndex = -1
  144. },
  145. // 鼠标在父盒子移动时,判断是否按下,然后再走逻辑
  146. onMouseMove(index) {
  147. // 禁止默认事件--下拉
  148. event.preventDefault()
  149. if (!this.dragging) return
  150. if (this.domIndex != index) return
  151. // console.log(event.touches[0])
  152. // 双指缩放
  153. if (event.touches[1]) {
  154. const distance = this.getDistance(event.touches[0], event.touches[1])
  155. const scale = (distance / this.startDistance).toFixed(2)
  156. this.materialList.scList[index].w = scale
  157. this.materialList.scList[index].h = scale
  158. }
  159. const deltaX = event.touches[0].clientX - this.startX
  160. const deltaY = event.touches[0].clientY - this.startY
  161. // console.log(deltaX)
  162. this.materialList.scList[index].x += deltaX
  163. this.materialList.scList[index].y += deltaY
  164. this.startX = event.touches[0].clientX
  165. this.startY = event.touches[0].clientY
  166. // 得到父子盒子信息
  167. const fatherRect = this.$refs.fatherBox.getBoundingClientRect()
  168. // 子盒子信息
  169. const sonRect = document
  170. .getElementById(`item${index}`)
  171. .getBoundingClientRect()
  172. // 限制X轴
  173. // console.log(fatherRect)
  174. // console.log(sonRect)
  175. if (this.materialList.scList[index].x < -sonRect.width) {
  176. this.materialList.scList[index].x = 0
  177. this.exceed()
  178. }
  179. if (this.materialList.scList[index].x > fatherRect.width) {
  180. this.materialList.scList[index].x = 0
  181. this.exceed()
  182. }
  183. // 限制Y轴
  184. if (this.materialList.scList[index].y < -sonRect.height) {
  185. this.materialList.scList[index].y = 0
  186. this.exceed()
  187. }
  188. if (this.materialList.scList[index].y > fatherRect.height) {
  189. this.materialList.scList[index].y = 0
  190. this.exceed()
  191. }
  192. },
  193. // 数字人的处理
  194. // 鼠标按下事件
  195. onMouseDown1() {
  196. this.domIndex = -2
  197. this.dragging = true
  198. //双指缩放初始化
  199. if (event.touches[1]) {
  200. this.startDistance = this.getDistance(
  201. event.touches[0],
  202. event.touches[1]
  203. )
  204. }
  205. // 记录点击瞬间的鼠标坐标
  206. this.startX = event.touches[0].clientX
  207. this.startY = event.touches[0].clientY
  208. },
  209. // 鼠标抬起
  210. onMouseUp1() {
  211. this.dragging = false
  212. },
  213. // 鼠标在父盒子移动时,判断是否按下,然后再走逻辑
  214. onMouseMove1() {
  215. // 禁止默认事件--下拉
  216. event.preventDefault()
  217. if (!this.dragging) return
  218. // console.log(event.touches[0])
  219. // 双指缩放
  220. if (event.touches[1]) {
  221. const distance = this.getDistance(event.touches[0], event.touches[1])
  222. const scale = (distance / this.startDistance).toFixed(2)
  223. this.materialList.virtual.w = scale
  224. this.materialList.virtual.h = scale
  225. }
  226. // 得到父子盒子信息
  227. const fatherRect = this.$refs.fatherBox.getBoundingClientRect()
  228. // 子盒子信息
  229. const sonRect = document.getElementById(`virtual`).getBoundingClientRect()
  230. const deltaX = event.touches[0].clientX - this.startX
  231. const deltaY = event.touches[0].clientY - this.startY
  232. // console.log(deltaX)
  233. this.materialList.virtual.x += deltaX.toFixed(0) * this.proportion
  234. this.materialList.virtual.y += deltaY.toFixed(0) * this.proportion
  235. this.startX = event.touches[0].clientX
  236. this.startY = event.touches[0].clientY
  237. // 限制X轴
  238. // console.log(fatherRect)
  239. // console.log(sonRect)
  240. // if (this.materialList.virtual.x < -sonRect.width) {
  241. // this.materialList.virtual.x = 0
  242. // this.exceed()
  243. // }
  244. // if (this.materialList.virtual.x > fatherRect.width) {
  245. // this.materialList.virtual.x = 0
  246. // this.exceed()
  247. // }
  248. // // 限制Y轴
  249. // if (this.materialList.virtual.y < -sonRect.height) {
  250. // this.materialList.virtual.y = 0
  251. // this.exceed()
  252. // }
  253. // if (this.materialList.virtual.y > fatherRect.height) {
  254. // this.materialList.virtual.y = 0
  255. // this.exceed()
  256. // }
  257. },
  258. // 控制台
  259. controlImg(type) {
  260. if (this.domIndex == -1) {
  261. Toast('请选择素材')
  262. return
  263. }
  264. if (type == 1) {
  265. this.materialList[this.domIndex].scale += 0.1
  266. }
  267. if (type == 2) {
  268. this.materialList[this.domIndex].scale -= 0.1
  269. }
  270. if (type == 3) {
  271. // 如果是点的数字人
  272. if (this.domIndex == -2) {
  273. this.materialList.virtual.z += 1
  274. if (this.materialList.virtual.z >= 10) {
  275. this.materialList.virtual.z = 10
  276. }
  277. return
  278. }
  279. // 点的素材
  280. this.materialList.scList[this.domIndex].z += 1
  281. if (this.materialList.scList[this.domIndex].z >= 10) {
  282. this.materialList.scList[this.domIndex].z = 10
  283. }
  284. }
  285. if (type == 4) {
  286. // 如果是点的数字人
  287. if (this.domIndex == -2) {
  288. this.materialList.virtual.z -= 1
  289. if (this.materialList.virtual.z <= 0) {
  290. this.materialList.virtual.z = 0
  291. }
  292. return
  293. }
  294. // 点的素材
  295. this.materialList.scList[this.domIndex].z -= 1
  296. if (this.materialList.scList[this.domIndex].z <= 0) {
  297. this.materialList.scList[this.domIndex].z = 0
  298. }
  299. }
  300. },
  301. // 素材超出显示范围
  302. exceed() {
  303. Toast('素材超出显示范围')
  304. },
  305. // 计算双指距离
  306. getDistance(touch1, touch2) {
  307. const dx = touch1.pageX - touch2.pageX
  308. const dy = touch1.pageY - touch2.pageY
  309. return Math.sqrt(dx * dx + dy * dy)
  310. },
  311. go(url) {
  312. this.$router.push(url)
  313. }
  314. },
  315. watch: {
  316. // proportion(newValue) {
  317. // this.proportionSon = newValue
  318. // }
  319. },
  320. created() {},
  321. mounted() {
  322. this.inPage = true
  323. scrollToID('top')
  324. // const elementWidth = document.getElementById('pageBody').clientHeight
  325. // this.proportionSon = elementWidth / 1080
  326. // console.log(elementWidth)
  327. }
  328. }
  329. </script>
  330. <style lang="scss" scoped>
  331. * {
  332. box-sizing: content-box !important;
  333. }
  334. .page {
  335. transform: translateX(30%);
  336. opacity: 0;
  337. transition: all 0.5s; // global-transition
  338. &.active {
  339. opacity: 1;
  340. transform: translateX(0);
  341. }
  342. height: 100%;
  343. width: 100%;
  344. position: fixed;
  345. top: 0;
  346. left: 0;
  347. }
  348. .content {
  349. position: relative;
  350. width: 100%;
  351. height: 100%;
  352. // width: 1080px;
  353. // height: 1920px;
  354. // transform: scale(0.3, 0.3);
  355. // transform-origin: top left;
  356. // background-color: green;
  357. overflow: hidden;
  358. .active {
  359. position: absolute;
  360. top: -10px;
  361. left: -10px;
  362. width: 100%;
  363. height: 100%;
  364. border: 10px solid rgba(0, 0, 0, 0.5);
  365. }
  366. .material {
  367. position: absolute;
  368. top: 0;
  369. left: 0;
  370. // width: 150px;
  371. // height: 140px;
  372. // background-color: red;
  373. img {
  374. // width: 216px;
  375. // height: 150px;
  376. // background-color: red;
  377. }
  378. }
  379. }
  380. </style>