Voicefullscreen.vue 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908
  1. <!-- -->
  2. <template>
  3. <div :class="['voicefull', bgIndex == 0 ? 'bg1' : 'bg2']" v-if="sentList">
  4. <div
  5. class="voicefull-top"
  6. @mouseover="setTopShow(true)"
  7. @mouseleave="setTopShow(false)"
  8. >
  9. <div :class="[isTopShow ? 'voicefull-top-show' : 'voicefull-top-hidden']">
  10. <div class="top-left">
  11. <div :class="['select-bg', bgIndex == 1 ? 'select-bg-blue' : '']">
  12. <div :class="['bg-green-box', bgIndex == 1 ? 'active' : '']">
  13. <span
  14. :class="['bg-green', bgIndex == 1 ? 'active' : '']"
  15. @click="changeBg(1)"
  16. ></span>
  17. </div>
  18. <div :class="['bg-white-box', bgIndex == 0 ? 'active' : '']">
  19. <span
  20. :class="['bg-white', bgIndex == 0 ? 'active' : '']"
  21. @click="changeBg(0)"
  22. ></span>
  23. </div>
  24. </div>
  25. <div
  26. :class="['set-fontSize', bgIndex == 1 ? 'set-fontSize-green' : '']"
  27. >
  28. <template v-if="hzSize >= 34">
  29. <span
  30. :class="[
  31. 'font-jian-black',
  32. bgIndex == 1 ? 'font-jian-yellow' : '',
  33. ]"
  34. @click="setFontSize('-')"
  35. ></span>
  36. </template>
  37. <template v-else>
  38. <span
  39. :class="[
  40. 'font-jian-black',
  41. bgIndex == 1
  42. ? 'font-jian-yellow-disabled'
  43. : 'font-jian-white-disabled',
  44. ]"
  45. ></span>
  46. </template>
  47. <span
  48. :class="['font-img-black', bgIndex == 1 ? 'font-img-yellow' : '']"
  49. ></span>
  50. <template v-if="hzSize <= 76">
  51. <span
  52. :class="[
  53. 'font-jia-black',
  54. bgIndex == 1 ? 'font-jia-yellow' : '',
  55. ]"
  56. @click="setFontSize('+')"
  57. ></span>
  58. </template>
  59. <template v-else>
  60. <span
  61. :class="[
  62. 'font-jia-black',
  63. bgIndex == 1
  64. ? 'font-jia-yellow-disabled'
  65. : 'font-jia-white-disabled',
  66. ]"
  67. ></span>
  68. </template>
  69. </div>
  70. <div
  71. :class="['op-btn', bgIndex == 1 ? 'op-btn-green' : '']"
  72. @click="changeStatus('isKeyboard')"
  73. title="键盘控制开启后,可用方向键控制翻页,空格键播放暂停,回车键录音"
  74. >
  75. <span
  76. :class="[
  77. 'keyboard-icon',
  78. !isKeyboard ? 'disabled' : '',
  79. isKeyboard && bgIndex == 1 ? 'keyboard-icon-yellow' : '',
  80. ]"
  81. ></span>
  82. </div>
  83. </div>
  84. <div class="top-middle">
  85. <template v-if="mp3">
  86. <AudioLineSentence
  87. :key="'sent' + curSentIndex"
  88. :mp3="mp3"
  89. :getCurTime="getCurTime"
  90. ref="audioLineSent"
  91. :audioId="'artPraAudioId' + curSentIndex"
  92. :stopAudio="stopAudio"
  93. :width="120"
  94. :hideSlider="true"
  95. :bg="bg"
  96. :ed="ed"
  97. :curTime="curTime"
  98. :maxTime="maxTime"
  99. :bgIndex="bgIndex"
  100. :isRepeat="isRepeat"
  101. :isAuto="isAuto"
  102. @playChange="playChange"
  103. @rollSentence="rollSentence"
  104. />
  105. </template>
  106. <div
  107. :class="['op-btn', bgIndex == 1 ? 'op-btn-green' : '']"
  108. @click="setStatus"
  109. >
  110. <span
  111. :class="[
  112. 'repeat-icon',
  113. !isRepeat && !isAuto ? 'disabled' : '',
  114. !isRepeat && isAuto ? 'auto-icon' : '',
  115. isRepeat && bgIndex == 1 ? 'repeat-icon-yellow' : '',
  116. !isRepeat && isAuto && bgIndex == 1 ? 'auto-icon-yellow' : '',
  117. ]"
  118. ></span>
  119. </div>
  120. <div
  121. :class="['op-btn', bgIndex == 1 ? 'op-btn-green' : '']"
  122. @click="changePinyin"
  123. >
  124. <span
  125. :class="[
  126. 'pinyin-icon',
  127. !config.isShowPY ? 'disabled' : '',
  128. config.isShowPY && bgIndex == 1 ? 'pinyin-icon-yellow' : '',
  129. ]"
  130. ></span>
  131. </div>
  132. <div
  133. :class="['op-btn', bgIndex == 1 ? 'op-btn-green' : '']"
  134. @click="changeEN"
  135. >
  136. <span
  137. :class="[
  138. 'en-icon',
  139. !enwords ? 'disabled' : '',
  140. !config.isShowEN ? 'disabled' : '',
  141. config.isShowEN && bgIndex == 1 ? 'en-icon-yellow' : '',
  142. ]"
  143. ></span>
  144. </div>
  145. <div
  146. :class="['op-btn', bgIndex == 1 ? 'op-btn-green' : '']"
  147. @click="handleColl"
  148. title="点击收藏后可在“个人中心”-“我的收藏”查看"
  149. >
  150. <span
  151. :class="[
  152. 'coll-icon',
  153. !isCollArr[curSentIndex] ? 'disabled' : '',
  154. isCollArr[curSentIndex] && bgIndex == 1
  155. ? 'coll-icon-yellow'
  156. : '',
  157. ]"
  158. ></span>
  159. </div>
  160. </div>
  161. <div
  162. :class="['op-btn', bgIndex == 1 ? 'op-btn-green' : '']"
  163. @click="exitFullScreen"
  164. >
  165. <span
  166. :class="['close-icon', bgIndex == 1 ? 'close-icon-white' : '']"
  167. ></span>
  168. </div>
  169. </div>
  170. </div>
  171. <div class="voicefull-content" v-if="item">
  172. <div
  173. class="vc-box"
  174. @mousemove="showPrevNext(true, 'isShowLeft')"
  175. @mouseleave="showPrevNext(false, 'isShowLeft')"
  176. >
  177. <div
  178. :class="[
  179. 'vc-left vc-left-grey',
  180. isShowLeft && bgIndex == 0 ? 'vc-left-black' : '',
  181. isShowLeft && bgIndex == 1 ? 'vc-left-white' : '',
  182. curSentIndex == 0 ? 'hidden' : '',
  183. ]"
  184. @click="prevSentence"
  185. ></div>
  186. </div>
  187. <div class="vc-main">
  188. <div class="NNPE-words-box">
  189. <div
  190. class="NNPE-words"
  191. v-for="(pItem, pIndex) in item"
  192. :key="'wordsList' + pIndex"
  193. :class="[
  194. pItem.chs != '“' && pItem.wordIndex == 0
  195. ? 'textLeft'
  196. : 'textCenter',
  197. pItem.chs == '“' ? 'textRight' : '',
  198. ]"
  199. @dblclick="showWordDetail($event, pItem)"
  200. @click="playWord(pItem)"
  201. >
  202. <template v-if="!pItem.width">
  203. <template v-if="pItem.isShow">
  204. <template
  205. v-if="
  206. item[pIndex + 1] &&
  207. item[pIndex + 1].chs &&
  208. chsFhList.indexOf(item[pIndex + 1].chs) > -1
  209. "
  210. >
  211. <span class="NNPE-words-box">
  212. <template v-if="curQue.pyPosition == 'top'">
  213. <span
  214. v-if="config.isShowPY"
  215. class="NNPE-pinyin"
  216. :class="[
  217. pItem.className ? pItem.className : '',
  218. noFont.indexOf(pItem.pinyin) > -1 ? 'noFont' : '',
  219. bgIndex == 1 ? 'font-white' : '',
  220. ]"
  221. :style="'font-size:' + pySize + 'px'"
  222. >{{ pItem.pinyin }}</span
  223. >
  224. </template>
  225. <span
  226. class="NNPE-chs"
  227. :class="[
  228. pItem.padding && config.isShowPY ? 'padding' : '',
  229. curQue.pyPosition == 'top' ? 'bottom' : '',
  230. ]"
  231. >
  232. <template>
  233. <span
  234. v-for="(wItem, wIndex) in pItem.leg"
  235. :key="'ci' + wIndex + pIndex"
  236. :class="[
  237. isPlaying &&
  238. pItem.timeList &&
  239. pItem.timeList[wIndex] &&
  240. curTime >= pItem.timeList[wIndex].wordBg &&
  241. curQue.wordTime &&
  242. curQue.wordTime[curSentIndex] &&
  243. curTime <= curQue.wordTime[curSentIndex].ed
  244. ? bgIndex == 0
  245. ? 'active'
  246. : 'active-yellow'
  247. : '',
  248. bgIndex == 1 ? 'font-white' : '',
  249. bgIndex == 0 && wordIndex == pItem.wordIndex
  250. ? 'wordActive'
  251. : '',
  252. bgIndex == 1 && wordIndex == pItem.wordIndex
  253. ? 'wordActive-blue'
  254. : '',
  255. ]"
  256. :style="'font-size:' + hzSize + 'px'"
  257. >{{ pItem.chs[wIndex] }}</span
  258. >
  259. </template>
  260. </span>
  261. <template v-if="curQue.pyPosition == 'bottom'">
  262. <span
  263. v-if="config.isShowPY"
  264. class="NNPE-pinyin bottom"
  265. :class="[
  266. pItem.className ? pItem.className : '',
  267. noFont.indexOf(pItem.pinyin) > -1 ? 'noFont' : '',
  268. bgIndex == 1 ? 'font-white' : '',
  269. ]"
  270. :style="'font-size:' + pySize + 'px'"
  271. >{{ pItem.pinyin }}</span
  272. >
  273. </template>
  274. </span>
  275. <span class="NNPE-words-box">
  276. <template v-if="curQue.pyPosition == 'top'">
  277. <span
  278. v-if="config.isShowPY"
  279. :class="[
  280. 'NNPE-pinyin',
  281. noFont.indexOf(item[pIndex + 1].pinyin) > -1
  282. ? 'noFont'
  283. : '',
  284. bgIndex == 1 ? 'font-white' : '',
  285. ]"
  286. :style="{ fontSize: pySize + 'px', textAlign: left }"
  287. >{{ item[pIndex + 1].pinyin }}</span
  288. >
  289. </template>
  290. <span
  291. :class="[
  292. 'NNPE-chs',
  293. curQue.pyPosition == 'top' ? 'bottom' : '',
  294. ]"
  295. :style="{ fontSize: hzSize + 'px', textAlign: left }"
  296. >
  297. <span
  298. :class="[
  299. isPlaying &&
  300. pItem.timeList[pItem.leg - 1] &&
  301. curTime >= pItem.timeList[pItem.leg - 1].wordBg &&
  302. curQue.wordTime &&
  303. curQue.wordTime[curSentIndex] &&
  304. curTime <= curQue.wordTime[curSentIndex].ed
  305. ? bgIndex == 0
  306. ? 'active'
  307. : 'active-yellow'
  308. : '',
  309. bgIndex == 1 ? 'font-white' : '',
  310. ]"
  311. :style="{ fontSize: pySize + 'px' }"
  312. >{{ item[pIndex + 1].chs }}</span
  313. >
  314. </span>
  315. <template v-if="curQue.pyPosition == 'bottom'">
  316. <span
  317. v-if="config.isShowPY"
  318. :class="[
  319. 'NNPE-pinyin',
  320. noFont.indexOf(item[pIndex + 1].pinyin) > -1
  321. ? 'noFont'
  322. : '',
  323. bgIndex == 1 ? 'font-white' : '',
  324. 'bottom',
  325. ]"
  326. :style="{ fontSize: pySize + 'px', textAlign: left }"
  327. >{{ item[pIndex + 1].pinyin }}</span
  328. >
  329. </template>
  330. </span>
  331. <span
  332. class="NNPE-words-box"
  333. v-if="
  334. item[pIndex + 2] &&
  335. item[pIndex + 2].chs &&
  336. chsFhList.indexOf(item[pIndex + 2].chs) > -1
  337. "
  338. >
  339. <template v-if="curQue.pyPosition == 'top'">
  340. <span
  341. v-if="config.isShowPY"
  342. :class="[
  343. 'NNPE-pinyin',
  344. noFont.indexOf(item[pIndex + 2].pinyin) > -1
  345. ? 'noFont'
  346. : '',
  347. bgIndex == 1 ? 'font-white' : '',
  348. ]"
  349. :style="{ fontSize: pySize + 'px', textAlign: left }"
  350. >{{ item[pIndex + 2].pinyin }}</span
  351. >
  352. </template>
  353. <span
  354. :class="[
  355. 'NNPE-chs',
  356. curQue.pyPosition == 'top' ? 'bottom' : '',
  357. ]"
  358. :style="{ fontSize: hzSize + 'px', textAlign: left }"
  359. >
  360. <span
  361. :class="[
  362. isPlaying &&
  363. pItem.timeList[pItem.leg - 1] &&
  364. curTime >= pItem.timeList[pItem.leg - 1].wordBg &&
  365. curQue.wordTime &&
  366. curQue.wordTime[curSentIndex] &&
  367. curTime <= curQue.wordTime[curSentIndex].ed
  368. ? bgIndex == 0
  369. ? 'active'
  370. : 'active-yellow'
  371. : '',
  372. bgIndex == 1 ? 'font-white' : '',
  373. ]"
  374. :style="{ fontSize: pySize + 'px' }"
  375. >{{ item[pIndex + 2].chs }}</span
  376. >
  377. </span>
  378. <template v-if="curQue.pyPosition == 'bottom'">
  379. <span
  380. v-if="config.isShowPY"
  381. :class="[
  382. 'NNPE-pinyin',
  383. noFont.indexOf(item[pIndex + 2].pinyin) > -1
  384. ? 'noFont'
  385. : '',
  386. bgIndex == 1 ? 'font-white' : '',
  387. 'bottom',
  388. ]"
  389. :style="{ fontSize: pySize + 'px', textAlign: left }"
  390. >{{ item[pIndex + 2].pinyin }}</span
  391. >
  392. </template>
  393. </span>
  394. </template>
  395. <template v-else>
  396. <template v-if="curQue.pyPosition == 'top'">
  397. <template v-if="NumberList.indexOf(pItem.pinyin) < 0">
  398. <span
  399. v-if="config.isShowPY"
  400. class="NNPE-pinyin"
  401. :class="[
  402. pItem.chs != '“' && pItem.padding ? 'padding' : '',
  403. pItem.className ? pItem.className : '',
  404. noFont.indexOf(pItem.pinyin) > -1 ? 'noFont' : '',
  405. bgIndex == 1 ? 'font-white' : '',
  406. ]"
  407. :style="{ fontSize: pySize + 'px' }"
  408. >{{ pItem.pinyin }}</span
  409. >
  410. </template>
  411. </template>
  412. <span
  413. v-if="pItem.chs != '#'"
  414. class="NNPE-chs"
  415. :class="[
  416. pItem.chs != '“' && pItem.padding && config.isShowPY
  417. ? 'padding'
  418. : '',
  419. curQue.pyPosition == 'top' ? 'bottom' : '',
  420. ]"
  421. >
  422. <template>
  423. <span
  424. v-for="(wItem, wIndex) in pItem.leg"
  425. :key="'ci' + wIndex + pIndex + curSentIndex"
  426. :class="[
  427. isPlaying &&
  428. pItem.timeList &&
  429. pItem.timeList[wIndex] &&
  430. curTime >= pItem.timeList[wIndex].wordBg &&
  431. curQue.wordTime &&
  432. curQue.wordTime[curSentIndex] &&
  433. curTime <= curQue.wordTime[curSentIndex].ed
  434. ? bgIndex == 0
  435. ? 'active'
  436. : 'active-yellow'
  437. : '',
  438. bgIndex == 1 ? 'font-white' : '',
  439. bgIndex == 0 && wordIndex == pItem.wordIndex
  440. ? 'wordActive'
  441. : '',
  442. bgIndex == 1 && wordIndex == pItem.wordIndex
  443. ? 'wordActive-blue'
  444. : '',
  445. ]"
  446. :style="{ fontSize: hzSize + 'px' }"
  447. >{{ pItem.chs[wIndex] }}</span
  448. >
  449. </template>
  450. </span>
  451. <template v-if="curQue.pyPosition == 'bottom'">
  452. <template v-if="NumberList.indexOf(pItem.pinyin) < 0">
  453. <span
  454. v-if="config.isShowPY"
  455. class="NNPE-pinyin bottom"
  456. :class="[
  457. pItem.chs != '“' && pItem.padding ? 'padding' : '',
  458. pItem.className ? pItem.className : '',
  459. bgIndex == 1 ? 'font-white' : '',
  460. ]"
  461. :style="{ fontSize: pySize + 'px' }"
  462. >{{ pItem.pinyin }}</span
  463. >
  464. </template>
  465. </template>
  466. </template>
  467. </template>
  468. </template>
  469. <template v-else>
  470. <span
  471. :style="{
  472. height: pItem.height + 'px',
  473. width: pItem.width + 'px',
  474. }"
  475. ></span>
  476. </template>
  477. </div>
  478. </div>
  479. <div style="clear: both; overflow: hidden"></div>
  480. <div
  481. v-if="enwords && config.isShowEN"
  482. :class="['enwords', bgIndex == 1 ? 'enwords-green' : '']"
  483. :style="{ fontSize: enSize + 'px' }"
  484. >
  485. {{ enwords }}
  486. </div>
  487. </div>
  488. <div
  489. class="vc-box-right"
  490. @mousemove="showPrevNext(true, 'isShowRight')"
  491. @mouseleave="showPrevNext(false, 'isShowRight')"
  492. >
  493. <div
  494. :class="[
  495. 'vc-left vc-right-grey',
  496. isShowRight && bgIndex == 0 ? 'vc-right-black' : '',
  497. isShowRight && bgIndex == 1 ? 'vc-right-white' : '',
  498. curSentIndex == sentList.length - 1 ? 'hidden' : '',
  499. ]"
  500. @click="nextSentence"
  501. ></div>
  502. </div>
  503. </div>
  504. <div
  505. class="voicefull-bottom"
  506. @mouseover="setBottomShow(true)"
  507. @mouseleave="setBottomShow(false)"
  508. >
  509. <div
  510. :class="[
  511. isBottomShow ? 'voicefull-bottom-show' : 'voicefull-bottom-hidden',
  512. ]"
  513. >
  514. <div
  515. :class="[
  516. 'bottom-left',
  517. TaskModel == 'ANSWER' ? 'bottom-left-margin' : '',
  518. ]"
  519. >
  520. <Soundrecorddiff
  521. ref="Soundrecorddiff"
  522. @handleWav="handleWav"
  523. @getWavblob="getWavblob"
  524. @handleParentPlay="handleParentPlay"
  525. @sentPause="sentPause"
  526. @getRerordStatus="getRerordStatus"
  527. @getMicrophoneStatus="getMicrophoneStatus"
  528. @getPlayStatus="getPlayStatus"
  529. :bgIndex="bgIndex"
  530. :TaskModel="TaskModel"
  531. :answerRecordList="
  532. curQue.Bookanswer.practiceModel[curSentIndex] &&
  533. curQue.Bookanswer.practiceModel[curSentIndex].recordList
  534. "
  535. :tmIndex="curSentIndex"
  536. :key="'Soundrecorddiff' + curSentIndex"
  537. />
  538. <div
  539. :class="['compare-box', bgIndex == 1 ? 'compare-box-white' : '']"
  540. v-if="isShowCompare"
  541. >
  542. <Audio-compare
  543. :bgIndex="bgIndex"
  544. type="full"
  545. :themeColor="themeColor"
  546. :index="curSentIndex"
  547. :sentIndex="curSentIndex"
  548. :url="curQue.mp3_list[0].id"
  549. :bg="bg"
  550. :ed="ed"
  551. :wavblob="wavblob"
  552. :getCurTime="getCurCompareTime"
  553. :sentPause="sentPause"
  554. :isRecord="isRecord"
  555. :handleChangeStopAudio="handleChangeStopAudio"
  556. :getPlayStatus="getPlayStatus"
  557. :key="'mp3Compare' + curSentIndex"
  558. />
  559. </div>
  560. </div>
  561. <div
  562. :class="[
  563. 'page-count',
  564. bgIndex == 0 ? 'page-count-white' : 'page-count-green',
  565. ]"
  566. >
  567. {{ curSentIndex + 1 }}/{{ sentList.length }}
  568. </div>
  569. </div>
  570. </div>
  571. <template v-if="isShow">
  572. <div
  573. ref="wordcard"
  574. class="NNPE-wordDetail"
  575. :style="{ top: top + 'px', left: left + 'px' }"
  576. >
  577. <Wordcard
  578. :word="word"
  579. :changeWordCard="changeWordCard"
  580. :themeColor="themeColor"
  581. :currentTreeID="currentTreeID"
  582. />
  583. </div>
  584. </template>
  585. <div class="word-play-audio" v-if="isWordPlay">
  586. <AudioLineSentence
  587. :mp3="mp3"
  588. :getCurTime="getCurWordTime"
  589. ref="audioLineWord"
  590. :audioId="'artPraAudioId' + curSentIndex + wordIndex"
  591. :stopAudio="stopAudio"
  592. :width="120"
  593. :hideSlider="false"
  594. :bg="wordbg"
  595. :ed="worded"
  596. :maxTime="wordMaxTime"
  597. :bgIndex="bgIndex"
  598. :isRepeat="isRepeat"
  599. :wordPlay="true"
  600. @changePlayStatus="changePlayStatus"
  601. />
  602. </div>
  603. </div>
  604. </template>
  605. <script>
  606. import AudioLineSentence from "./AudioLineSentence.vue";
  607. import Soundrecorddiff from "./Soundrecorddiff.vue";
  608. import AudioCompare from "./AudioCompare.vue";
  609. import Wordcard from "./components/Wordcard.vue";
  610. import { LearnWebSI } from "../../../api/ajax";
  611. export default {
  612. components: {
  613. AudioLineSentence,
  614. Soundrecorddiff,
  615. AudioCompare,
  616. Wordcard,
  617. },
  618. props: [
  619. "sentList",
  620. "sentIndex",
  621. "mp3",
  622. "wordTimeList",
  623. "curQue",
  624. "noFont",
  625. "themeColor",
  626. "NNPENewWordList",
  627. "currentTreeID",
  628. "config",
  629. "TaskModel",
  630. ],
  631. data() {
  632. return {
  633. pySize: 32,
  634. hzSize: 48,
  635. enSize: 24,
  636. bgIndex: 1,
  637. maxTime: 0,
  638. item: null,
  639. bg: 0,
  640. ed: 0,
  641. isRepeat: false,
  642. NumberList: [
  643. "①",
  644. "②",
  645. "③",
  646. "④",
  647. "⑤",
  648. "⑥",
  649. "⑦",
  650. "⑧",
  651. "⑨",
  652. "⑩",
  653. "⑪",
  654. "⑫",
  655. "⑬",
  656. "⑭",
  657. "⑮",
  658. "⑯",
  659. "⑰",
  660. "⑱",
  661. "⑲",
  662. "⑳",
  663. ],
  664. chsFhList: [",", "。", "”", ":", "》", "《", "?", "!", ";"],
  665. enFhList: [",", ".", ";", "?", "!", ":", ">", "<"],
  666. curTime: 0,
  667. wavblob: null,
  668. stopAudio: false,
  669. isRecord: false,
  670. isShowCompare: false,
  671. isShowRight: false,
  672. isShowLeft: false,
  673. curSentIndex: 0,
  674. oldHz: "",
  675. hz: "",
  676. clientY: 0,
  677. top: 0,
  678. left: 0,
  679. newWordList: [],
  680. pinyin: "",
  681. wordIndex: -1,
  682. isShow: false,
  683. wordbg: 0,
  684. worded: 0,
  685. wordMaxTime: 0,
  686. isWordPlay: false,
  687. curWordTime: 0,
  688. isPlaying: false,
  689. isAuto: false,
  690. key: "isRepeat",
  691. isKeyboard: true,
  692. isTopShow: false,
  693. isBottomShow: false,
  694. isRecording: false,
  695. recordPlaying: false,
  696. isCollArr: [],
  697. enwords: "",
  698. screenHeight: 0,
  699. };
  700. },
  701. computed: {
  702. // isPlaying: function () {
  703. // let playing = false;
  704. // if (this.$refs.audioLineSent) {
  705. // playing = this.$refs.audioLineSent.audio.isPlaying;
  706. // }
  707. // console.log(playing);
  708. // return playing;
  709. // },
  710. },
  711. watch: {
  712. isRecording: {
  713. handler: function (newVal, oldVal) {
  714. if (newVal) {
  715. this.isBottomShow = newVal;
  716. }
  717. },
  718. deep: true,
  719. },
  720. recordPlaying: {
  721. handler: function (newVal, oldVal) {
  722. if (newVal) {
  723. this.isBottomShow = newVal;
  724. }
  725. },
  726. deep: true,
  727. },
  728. sentIndex: {
  729. handler: function (newVal, oldVal) {
  730. this.curSentIndex = newVal;
  731. this.getSentence();
  732. },
  733. deep: true,
  734. },
  735. hz: {
  736. handler: function (val, oldVal) {
  737. let _this = this;
  738. if (val) {
  739. _this.handleNewWords(val);
  740. }
  741. },
  742. // 深度观察监听
  743. deep: true,
  744. },
  745. isShow: {
  746. handler: function (val, oldVal) {
  747. let _this = this;
  748. if (val) {
  749. setTimeout(() => {
  750. _this.cardHeight = _this.$refs.wordcard.offsetHeight;
  751. if (_this.screenHeight - _this.clientY > _this.cardHeight) {
  752. _this.top = _this.clientY + 20;
  753. } else {
  754. _this.top = _this.clientY - _this.cardHeight - 30;
  755. }
  756. }, 50);
  757. }
  758. },
  759. // 深度观察监听
  760. deep: true,
  761. },
  762. },
  763. //方法集合
  764. methods: {
  765. setTopShow(bool) {
  766. this.isTopShow = bool;
  767. },
  768. setBottomShow(bool) {
  769. if (!this.recordPlaying && !this.isRecording) {
  770. this.isBottomShow = bool;
  771. }
  772. },
  773. getPlayStatus(bool) {
  774. this.recordPlaying = bool;
  775. },
  776. setFontSize(type) {
  777. let _this = this;
  778. if (type == "-") {
  779. if (_this.hzSize >= 34) {
  780. this.hzSize = this.hzSize - 4;
  781. }
  782. }
  783. if (type == "+") {
  784. if (_this.hzSize <= 76) {
  785. this.hzSize = this.hzSize + 4;
  786. }
  787. }
  788. _this.pySize = parseInt(_this.hzSize / 1.5);
  789. _this.enSize = parseInt(_this.hzSize / 2);
  790. },
  791. playChange(bool) {
  792. this.isPlaying = bool;
  793. },
  794. handleColl() {
  795. let _this = this;
  796. if (_this.isCollArr[_this.curSentIndex]) {
  797. _this.cancleColl();
  798. } else {
  799. _this.addColl();
  800. }
  801. },
  802. //添加收藏
  803. addColl() {
  804. let Bookdetail = sessionStorage.getItem("Bookdetail");
  805. if (Bookdetail) {
  806. Bookdetail = JSON.parse(Bookdetail);
  807. let MethodName = "order-collection_manager-AddMyCollection";
  808. let text = "";
  809. this.item.forEach((item) => {
  810. if (item.chs != "#") {
  811. text += item.chs;
  812. }
  813. });
  814. let sentence_json = {
  815. item: JSON.stringify(this.item),
  816. bg: this.bg,
  817. ed: this.ed,
  818. mp3: this.mp3,
  819. pyPosition: this.curQue.pyPosition,
  820. };
  821. let data = {
  822. goods_id: this.currentTreeID,
  823. goods_type: 502,
  824. goods_name: Bookdetail.name,
  825. goods_person_name_desc: Bookdetail.description
  826. ? Bookdetail.description
  827. : "",
  828. goods_picture_id: Bookdetail.picture_id ? Bookdetail.picture_id : "",
  829. goods_price: Bookdetail.price,
  830. sentence: {
  831. sentence_text: text,
  832. sentence_json: JSON.stringify(sentence_json),
  833. },
  834. };
  835. LearnWebSI(MethodName, data).then((res) => {
  836. this.$set(this.isCollArr, this.curSentIndex, true);
  837. this.$message.success("收藏成功!");
  838. });
  839. } else {
  840. this.$message.warning("权限不足!");
  841. }
  842. },
  843. //取消收藏
  844. cancleColl() {
  845. let text = "";
  846. this.item.forEach((item) => {
  847. if (item.chs != "#") {
  848. text += item.chs;
  849. }
  850. });
  851. let MethodName = "order-collection_manager-CancelMyGoodsCollection_WS";
  852. let data = {
  853. goods_type: 502,
  854. goods_list: [
  855. {
  856. goods_id: this.currentTreeID, //课件的id
  857. sentence_text: text,
  858. },
  859. ],
  860. };
  861. LearnWebSI(MethodName, data).then((res) => {
  862. this.$set(this.isCollArr, this.curSentIndex, false);
  863. this.$message.success("取消成功!");
  864. });
  865. },
  866. //检查收藏状态
  867. checkCollStatus() {
  868. let text = "";
  869. this.item.forEach((item) => {
  870. if (item.chs != "#") {
  871. text += item.chs;
  872. }
  873. });
  874. let MethodName = "order-collection_manager-CheckMyGoodsCollectionStatus";
  875. let data = {
  876. goods_type: 502,
  877. goods_id: this.currentTreeID, //课件的id
  878. sentence_text: text,
  879. };
  880. LearnWebSI(MethodName, data).then((res) => {
  881. let collFlag = res.is_collection == "true" ? true : false;
  882. this.$set(this.isCollArr, this.curSentIndex, collFlag);
  883. });
  884. },
  885. showPrevNext(bool, key) {
  886. this[key] = bool;
  887. },
  888. prevSentence() {
  889. let _this = this;
  890. if (_this.curSentIndex == 0) {
  891. _this.$message.warning("已经是第一个句子了");
  892. return;
  893. }
  894. _this.curSentIndex = _this.curSentIndex - 1;
  895. _this.getSentence();
  896. if (_this.isAuto) {
  897. _this.curTime = _this.bg;
  898. _this.$refs.audioLineSent.onTimeupdateTime(_this.bg / 1000);
  899. }
  900. },
  901. nextSentence() {
  902. if (this.curSentIndex == this.sentList.length - 1) {
  903. this.$message.warning("已经是最后一个句子了");
  904. return;
  905. }
  906. this.curSentIndex = this.curSentIndex + 1;
  907. this.getSentence();
  908. },
  909. rollSentence() {
  910. if (this.curSentIndex == this.sentList.length - 1) {
  911. this.curSentIndex = 0;
  912. } else {
  913. this.curSentIndex = this.curSentIndex + 1;
  914. }
  915. this.getSentence();
  916. },
  917. changeStatus(key) {
  918. if (key == "config.isShowEN") {
  919. if (this.enwords) {
  920. this[key] = !this[key];
  921. }
  922. } else {
  923. this[key] = !this[key];
  924. }
  925. },
  926. changePinyin() {
  927. this.$emit("changePinyin");
  928. },
  929. changeEN() {
  930. this.$emit("changeEN");
  931. },
  932. setStatus() {
  933. let _this = this;
  934. if (_this.key == "isRepeat") {
  935. if (_this.isRepeat) {
  936. _this.isRepeat = false;
  937. _this.isAuto = true;
  938. _this.key = "isAuto";
  939. } else {
  940. _this.isRepeat = true;
  941. _this.key = "isRepeat";
  942. }
  943. } else if (_this.key == "isAuto") {
  944. if (_this.isAuto) {
  945. _this.isRepeat = false;
  946. _this.isAuto = false;
  947. _this.key = "isRepeat";
  948. }
  949. }
  950. },
  951. getRerordStatus(bool) {
  952. this.isShowCompare = bool;
  953. },
  954. getMicrophoneStatus(bool) {
  955. this.isRecording = bool;
  956. },
  957. getWavblob(wavblob) {
  958. this.wavblob = wavblob;
  959. },
  960. sentPause(isRecord) {
  961. this.isRecord = isRecord;
  962. },
  963. getCurTime(curTime) {
  964. let _this = this;
  965. if (_this.isRepeat) {
  966. let time = curTime * 1000;
  967. if (time > _this.ed || time < _this.bg) {
  968. _this.curTime = _this.bg;
  969. this.$refs.audioLineSent.onTimeupdateTime(_this.bg / 1000);
  970. } else {
  971. _this.curTime = curTime * 1000;
  972. }
  973. } else if (_this.isAuto) {
  974. let time = curTime * 1000;
  975. if (time > _this.ed) {
  976. _this.rollSentence();
  977. _this.curTime = _this.bg;
  978. _this.$refs.audioLineSent.onTimeupdateTime(_this.bg / 1000);
  979. } else {
  980. _this.curTime = curTime * 1000;
  981. }
  982. } else {
  983. _this.curTime = curTime * 1000;
  984. }
  985. },
  986. getCurCompareTime(curTime) {
  987. let _this = this;
  988. _this.curTime = curTime * 1000;
  989. },
  990. getCurWordTime(curTime) {
  991. let _this = this;
  992. _this.curWordTime = curTime * 1000;
  993. },
  994. changeBg(bgIndex) {
  995. this.bgIndex = bgIndex;
  996. },
  997. getSentence() {
  998. let _this = this;
  999. _this.isShowCompare =
  1000. _this.curQue.Bookanswer.practiceModel[_this.curSentIndex] &&
  1001. _this.curQue.Bookanswer.practiceModel[_this.curSentIndex].recordList &&
  1002. _this.curQue.Bookanswer.practiceModel[_this.curSentIndex].recordList
  1003. .length > 0;
  1004. _this.pauseAudio();
  1005. _this.isPlaying = false;
  1006. let item = JSON.parse(JSON.stringify(_this.sentList[_this.curSentIndex]));
  1007. if (item.sentArr) {
  1008. _this.item = item.sentArr;
  1009. _this.enwords = item.enwords;
  1010. } else {
  1011. _this.item = item;
  1012. }
  1013. _this.sentList.forEach((item) => {
  1014. this.isCollArr.push(false);
  1015. });
  1016. _this.bg = _this.curQue.wordTime[_this.curSentIndex].bg;
  1017. _this.ed = _this.curQue.wordTime[_this.curSentIndex].ed;
  1018. let maxTime = (_this.ed - _this.bg) / 1000;
  1019. if (maxTime < 1) {
  1020. _this.maxTime = 1;
  1021. } else {
  1022. _this.maxTime = maxTime;
  1023. }
  1024. _this.checkCollStatus();
  1025. },
  1026. pauseAudio() {
  1027. let audio = document.getElementsByTagName("audio");
  1028. audio.forEach((item) => {
  1029. item.pause();
  1030. });
  1031. },
  1032. exitFullScreen() {
  1033. this.pauseAudio();
  1034. this.$emit("exitFullscreen");
  1035. },
  1036. changeFullScreen() {
  1037. this.pauseAudio();
  1038. this.$emit("changeIsFull");
  1039. },
  1040. handleWav(list, tmIndex) {
  1041. tmIndex = tmIndex ? tmIndex : 0;
  1042. this.$emit("handleWav", list, tmIndex);
  1043. },
  1044. // 录音时暂停音频播放
  1045. handleParentPlay() {
  1046. this.stopAudio = true;
  1047. },
  1048. // 音频播放时改变布尔值
  1049. handleChangeStopAudio() {
  1050. this.stopAudio = false;
  1051. },
  1052. //播放音频
  1053. playWord(item) {
  1054. let _this = this;
  1055. _this.pauseAudio();
  1056. _this.isWordPlay = false;
  1057. _this.wordIndex = item.wordIndex;
  1058. setTimeout(() => {
  1059. let leg = item.timeList.length;
  1060. _this.wordbg = item.timeList[0].wordBg;
  1061. _this.worded = item.timeList[leg - 1].wordEd;
  1062. let wordMaxTime = (_this.worded - _this.wordbg) / 1000;
  1063. if (wordMaxTime < 1) {
  1064. _this.wordMaxTime = 1;
  1065. } else {
  1066. _this.wordMaxTime = wordMaxTime;
  1067. }
  1068. _this.isWordPlay = true;
  1069. }, 50);
  1070. },
  1071. changePlayStatus() {
  1072. this.isWordPlay = false;
  1073. this.wordIndex = -1;
  1074. },
  1075. showWordDetail(e, item) {
  1076. let _this = this;
  1077. if (_this.TaskModel == "ANSWER") {
  1078. return;
  1079. }
  1080. if (_this.chsFhList.indexOf(item.chs) > -1) {
  1081. return;
  1082. }
  1083. if (_this.oldHz != item.chs) {
  1084. this.isShow = false;
  1085. setTimeout(() => {
  1086. _this.hz = item.chs;
  1087. _this.pinyin = item.pinyin;
  1088. _this.wordIndex = item.wordIndex;
  1089. }, 50);
  1090. }
  1091. _this.clientY = e.clientY;
  1092. let left = e.clientX;
  1093. let width = 0;
  1094. if (item.chs.length == 1 || item.chs.length == 2) {
  1095. width = 304;
  1096. } else if (item.chs.length == 3 || item.chs.length == 4) {
  1097. width = 432;
  1098. } else if (item.chs.length > 3) {
  1099. width = 560;
  1100. }
  1101. // if (left - this.bodyLeft > this.contentWidth / 2) {
  1102. // _this.left = left - width + 10;
  1103. // } else {
  1104. _this.left = left - width / 2;
  1105. //}
  1106. },
  1107. changeWordCard(isShow) {
  1108. let _this = this;
  1109. _this.isShow = isShow;
  1110. _this.oldHz = "";
  1111. _this.hz = "";
  1112. _this.wordIndex = -1;
  1113. },
  1114. // 处理分词数据
  1115. handleNewWords(val) {
  1116. let _this = this;
  1117. _this.isShow = true;
  1118. _this.word = null;
  1119. if (_this.newWordList.indexOf(val) > -1) {
  1120. for (let i = 0; i < this.NNPENewWordList.length; i++) {
  1121. let pItem = this.NNPENewWordList[i];
  1122. for (let j = 0; j < pItem.length; j++) {
  1123. let item = pItem[j];
  1124. if (item.new_word.trim() == val.trim()) {
  1125. let wordlist = val.split("");
  1126. this.word = { list: wordlist, detail: item };
  1127. break;
  1128. }
  1129. }
  1130. }
  1131. } else {
  1132. let wordlist = val.split("");
  1133. let option = {
  1134. definition_list: [],
  1135. mp3_list: [],
  1136. new_word: val,
  1137. pinyin: _this.pinyin,
  1138. };
  1139. _this.word = { list: wordlist, detail: option };
  1140. }
  1141. _this.oldHz = val;
  1142. },
  1143. handleNewword() {
  1144. let NewWordList = [];
  1145. this.NNPENewWordList.forEach((item) => {
  1146. item.forEach((wItem) => {
  1147. NewWordList.push(wItem.new_word);
  1148. });
  1149. });
  1150. this.newWordList = JSON.parse(JSON.stringify(NewWordList));
  1151. },
  1152. getScreenHeight() {
  1153. this.screenHeight = window.innerHeight;
  1154. },
  1155. },
  1156. //生命周期 - 创建完成(可以访问当前this实例)
  1157. created() {
  1158. let _this = this;
  1159. },
  1160. //生命周期 - 挂载完成(可以访问DOM元素)
  1161. mounted() {
  1162. let _this = this;
  1163. $(window).resize(() => {
  1164. _this.getScreenHeight();
  1165. });
  1166. _this.getScreenHeight();
  1167. document.addEventListener("keyup", function (e) {
  1168. if (_this.isKeyboard) {
  1169. if (e.keyCode == 32) {
  1170. //空格
  1171. _this.$nextTick(() => {
  1172. if (_this.$refs.audioLineSent) {
  1173. _this.$refs.audioLineSent.PlayAudio();
  1174. }
  1175. });
  1176. } else if (e.keyCode == 38) {
  1177. _this.prevSentence();
  1178. } else if (e.keyCode == 40) {
  1179. _this.nextSentence();
  1180. } else if (e.keyCode == 13) {
  1181. _this.$nextTick(() => {
  1182. _this.$refs.Soundrecorddiff.microphone();
  1183. });
  1184. }
  1185. }
  1186. });
  1187. if (_this.NNPENewWordList) {
  1188. _this.handleNewword();
  1189. }
  1190. _this.curSentIndex = _this.sentIndex;
  1191. _this.getSentence();
  1192. let isFullscreen =
  1193. document.fullscreenElement ||
  1194. document.mozFullScreenElement ||
  1195. document.webkitFullscreenElement ||
  1196. document.fullScreen ||
  1197. document.mozFullScreen ||
  1198. document.webkitIsFullScreen;
  1199. isFullscreen = !!isFullscreen;
  1200. document.addEventListener("fullscreenchange", () => {
  1201. let isFullscreen =
  1202. document.fullscreenElement ||
  1203. document.mozFullScreenElement ||
  1204. document.webkitFullscreenElement ||
  1205. document.fullScreen ||
  1206. document.mozFullScreen ||
  1207. document.webkitIsFullScreen;
  1208. if (!isFullscreen) {
  1209. _this.changeFullScreen();
  1210. }
  1211. });
  1212. document.addEventListener("mozfullscreenchange", () => {
  1213. let isFullscreen =
  1214. document.fullscreenElement ||
  1215. document.mozFullScreenElement ||
  1216. document.webkitFullscreenElement ||
  1217. document.fullScreen ||
  1218. document.mozFullScreen ||
  1219. document.webkitIsFullScreen;
  1220. if (!isFullscreen) {
  1221. _this.changeFullScreen();
  1222. }
  1223. });
  1224. document.addEventListener("webkitfullscreenchange", () => {
  1225. let isFullscreen =
  1226. document.fullscreenElement ||
  1227. document.mozFullScreenElement ||
  1228. document.webkitFullscreenElement ||
  1229. document.fullScreen ||
  1230. document.mozFullScreen ||
  1231. document.webkitIsFullScreen;
  1232. if (!isFullscreen) {
  1233. _this.changeFullScreen();
  1234. }
  1235. });
  1236. document.addEventListener("msfullscreenchange", () => {
  1237. let isFullscreen =
  1238. document.fullscreenElement ||
  1239. document.mozFullScreenElement ||
  1240. document.webkitFullscreenElement ||
  1241. document.fullScreen ||
  1242. document.mozFullScreen ||
  1243. document.webkitIsFullScreen;
  1244. if (!isFullscreen) {
  1245. _this.changeFullScreen();
  1246. }
  1247. });
  1248. },
  1249. beforeCreate() {}, //生命周期 - 创建之前
  1250. beforeMount() {}, //生命周期 - 挂载之前
  1251. beforeUpdate() {}, //生命周期 - 更新之前
  1252. updated() {}, //生命周期 - 更新之后
  1253. beforeDestroy() {}, //生命周期 - 销毁之前
  1254. destroyed() {}, //生命周期 - 销毁完成
  1255. activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
  1256. };
  1257. </script>
  1258. <style lang='scss' scoped>
  1259. //@import url(); 引入公共css类
  1260. .voicefull {
  1261. width: 100%;
  1262. height: 100vh;
  1263. overflow: hidden;
  1264. display: flex;
  1265. flex-direction: column;
  1266. .NNPE-wordDetail {
  1267. position: fixed;
  1268. z-index: 9999;
  1269. }
  1270. &.bg1 {
  1271. background: #fff;
  1272. }
  1273. &.bg2 {
  1274. background: linear-gradient(180deg, #274533 0%, #385f45 100%);
  1275. }
  1276. &-top {
  1277. height: 136px;
  1278. width: 100%;
  1279. box-sizing: border-box;
  1280. padding: 0 40px;
  1281. .voicefull-top-hidden {
  1282. width: 100%;
  1283. height: 136px;
  1284. visibility: hidden;
  1285. display: flex;
  1286. justify-content: space-between;
  1287. align-items: center;
  1288. }
  1289. .voicefull-top-show {
  1290. width: 100%;
  1291. height: 136px;
  1292. visibility: visible;
  1293. display: flex;
  1294. justify-content: space-between;
  1295. align-items: center;
  1296. }
  1297. .top-left {
  1298. display: flex;
  1299. justify-content: flex-start;
  1300. align-items: center;
  1301. }
  1302. .select-bg {
  1303. display: flex;
  1304. justify-content: space-between;
  1305. align-items: center;
  1306. width: 96px;
  1307. height: 56px;
  1308. border: 1px solid rgba(0, 0, 0, 0.1);
  1309. border-radius: 40px;
  1310. display: flex;
  1311. justify-content: center;
  1312. align-items: center;
  1313. box-sizing: border-box;
  1314. margin-right: 32px;
  1315. &.select-bg-blue {
  1316. background: rgba(255, 255, 255, 0.1);
  1317. border: 1px solid rgba(0, 0, 0, 0.1);
  1318. }
  1319. > div {
  1320. width: 36px;
  1321. height: 36px;
  1322. border-radius: 100%;
  1323. display: flex;
  1324. justify-content: center;
  1325. align-items: center;
  1326. &.bg-white-box {
  1327. background: 0 0;
  1328. margin-right: 4px;
  1329. &.active {
  1330. background: #de4444;
  1331. }
  1332. }
  1333. &.bg-green-box {
  1334. background: #fff;
  1335. &.active {
  1336. background: #ffc600;
  1337. }
  1338. }
  1339. > span {
  1340. width: 24px;
  1341. height: 24px;
  1342. border-radius: 100%;
  1343. box-sizing: border-box;
  1344. cursor: pointer;
  1345. &.bg-white {
  1346. background: #fff;
  1347. }
  1348. &.bg-green {
  1349. background: linear-gradient(180deg, #274533 0%, #385f45 100%);
  1350. }
  1351. }
  1352. }
  1353. }
  1354. .set-fontSize {
  1355. padding: 0 20px;
  1356. height: 56px;
  1357. background: #ffffff;
  1358. border: 1px solid rgba(0, 0, 0, 0.1);
  1359. border-radius: 40px;
  1360. display: flex;
  1361. justify-content: center;
  1362. align-items: center;
  1363. &-green {
  1364. background: rgba(255, 255, 255, 0.1);
  1365. border: 1px solid rgba(0, 0, 0, 0.1);
  1366. }
  1367. > span {
  1368. width: 24px;
  1369. height: 24px;
  1370. margin: 0 4px;
  1371. &.font-jian {
  1372. &-black {
  1373. background: url("../../../assets/NPC/jian-black.png") no-repeat left
  1374. top;
  1375. background-size: 100% 100%;
  1376. cursor: pointer;
  1377. }
  1378. &-yellow {
  1379. background: url("../../../assets/NPC/jian-white.png") no-repeat left
  1380. top;
  1381. background-size: 100% 100%;
  1382. cursor: pointer;
  1383. }
  1384. &-white-disabled {
  1385. background: url("../../../assets/NPC/jian-white-disabled.png")
  1386. no-repeat left top;
  1387. background-size: 100% 100%;
  1388. cursor: pointer;
  1389. }
  1390. &-yellow-disabled {
  1391. background: url("../../../assets/NPC/jian-yellow-disabled.png")
  1392. no-repeat left top;
  1393. background-size: 100% 100%;
  1394. cursor: pointer;
  1395. }
  1396. }
  1397. &.font-img {
  1398. &-black {
  1399. background: url("../../../assets/NPC/fontSize-black.png") no-repeat
  1400. left top;
  1401. background-size: 100% 100%;
  1402. }
  1403. &-yellow {
  1404. background: url("../../../assets/NPC/fontSize-white.png") no-repeat
  1405. left top;
  1406. background-size: 100% 100%;
  1407. }
  1408. }
  1409. &.font-jia {
  1410. &-black {
  1411. background: url("../../../assets/NPC/jia-black.png") no-repeat left
  1412. top;
  1413. background-size: 100% 100%;
  1414. cursor: pointer;
  1415. }
  1416. &-yellow {
  1417. background: url("../../../assets/NPC/jia-white.png") no-repeat left
  1418. top;
  1419. background-size: 100% 100%;
  1420. cursor: pointer;
  1421. }
  1422. &-white-disabled {
  1423. background: url("../../../assets/NPC/jia-white-disabled.png")
  1424. no-repeat left top;
  1425. background-size: 100% 100%;
  1426. cursor: pointer;
  1427. }
  1428. &-yellow-disabled {
  1429. background: url("../../../assets/NPC/jia-yellow-disabled.png")
  1430. no-repeat left top;
  1431. background-size: 100% 100%;
  1432. cursor: pointer;
  1433. }
  1434. }
  1435. }
  1436. }
  1437. .top-middle {
  1438. display: flex;
  1439. justify-content: center;
  1440. align-items: center;
  1441. .audio-box {
  1442. width: 56px;
  1443. height: 56px;
  1444. background: #ffffff;
  1445. border: 1px solid rgba(0, 0, 0, 0.1);
  1446. border-radius: 40px;
  1447. display: flex;
  1448. justify-content: center;
  1449. align-items: center;
  1450. &-green {
  1451. background: rgba(255, 255, 255, 0.1);
  1452. border: 1px solid rgba(0, 0, 0, 0.1);
  1453. }
  1454. }
  1455. }
  1456. }
  1457. .op-btn {
  1458. width: 56px;
  1459. height: 56px;
  1460. border-radius: 100%;
  1461. display: flex;
  1462. justify-content: center;
  1463. align-items: center;
  1464. cursor: pointer;
  1465. margin-left: 32px;
  1466. background: #ffffff;
  1467. border: 1px solid rgba(0, 0, 0, 0.1);
  1468. box-sizing: border-box;
  1469. &-green {
  1470. background: rgba(255, 255, 255, 0.1);
  1471. border: 1px solid rgba(0, 0, 0, 0.1);
  1472. }
  1473. &.close-btn {
  1474. background: #274533;
  1475. border: 1px solid rgba(0, 0, 0, 0.1);
  1476. }
  1477. > span {
  1478. width: 24px;
  1479. height: 24px;
  1480. &.close-icon {
  1481. background: url("../../../assets/icon/cross-24-normal-black.png")
  1482. no-repeat left top;
  1483. background-size: 100% 100%;
  1484. &-white {
  1485. background: url("../../../assets/icon/cross-24-normal-white.png")
  1486. no-repeat left top;
  1487. background-size: 100% 100%;
  1488. }
  1489. }
  1490. }
  1491. }
  1492. .repeat-icon {
  1493. background: url("../../../assets/icon/Repeat-24-normal-red.png") no-repeat
  1494. left top;
  1495. background-size: 100% 100%;
  1496. &.disabled {
  1497. background: url("../../../assets/icon/Repeat-24-disable-Black.png")
  1498. no-repeat left top;
  1499. background-size: 100% 100%;
  1500. }
  1501. &-yellow {
  1502. background: url("../../../assets/icon/Repeat-24-normal-yellow.png")
  1503. no-repeat left top;
  1504. background-size: 100% 100%;
  1505. }
  1506. &.auto-icon {
  1507. background: url("../../../assets/icon/Auto-24-next-red.png") no-repeat
  1508. left top;
  1509. background-size: 100% 100%;
  1510. &-yellow {
  1511. background: url("../../../assets/icon/Auto-24-next-yellow.png")
  1512. no-repeat left top;
  1513. background-size: 100% 100%;
  1514. }
  1515. }
  1516. }
  1517. .pinyin-icon {
  1518. background: url("../../../assets/icon/pinyin-24-normal-red.png") no-repeat
  1519. left top;
  1520. background-size: 100% 100%;
  1521. &.disabled {
  1522. background: url("../../../assets/icon/pinyin-24-disable-Black.png")
  1523. no-repeat left top;
  1524. background-size: 100% 100%;
  1525. }
  1526. &-yellow {
  1527. background: url("../../../assets/icon/pinyin-24-normal-yellow.png")
  1528. no-repeat left top;
  1529. background-size: 100% 100%;
  1530. }
  1531. }
  1532. .en-icon {
  1533. background: url("../../../assets/icon/EN-24-normal-Red.png") no-repeat left
  1534. top;
  1535. background-size: 100% 100%;
  1536. &.disabled {
  1537. background: url("../../../assets/icon/EN-24-disable-Black.png") no-repeat
  1538. left top;
  1539. background-size: 100% 100%;
  1540. }
  1541. &-yellow {
  1542. background: url("../../../assets/icon/EN-24-normal-yellow.png") no-repeat
  1543. left top;
  1544. background-size: 100% 100%;
  1545. }
  1546. }
  1547. .coll-icon {
  1548. background: url("../../../assets/icon/bookmarkfill-24-normal-red.png")
  1549. no-repeat left top;
  1550. background-size: 100% 100%;
  1551. &.disabled {
  1552. background: url("../../../assets/icon/bookmarkfill-24-disable-Black.png")
  1553. no-repeat left top;
  1554. background-size: 100% 100%;
  1555. }
  1556. &-yellow {
  1557. background: url("../../../assets/icon/bookmarkfill-24-normal-yellow.png")
  1558. no-repeat left top;
  1559. background-size: 100% 100%;
  1560. }
  1561. }
  1562. .keyboard-icon {
  1563. background: url("../../../assets/icon/enter-24-keyboard-red.png") no-repeat
  1564. left top;
  1565. background-size: 100% 100%;
  1566. &.disabled {
  1567. background: url("../../../assets/icon/enter-24-keyboard-disable-Black.png")
  1568. no-repeat left top;
  1569. background-size: 100% 100%;
  1570. }
  1571. &-yellow {
  1572. background: url("../../../assets/icon/enter-24-keyboard-yellow.png")
  1573. no-repeat left top;
  1574. background-size: 100% 100%;
  1575. }
  1576. }
  1577. &-content {
  1578. flex: 1;
  1579. width: 100%;
  1580. box-sizing: border-box;
  1581. display: flex;
  1582. align-items: center;
  1583. .vc-box {
  1584. padding: 0 8px 0 36px;
  1585. &-right {
  1586. padding: 0 36px 0 8px;
  1587. }
  1588. }
  1589. .vc-left {
  1590. width: 64px;
  1591. height: 64px;
  1592. cursor: pointer;
  1593. &-grey {
  1594. background: url("../../../assets/NPC/left-grey.png") no-repeat left top;
  1595. background-size: 100% 100%;
  1596. }
  1597. &-black {
  1598. background: url("../../../assets/NPC/left-black.png") no-repeat left top;
  1599. background-size: 100% 100%;
  1600. }
  1601. &-white {
  1602. background: url("../../../assets/NPC/left-white.png") no-repeat left top;
  1603. background-size: 100% 100%;
  1604. }
  1605. &.hidden {
  1606. visibility: hidden;
  1607. }
  1608. }
  1609. .vc-right {
  1610. width: 64px;
  1611. height: 64px;
  1612. cursor: pointer;
  1613. &-grey {
  1614. background: url("../../../assets/NPC/right-grey.png") no-repeat left top;
  1615. background-size: 100% 100%;
  1616. }
  1617. &-black {
  1618. background: url("../../../assets/NPC/right-black.png") no-repeat left
  1619. top;
  1620. background-size: 100% 100%;
  1621. }
  1622. &-white {
  1623. background: url("../../../assets/NPC/right-white.png") no-repeat left
  1624. top;
  1625. background-size: 100% 100%;
  1626. }
  1627. }
  1628. .vc-main {
  1629. width: fit-content;
  1630. margin: 0 auto;
  1631. padding: 0 67px;
  1632. .enwords {
  1633. padding: 0 3px;
  1634. margin-top: 24px;
  1635. color: rgba(0, 0, 0, 0.45);
  1636. font-size: 24px;
  1637. line-height: 32px;
  1638. font-family: "robot";
  1639. &-green {
  1640. color: rgba(255, 255, 255, 0.65);
  1641. }
  1642. }
  1643. }
  1644. .NNPE-words {
  1645. float: left;
  1646. user-select: none;
  1647. -webkit-user-select: none;
  1648. -moz-user-select: none;
  1649. -ms-user-select: none;
  1650. &-box {
  1651. float: left;
  1652. > span {
  1653. display: block;
  1654. &.NNPE-pinyin {
  1655. font-family: "GB-PINYINOK-B";
  1656. font-weight: normal;
  1657. font-size: 32px;
  1658. line-height: 1.25;
  1659. box-sizing: border-box;
  1660. color: rgba(0, 0, 0, 0.85);
  1661. &.bottom {
  1662. padding-bottom: 16px;
  1663. }
  1664. &.noFont {
  1665. font-family: initial;
  1666. }
  1667. &.textLeft {
  1668. text-align: left;
  1669. }
  1670. &.font-white {
  1671. color: #fff;
  1672. }
  1673. &.wordBlank {
  1674. color: rgba(0, 0, 0, 0.85);
  1675. }
  1676. }
  1677. &.NNPE-chs {
  1678. font-family: "FZJCGFKTK";
  1679. font-size: 48px;
  1680. line-height: 1.17;
  1681. color: rgba(0, 0, 0, 0.85);
  1682. &.bottom {
  1683. padding-bottom: 16px;
  1684. }
  1685. .font-white {
  1686. color: #fff;
  1687. }
  1688. .active {
  1689. color: #de4444;
  1690. &-yellow {
  1691. color: #ffc600;
  1692. }
  1693. }
  1694. .wordActive {
  1695. color: #de4444;
  1696. }
  1697. .wordActive-blue {
  1698. color: #ffc600;
  1699. }
  1700. }
  1701. // &.padding {
  1702. // padding-right: 6px;
  1703. // }
  1704. }
  1705. }
  1706. &.textLeft {
  1707. text-align: left;
  1708. }
  1709. &.textCenter {
  1710. text-align: center;
  1711. }
  1712. &.textRight {
  1713. text-align: right;
  1714. }
  1715. > span {
  1716. display: block;
  1717. &.NNPE-pinyin {
  1718. font-family: "GB-PINYINOK-B";
  1719. font-weight: normal;
  1720. font-size: 32px;
  1721. line-height: 1.25;
  1722. box-sizing: border-box;
  1723. color: rgba(0, 0, 0, 0.85);
  1724. &.bottom {
  1725. padding-bottom: 16px;
  1726. }
  1727. &.font-white {
  1728. color: #fff;
  1729. }
  1730. &.noFont {
  1731. font-family: initial;
  1732. }
  1733. &.textLeft {
  1734. text-align: left;
  1735. }
  1736. &.wordBlank {
  1737. color: rgba(0, 0, 0, 0.85);
  1738. }
  1739. }
  1740. &.NNPE-chs {
  1741. font-family: "FZJCGFKTK";
  1742. font-size: 48px;
  1743. line-height: 1.17;
  1744. color: rgba(0, 0, 0, 0.85);
  1745. &.bottom {
  1746. padding-bottom: 16px;
  1747. }
  1748. .font-white {
  1749. color: #fff;
  1750. }
  1751. .active {
  1752. color: #de4444;
  1753. &-yellow {
  1754. color: #ffc600;
  1755. }
  1756. }
  1757. .wordActive {
  1758. color: #de4444;
  1759. }
  1760. .wordActive-blue {
  1761. color: #ffc600;
  1762. }
  1763. }
  1764. &.padding {
  1765. padding-left: 3px;
  1766. padding-right: 3px;
  1767. }
  1768. }
  1769. }
  1770. }
  1771. &-bottom {
  1772. height: 136px;
  1773. width: 100%;
  1774. box-sizing: border-box;
  1775. display: flex;
  1776. justify-content: space-between;
  1777. align-items: center;
  1778. padding-right: 40px;
  1779. .voicefull-bottom-show {
  1780. height: 136px;
  1781. width: 100%;
  1782. display: flex;
  1783. justify-content: space-between;
  1784. align-items: center;
  1785. visibility: visible;
  1786. }
  1787. .voicefull-bottom-hidden {
  1788. height: 136px;
  1789. width: 100%;
  1790. display: flex;
  1791. justify-content: space-between;
  1792. align-items: center;
  1793. visibility: hidden;
  1794. }
  1795. .bottom-left {
  1796. display: flex;
  1797. justify-content: flex-start;
  1798. align-items: center;
  1799. &-margin {
  1800. margin-left: 40px;
  1801. }
  1802. .compare-box {
  1803. height: 56px;
  1804. padding: 16px 16px;
  1805. box-sizing: border-box;
  1806. border: 1px solid rgba(0, 0, 0, 0.1);
  1807. border-radius: 0 40px 40px 0;
  1808. border-left: 0px solid rgba(0, 0, 0, 0.1);
  1809. &-white {
  1810. background: rgba(255, 255, 255, 0.1);
  1811. border: 1px solid rgba(0, 0, 0, 0.1);
  1812. border-left: 0;
  1813. }
  1814. &-answer {
  1815. border-radius: 40px;
  1816. }
  1817. }
  1818. }
  1819. .page-count {
  1820. padding: 8px;
  1821. font-size: 16px;
  1822. line-height: 24px;
  1823. font-family: "robot";
  1824. color: #000000;
  1825. min-width: 60px;
  1826. box-sizing: border-box;
  1827. border-radius: 8px;
  1828. background: #fff;
  1829. text-align: center;
  1830. &-green {
  1831. color: #ffffff;
  1832. background: rgba(255, 255, 255, 0.2);
  1833. }
  1834. }
  1835. }
  1836. }
  1837. .word-play-audio {
  1838. position: absolute;
  1839. left: -1000px;
  1840. }
  1841. </style>
  1842. <style lang="scss">
  1843. .NPC-Big-Book-preview-green {
  1844. .bg1 {
  1845. .repeat-icon {
  1846. background: url("../../../assets/icon/Repeat-24-normal-Green.png")
  1847. no-repeat left top;
  1848. background-size: 100% 100%;
  1849. }
  1850. .pinyin-icon {
  1851. background: url("../../../assets/icon/pinyin-24-normal-green.png")
  1852. no-repeat left top;
  1853. background-size: 100% 100%;
  1854. }
  1855. .en-icon {
  1856. background: url("../../../assets/icon/EN-24-normal-Green.png") no-repeat
  1857. left top;
  1858. background-size: 100% 100%;
  1859. }
  1860. .coll-icon {
  1861. background: url("../../../assets/icon/bookmarkfill-24-normal-green.png")
  1862. no-repeat left top;
  1863. background-size: 100% 100%;
  1864. }
  1865. }
  1866. }
  1867. .NPC-Big-Book-preview-brown {
  1868. .bg1 {
  1869. .repeat-icon {
  1870. background: url("../../../assets/icon/Repeat-24-normal-Brown.png")
  1871. no-repeat left top;
  1872. background-size: 100% 100%;
  1873. }
  1874. .pinyin-icon {
  1875. background: url("../../../assets/icon/pinyin-24-normal-brown.png")
  1876. no-repeat left top;
  1877. background-size: 100% 100%;
  1878. }
  1879. .en-icon {
  1880. background: url("../../../assets/icon/EN-24-normal-Brown.png") no-repeat
  1881. left top;
  1882. background-size: 100% 100%;
  1883. }
  1884. .coll-icon {
  1885. background: url("../../../assets/icon/bookmarkfill-24-normal-brown.png")
  1886. no-repeat left top;
  1887. background-size: 100% 100%;
  1888. }
  1889. }
  1890. }
  1891. </style>