ImageTextPreview.vue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. <!-- eslint-disable vue/no-v-html -->
  2. <template>
  3. <div class="imageText-preview" :style="getAreaStyle()">
  4. <SerialNumberPosition v-if="isEnable(data.property.sn_display_mode)" :property="data.property" />
  5. <template v-if="data.mp3_list && data.mp3_list.length > 0 && mp3_url">
  6. <AudioLine
  7. ref="audioLine"
  8. audio-id="Audio"
  9. :mp3="mp3_url"
  10. :get-cur-time="getCurTime"
  11. :duration="data.mp3_list[0].media_duration"
  12. :mp3-source="data.mp3_list[0].source"
  13. :width="audio_width"
  14. :ed="ed"
  15. type="audioLine"
  16. @emptyEd="emptyEd"
  17. />
  18. </template>
  19. <div
  20. v-if="image_url"
  21. class="img-box"
  22. :style="{
  23. background: 'url(' + image_url + ') center / contain no-repeat',
  24. width: data.image_width + 'px',
  25. height: data.image_height + 'px',
  26. }"
  27. >
  28. <div
  29. v-for="(itemP, indexP) in data.text_list"
  30. :key="'text' + indexP"
  31. :class="['position-item', mageazineDetailIndex === indexP ? 'active' : '']"
  32. :style="{
  33. width: itemP.width,
  34. height: itemP.height,
  35. left: itemP.x,
  36. top: itemP.y,
  37. }"
  38. @click="handleChangePosition(indexP)"
  39. ></div>
  40. <div
  41. v-for="(itemP, indexP) in data.input_list"
  42. :key="'input' + indexP"
  43. :class="['position-item position-item-input', 'active']"
  44. :style="{
  45. width: itemP.width,
  46. height: itemP.height,
  47. left: itemP.x,
  48. top: itemP.y,
  49. }"
  50. >
  51. <el-input v-model="answer.answer_list[indexP].text" type="textarea" style="height: 100%" placeholder="请输入" />
  52. </div>
  53. </div>
  54. </div>
  55. </template>
  56. <script>
  57. import PreviewMixin from '../common/PreviewMixin';
  58. import AudioLine from '../voice_matrix/components/AudioLine.vue';
  59. import { getImageTextData } from '@/views/book/courseware/data/imageText';
  60. import { GetFileURLMap } from '@/api/app';
  61. export default {
  62. name: 'ImageTextPreview',
  63. components: { AudioLine },
  64. mixins: [PreviewMixin],
  65. data() {
  66. return {
  67. data: getImageTextData(),
  68. curTime: 0,
  69. paraIndex: -1, // 段落索引
  70. sentIndex: -1, // 句子索引
  71. ed: undefined,
  72. mp3_url: '',
  73. image_url: '',
  74. audio_width: 0,
  75. mageazineDetailIndex: null, // 当前高亮第几个
  76. mageazineDetailShow: false,
  77. inputIndex: null,
  78. };
  79. },
  80. created() {
  81. this.initData();
  82. },
  83. mounted() {
  84. this.audio_width = document.getElementsByClassName('imageText-preview')[0].clientWidth - 150;
  85. },
  86. methods: {
  87. initData() {
  88. if (!this.isJudgingRightWrong) {
  89. this.answer.answer_list = [];
  90. this.data.input_list.forEach((item, index) => {
  91. let obj = {
  92. text: '',
  93. answer: item.text,
  94. id: item.id,
  95. };
  96. this.answer.answer_list.push(obj);
  97. });
  98. }
  99. this.data.image_list.forEach((item) => {
  100. GetFileURLMap({ file_id_list: [item.file_id] }).then(({ url_map }) => {
  101. this.image_url = url_map[item.file_id];
  102. });
  103. });
  104. this.data.mp3_list.forEach((item) => {
  105. GetFileURLMap({ file_id_list: [item.file_id] }).then(({ url_map }) => {
  106. this.mp3_url = url_map[item.file_id];
  107. });
  108. });
  109. },
  110. getCurTime(curTime) {
  111. this.curTime = curTime * 1000;
  112. this.getSentIndex(this.curTime);
  113. },
  114. getSentIndex(curTime) {
  115. // for (let i = 0; i < this.curQue.wordTime.length; i++) {
  116. // let bg = this.curQue.wordTime[i].bg;
  117. // let ed = this.curQue.wordTime[i].ed;
  118. // if (curTime >= bg && curTime <= ed) {
  119. // this.sentIndex = i;
  120. // break;
  121. // }
  122. // }
  123. },
  124. emptyEd() {
  125. this.ed = undefined;
  126. },
  127. // 切换画刊里面的卡片
  128. handleChangePosition(index) {
  129. if (this.$refs.audioLine.audio.playing) {
  130. this.$refs.audioLine.PlayAudio();
  131. }
  132. this.mageazineDetailIndex = index;
  133. this.mageazineDetailShow = true;
  134. },
  135. },
  136. };
  137. </script>
  138. <style lang="scss" scoped>
  139. @use '@/styles/mixin.scss' as *;
  140. .position-item {
  141. position: absolute;
  142. z-index: 1;
  143. cursor: pointer;
  144. border: 3px solid transparent;
  145. &.active {
  146. border-color: #ff1616;
  147. }
  148. &:hover {
  149. border-color: #ff1616;
  150. }
  151. &.position-item-input {
  152. border-color: #f90;
  153. }
  154. :deep .el-textarea__inner {
  155. height: 100%;
  156. font-family: 'League', '楷体';
  157. text-align: center;
  158. resize: none;
  159. background: transparent;
  160. border: none;
  161. }
  162. }
  163. .img-box {
  164. position: relative;
  165. margin: 20px auto;
  166. }
  167. </style>