CharacterPreview.vue 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884
  1. <!-- eslint-disable vue/no-v-html -->
  2. <template>
  3. <div class="character-preview" :style="[getAreaStyle(), getComponentStyle()]">
  4. <SerialNumberPosition v-if="isEnable(data.property.sn_display_mode)" :property="data.property" />
  5. <div class="main">
  6. <template v-if="data.property.model === 'write'">
  7. <div
  8. v-for="(item, index) in data.option_list"
  9. :key="index"
  10. class="item-box"
  11. :class="[!item.is_margin ? 'item-box-write' : '']"
  12. >
  13. <div
  14. class="number-box"
  15. :style="{
  16. marginTop: isEnable(data.property.view_pinyin) ? '30px' : '',
  17. }"
  18. >
  19. <span
  20. class="number"
  21. :style="{
  22. background:
  23. data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : '',
  24. }"
  25. >{{ index + 1 }}</span
  26. >
  27. </div>
  28. <div class="pinyin-en" :class="[item.is_example ? 'item-example' : '']">
  29. <div
  30. v-if="isEnable(data.property.view_pinyin) && item.is_common_pinyin"
  31. class="pinyin"
  32. :style="{
  33. fontSize: data.unified_attrib && data.unified_attrib.pinyin_size ? data.unified_attrib.pinyin_size : '',
  34. }"
  35. >
  36. {{ item.pinyin }}
  37. </div>
  38. <div class="items-flex">
  39. <div v-for="(items, indexs) in item.content_list" :key="indexs" class="items">
  40. <div
  41. v-if="isEnable(data.property.view_pinyin) && !item.is_common_pinyin"
  42. class="pinyin"
  43. :style="{
  44. fontSize:
  45. data.unified_attrib && data.unified_attrib.pinyin_size ? data.unified_attrib.pinyin_size : '',
  46. }"
  47. >
  48. {{ items.pinyin }}
  49. </div>
  50. <div class="items-content">
  51. <template v-if="items && items.type === 'img'">
  52. <el-image
  53. v-if="items.file_list[0]"
  54. class="items-image"
  55. :src="items.file_list[0].file_url"
  56. fit="contain"
  57. />
  58. </template>
  59. <template v-else-if="items && items.type === 'lian'">
  60. <span
  61. class="items-lian"
  62. :style="{
  63. color:
  64. data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : '',
  65. }"
  66. >{{ items.con }}</span
  67. >
  68. </template>
  69. <Strockplayredline
  70. v-if="items && items.type === 'hanzi'"
  71. :Book_text="items.con"
  72. :play-storkes="isEnable(data.property.is_enable_play_structure)"
  73. :cur-item="
  74. isEnable(data.property.is_enable_high_strokes)
  75. ? data.property.model === 'input'
  76. ? items.high_strokes
  77. : userAnswer[index].item[indexs]
  78. : null
  79. "
  80. :type="data.property.model === 'input' ? 'newWord-template-input' : data.type"
  81. :target-div="'newWordTemplate-character' + items.con + index + indexs + randomId"
  82. :hz_json="items.hz_info[0].hzDetail.hz_json"
  83. :bg-type="data.property.frame_type"
  84. class="hanzi-storck"
  85. :class="[
  86. !item.is_margin && item.content_list.length > 1 && indexs == 0 ? 'leftBorderRadius' : '',
  87. !item.is_margin && item.content_list.length > 1 && indexs == item.content_list.length - 1
  88. ? 'rightBorderRadius'
  89. : '',
  90. !item.is_margin &&
  91. item.content_list.length > 1 &&
  92. indexs != item.content_list.length - 1 &&
  93. indexs != 0
  94. ? 'NoborderRadius'
  95. : '',
  96. !item.is_margin &&
  97. item.content_list.length > 1 &&
  98. indexs != item.content_list.length - 1 &&
  99. item.content_list[indexs + 1].type !== 'lian'
  100. ? 'NoborderRight'
  101. : '',
  102. ]"
  103. :play-color="
  104. data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : ''
  105. "
  106. :style="{
  107. borderColor:
  108. data.unified_attrib && data.unified_attrib.topic_color
  109. ? data.unified_attrib.topic_color
  110. : '#346cda',
  111. }"
  112. />
  113. <div
  114. v-if="items && items.type === 'write'"
  115. :class="[
  116. 'strockplay-newWord',
  117. !item.is_margin && item.content_list.length > 1 && indexs == 0 ? 'leftBorderRadius' : '',
  118. !item.is_margin && item.content_list.length > 1 && indexs == item.content_list.length - 1
  119. ? 'rightBorderRadius'
  120. : '',
  121. !item.is_margin &&
  122. item.content_list.length > 1 &&
  123. indexs != item.content_list.length - 1 &&
  124. indexs != 0
  125. ? 'NoborderRadius'
  126. : '',
  127. !item.is_margin &&
  128. item.content_list.length > 1 &&
  129. indexs != item.content_list.length - 1 &&
  130. item.content_list[indexs + 1].type !== 'lian'
  131. ? 'NoborderRight'
  132. : '',
  133. ]"
  134. :style="{
  135. borderColor:
  136. data.unified_attrib && data.unified_attrib.topic_color
  137. ? data.unified_attrib.topic_color
  138. : '#346cda',
  139. }"
  140. @click="
  141. freeWrite(
  142. userAnswer[index][indexs].imgArr ? userAnswer[index][indexs].imgArr : null,
  143. index,
  144. indexs,
  145. )
  146. "
  147. >
  148. <SvgIcon
  149. v-if="data.property.frame_type === 'tian'"
  150. icon-class="hanzi-writer-bg"
  151. class="character-target-bg"
  152. />
  153. <SvgIcon
  154. v-else-if="data.property.frame_type === 'mi'"
  155. icon-class="mi"
  156. class="character-target-bg"
  157. />
  158. <img
  159. v-if="
  160. !play_status &&
  161. userAnswer[index][indexs].imgArr &&
  162. userAnswer[index][indexs].imgArr.strokes_image
  163. "
  164. class="hanzi-writer-img"
  165. :src="userAnswer[index][indexs].imgArr.strokes_image"
  166. alt=""
  167. />
  168. </div>
  169. </div>
  170. </div>
  171. </div>
  172. <div class="en-common">{{ convertText(item.shiyi) }}</div>
  173. </div>
  174. </div>
  175. </template>
  176. <template v-else>
  177. <div :class="['words-box']">
  178. <div v-for="(item, index) in data.option_list" :key="index" :class="['words-item']">
  179. <div class="words-top">
  180. <div class="words-left" :style="{}">
  181. <AudioPlay
  182. v-if="isEnable(data.property.is_enable_voice)"
  183. :file-id="item.audio_file_id ? item.audio_file_id.file_url : ''"
  184. :theme-color="
  185. data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : ''
  186. "
  187. />
  188. <span
  189. v-if="isEnable(data.property.view_pinyin) && item.is_common_pinyin"
  190. class="pinyin"
  191. :style="{
  192. fontSize:
  193. data.unified_attrib && data.unified_attrib.pinyin_size ? data.unified_attrib.pinyin_size : '',
  194. }"
  195. >{{ item.pinyin }}</span
  196. >
  197. </div>
  198. </div>
  199. <div class="card-box">
  200. <!-- 描红 -->
  201. <template v-for="(items, indexs) in item.content_list">
  202. <div v-if="item.is_show_ben" :key="'miao' + indexs">
  203. <!-- <div v-if="isEnable(data.property.view_pinyin) && !item.is_common_pinyin" class="pinyin">
  204. {{ items.pinyin }}
  205. </div> -->
  206. <Strockplayredline
  207. :Book_text="items.con"
  208. :play-storkes="isEnable(data.property.is_enable_stroke)"
  209. :cur-item="null"
  210. :target-div="'newWordTemplate-character-answer' + items.con + index + indexs + randomId"
  211. :hz_json="
  212. items.hz_info && items.hz_info[0].hzDetail.hz_json ? items.hz_info[0].hzDetail.hz_json : []
  213. "
  214. class="hanzi-storck"
  215. :class="['strock-chinese', 'border-right-none']"
  216. :bg-type="data.property.frame_type"
  217. :play-color="
  218. data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : ''
  219. "
  220. :style="{
  221. borderColor:
  222. data.unified_attrib && data.unified_attrib.topic_color
  223. ? data.unified_attrib.topic_color
  224. : '#346cda',
  225. }"
  226. />
  227. </div>
  228. </template>
  229. <div
  230. v-for="(itemI, indexI) in item.miao_arr"
  231. :key="indexI + index"
  232. style="display: flex"
  233. :style="{
  234. borderColor:
  235. data.unified_attrib && data.unified_attrib.topic_color
  236. ? data.unified_attrib.topic_color
  237. : '#346cda',
  238. }"
  239. @click="miaoStorkes(index, indexI, item.mark, item.content, itemI.strokes)"
  240. >
  241. <Strockplayredlines
  242. v-if="
  243. userAnswer[index].strokes_content_list[indexI] &&
  244. userAnswer[index].strokes_content_list[indexI].flag === 'true'
  245. "
  246. :play-storkes="false"
  247. :book-text="item.content"
  248. :target-div="'write-praT-1' + indexI + index + randomId"
  249. :book-strokes="itemI.strokes"
  250. :class="['strock-chinese']"
  251. :bg-type="data.property.frame_type"
  252. :play-color="
  253. data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : ''
  254. "
  255. :style="{
  256. borderColor:
  257. data.unified_attrib && data.unified_attrib.topic_color
  258. ? data.unified_attrib.topic_color
  259. : '#346cda',
  260. }"
  261. />
  262. <Strockplayredlines
  263. v-else
  264. :play-storkes="false"
  265. :book-text="item.content"
  266. :target-div="'write-praT-2' + indexI + index + randomId"
  267. :book-strokes="itemI.strokes"
  268. :stroke-color="'#ddd'"
  269. :class="['strock-chinese']"
  270. :bg-type="data.property.frame_type"
  271. :play-color="
  272. data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : ''
  273. "
  274. :style="{
  275. borderColor:
  276. data.unified_attrib && data.unified_attrib.topic_color
  277. ? data.unified_attrib.topic_color
  278. : '#346cda',
  279. }"
  280. />
  281. </div>
  282. <!-- 书写 -->
  283. <div v-for="(items, indexs) in item.imgArr" :key="'write' + indexs" class="con-box">
  284. <div
  285. :class="['strockplay-newWord']"
  286. :style="{
  287. borderColor:
  288. data.unified_attrib && data.unified_attrib.topic_color
  289. ? data.unified_attrib.topic_color
  290. : '#346cda',
  291. }"
  292. @click="
  293. freeWrite(
  294. userAnswer[index].strokes_content_list[indexs].imgArr
  295. ? userAnswer[index].strokes_content_list[indexs].imgArr
  296. : null,
  297. index,
  298. indexs,
  299. )
  300. "
  301. >
  302. <SvgIcon
  303. v-if="data.property.frame_type === 'tian'"
  304. icon-class="hanzi-writer-bg"
  305. class="character-target-bg"
  306. />
  307. <SvgIcon v-else-if="data.property.frame_type === 'mi'" icon-class="mi" class="character-target-bg" />
  308. <img
  309. v-if="
  310. !play_status &&
  311. items &&
  312. userAnswer[index].strokes_content_list[indexs].imgArr &&
  313. userAnswer[index].strokes_content_list[indexs].imgArr.strokes_image
  314. "
  315. class="hanzi-writer-img"
  316. :src="userAnswer[index].strokes_content_list[indexs].imgArr.strokes_image"
  317. alt=""
  318. />
  319. </div>
  320. </div>
  321. </div>
  322. <div v-if="item.shiyi && isEnable(data.property.is_enable_shiyi)" class="words-bottom">
  323. {{ convertText(item.shiyi) }}
  324. </div>
  325. </div>
  326. </div>
  327. </template>
  328. <div v-if="if_free_show" class="practiceBox practice-box-strock">
  329. <FreewriteLettle
  330. ref="freePaint"
  331. :current-tree-i-d="'1234456'"
  332. :current-hz="current_hz"
  333. :curren-hz-data="current_hz_data"
  334. :row-index="active_index"
  335. :col-index="active_col_index"
  336. :disabled="disabled"
  337. :show-play="isEnable(data.property.is_enable_play_back)"
  338. :bg-type="data.property.frame_type"
  339. :attrib="data.unified_attrib"
  340. @closeIfFreeShow="closeIfFreeShow"
  341. @changePraShow="changePraShow"
  342. @changeCurQue="changeCurQue"
  343. @deleteWriteRecord="deleteWriteRecord"
  344. />
  345. </div>
  346. <div v-if="if_miao_show" class="practiceBox practice-box-strock">
  347. <div class="miao-box">
  348. <i class="el-icon-close close-icon" @click="if_miao_show = false"></i>
  349. <Strockplayredlines
  350. v-if="
  351. (userAnswer[active_index].strokes_content_list[active_col_index].flag &&
  352. userAnswer[active_index].strokes_content_list[active_col_index].flag === 'true') ||
  353. disabled
  354. "
  355. :play-storkes="false"
  356. :book-text="current_hz"
  357. :target-div="'write-praT-3' + current_hz + active_col_index + active_index + randomId"
  358. :book-strokes="current_hz_data"
  359. :stroke-color="
  360. disabled &&
  361. (!userAnswer[active_index].strokes_content_list[active_col_index].flag ||
  362. (userAnswer[active_index].strokes_content_list[active_col_index].flag &&
  363. userAnswer[active_index].strokes_content_list[active_col_index].flag === 'false'))
  364. ? '#ddd'
  365. : ''
  366. "
  367. :bg-type="data.property.frame_type"
  368. :play-color="data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : ''"
  369. />
  370. <Strockred
  371. ref="strockRed"
  372. :class="[
  373. 'strock-red',
  374. userAnswer[active_index].strokes_content_list[active_col_index].flag &&
  375. userAnswer[active_index].strokes_content_list[active_col_index].flag === 'true'
  376. ? 'strock-red-zindex'
  377. : '',
  378. ]"
  379. :book-text="current_hz"
  380. :hanzi-color="hanzi_color"
  381. :target-div="'write-praT' + current_hz + active_col_index + active_index + randomId"
  382. :book-strokes="current_hz_data"
  383. :is-answer.sync="userAnswer[active_index].strokes_content_list[active_col_index].flag"
  384. :show-error-tip="isEnable(data.property.is_enable_error)"
  385. :bg-type="data.property.frame_type"
  386. />
  387. <div v-if="!disabled" :class="['reset-box']" @click="resetHanzi">
  388. <SvgIcon icon-class="reset" class="reset-btn" />
  389. </div>
  390. </div>
  391. </div>
  392. <PreviewOperation @showAnswerAnalysis="showAnswerAnalysis" />
  393. <AnswerAnalysis
  394. :visible.sync="visibleAnswerAnalysis"
  395. :answer-list="data.answer_list"
  396. :analysis-list="data.analysis_list"
  397. />
  398. </div>
  399. </div>
  400. </template>
  401. <script>
  402. import { getCharacterData } from '@/views/book/courseware/data/character';
  403. import PreviewMixin from '../common/PreviewMixin';
  404. import AudioPlay from '../character_base/components/AudioPlay.vue';
  405. import Strockplayredline from '../newWord_template/components/Strockplayredline.vue';
  406. import Strockplayredlines from '../character_base/components/Strockplayredline.vue';
  407. import Strockred from '../character_base/components/Strockred.vue';
  408. import FreewriteLettle from '../character_base/components/FreewriteLettle.vue';
  409. export default {
  410. name: 'CharacterPreview',
  411. components: {
  412. AudioPlay,
  413. Strockplayredline,
  414. Strockred,
  415. FreewriteLettle,
  416. Strockplayredlines,
  417. },
  418. mixins: [PreviewMixin],
  419. data() {
  420. return {
  421. data: getCharacterData(),
  422. userAnswer: [],
  423. hanzi_color: '#404040', // 描红汉字底色
  424. writer_number_yuan: 15,
  425. writer_number: null, // 书写个数
  426. miao_number: null, // 描红个数
  427. if_free_show: false,
  428. free_img: [],
  429. active_index: null,
  430. active_col_index: null,
  431. current_hz: '', // 当前汉字
  432. current_hz_data: null, // 当前汉字数据
  433. play_status: false, // 播放状态
  434. active_mark: '',
  435. option_list: [],
  436. show_preview: false,
  437. miao_arr: [],
  438. if_miao_show: false, // 描红模块
  439. randomId: Math.random().toString(36).substring(2, 12),
  440. };
  441. },
  442. computed: {},
  443. watch: {
  444. 'data.option_list': {
  445. handler(val) {
  446. if (val) {
  447. this.handleData();
  448. }
  449. },
  450. deep: true,
  451. immediate: true,
  452. },
  453. },
  454. created() {},
  455. methods: {
  456. handleData() {
  457. let answer_list = [];
  458. this.data.option_list.forEach((item, index) => {
  459. if (this.data.property.model === 'write') {
  460. let arr = [];
  461. item.content_list.forEach((items) => {
  462. let obj = null;
  463. if (items.type === 'write') {
  464. obj = {
  465. imgArr: null,
  466. };
  467. }
  468. arr.push(obj);
  469. });
  470. answer_list.push(arr);
  471. } else {
  472. let miao_arr = [];
  473. let arr = [];
  474. if (item.content.trim()) {
  475. for (let i = 0; i < this.data.property.write_number; i++) {
  476. item.content_list.forEach((items) => {
  477. arr.push({ imgArr: null, flag: null });
  478. });
  479. }
  480. for (let i = 0; i < this.data.property.miao_number; i++) {
  481. item.content_list.forEach((items) => {
  482. miao_arr.push({
  483. strokes: items && items.hz_info && items.hz_info[0] ? items.hz_info[0].hzDetail.hz_json : null,
  484. length: item.content_list.length,
  485. });
  486. });
  487. }
  488. item.imgArr = arr;
  489. item.miao_arr = miao_arr;
  490. // if (this.isJudgingRightWrong) {
  491. // item.imgArr = this.userAnswer.find(
  492. // (items) => items.mark === item.mark,
  493. // )?.strokes_content_list;
  494. // }
  495. }
  496. let obj = {
  497. // mark: item.mark,
  498. strokes_content_list: arr,
  499. miao_arr,
  500. };
  501. // if (!this.isJudgingRightWrong) {
  502. // this.userAnswer.push(obj);
  503. // }
  504. answer_list.push(obj);
  505. }
  506. });
  507. this.userAnswer = answer_list;
  508. },
  509. changePraShow() {
  510. this.if_free_show = false;
  511. },
  512. closeIfFreeShow(data, rowIndex, colIndex, mark) {
  513. // this.option_list[rowIndex].imgArr[colIndex] = JSON.stringify(data);
  514. this.if_free_show = false;
  515. this.freeWrite(data, rowIndex, colIndex);
  516. this.$forceUpdate();
  517. },
  518. freeWrite(imgUrl, index, indexs) {
  519. this.if_free_show = true;
  520. this.active_index = index;
  521. this.active_col_index = indexs;
  522. this.current_hz =
  523. this.data.option_list[index] &&
  524. this.data.option_list[index].content_list[indexs] &&
  525. this.data.option_list[index].content_list[indexs].con
  526. ? this.data.option_list[index].content_list[indexs].con
  527. : '';
  528. this.current_hz_data = imgUrl;
  529. },
  530. // 删除记录
  531. deleteWriteRecord(rowIndex, colIndex) {
  532. this.$set(this.option_list[rowIndex].imgArr, colIndex, JSON.stringify({}));
  533. this.changeCurQue(null, rowIndex, colIndex);
  534. this.current_hz_data = null;
  535. this.active_mark = '';
  536. this.$forceUpdate();
  537. },
  538. changeCurQue(answer, rowIndex, colIndex) {
  539. if (answer) {
  540. if (this.data.property.model === 'write') {
  541. this.userAnswer[rowIndex][colIndex].imgArr = answer;
  542. } else {
  543. this.userAnswer[rowIndex].strokes_content_list[colIndex].imgArr = answer;
  544. }
  545. this.$forceUpdate();
  546. }
  547. },
  548. // 点击描红模块
  549. miaoStorkes(index, indexs, mark, content, storkes) {
  550. this.if_miao_show = true;
  551. this.active_index = index;
  552. this.active_col_index = indexs;
  553. this.current_hz = content;
  554. this.current_hz_data = storkes;
  555. },
  556. // 保存描红
  557. saveComplete(flag) {
  558. this.answer.answer_list[this.active_index].strokes_content_list[this.active_col_index] = flag;
  559. },
  560. resetHanzi() {
  561. this.$refs.strockRed.resetHanzi();
  562. },
  563. updateColor(color) {
  564. this.writer.updateColor('strokeColor', color);
  565. this.writer.updateColor('drawingColor', color);
  566. },
  567. },
  568. };
  569. </script>
  570. <style lang="scss" scoped>
  571. @use '@/styles/mixin.scss' as *;
  572. .character-preview {
  573. @include preview-base;
  574. display: block;
  575. .main {
  576. display: flex;
  577. flex-wrap: wrap;
  578. column-gap: 16px;
  579. justify-content: start;
  580. }
  581. .content-box {
  582. width: max-content;
  583. }
  584. .audio-wrapper-nobg {
  585. height: 24px;
  586. :deep .audio-play {
  587. width: 24px;
  588. height: 24px;
  589. // color: #000;
  590. background-color: initial;
  591. }
  592. :deep .audio-play.not-url {
  593. color: #a1a1a1;
  594. }
  595. :deep .voice-play {
  596. width: 16px;
  597. height: 16px;
  598. }
  599. }
  600. .main-top {
  601. display: flex;
  602. column-gap: 4px;
  603. align-items: center;
  604. justify-content: center;
  605. }
  606. .pinyin {
  607. font-family: 'League';
  608. font-size: 12px;
  609. font-weight: 500;
  610. color: #000;
  611. }
  612. .strock-chinese-box {
  613. display: flex;
  614. flex-wrap: wrap;
  615. margin: 8px 0;
  616. }
  617. .strockplay-newWord {
  618. position: relative;
  619. box-sizing: border-box;
  620. flex-shrink: 0;
  621. width: 80px;
  622. height: 80px;
  623. border: 2px solid #346cda;
  624. border-radius: 4px;
  625. .character-target-bg,
  626. .hanzi-writer-img {
  627. position: absolute;
  628. top: 0;
  629. left: 0;
  630. width: 100%;
  631. height: 100%;
  632. color: #dedede;
  633. }
  634. .hanzi-writer-img {
  635. z-index: 1;
  636. }
  637. }
  638. .border-right-none {
  639. border-right: none;
  640. }
  641. .item-box {
  642. display: flex;
  643. gap: 5px;
  644. }
  645. .number-box {
  646. display: flex;
  647. align-items: center;
  648. height: 80px;
  649. margin-right: 16px;
  650. .number {
  651. display: block;
  652. width: 24px;
  653. height: 24px;
  654. font-family: 'arial';
  655. font-size: 14px;
  656. font-weight: bold;
  657. line-height: 24px;
  658. color: #fff;
  659. text-align: center;
  660. background: #346cda;
  661. border-radius: 100%;
  662. }
  663. }
  664. .items {
  665. font-size: 0;
  666. }
  667. .pinyin {
  668. height: 30px;
  669. min-height: 16px;
  670. font-family: 'League';
  671. font-size: 20px;
  672. font-weight: 400;
  673. line-height: 30px;
  674. color: rgba(0, 0, 0, 50%);
  675. text-align: center;
  676. }
  677. .items-image,
  678. .hanzi-storck {
  679. width: 80px;
  680. height: 80px;
  681. overflow: hidden;
  682. border: 2px solid #346cda;
  683. border-radius: 4px;
  684. }
  685. .items-lian {
  686. display: block;
  687. height: 80px;
  688. padding: 0 10px;
  689. font-size: 34px;
  690. line-height: 80px;
  691. color: #346cda;
  692. }
  693. .items-flex {
  694. display: flex;
  695. gap: 5px;
  696. }
  697. .item-box-write {
  698. .items-flex {
  699. gap: 0;
  700. }
  701. .NoborderRadius {
  702. border-radius: 0;
  703. }
  704. .rightBorderRadius {
  705. border-radius: 0;
  706. border-top-right-radius: 4px;
  707. border-bottom-right-radius: 4px;
  708. }
  709. .leftBorderRadius {
  710. border-radius: 0;
  711. border-top-left-radius: 4px;
  712. border-bottom-left-radius: 4px;
  713. }
  714. .NoborderRight {
  715. border-right: none;
  716. }
  717. }
  718. .pinyin-common {
  719. margin-bottom: 5px;
  720. :deep .edit-div {
  721. font-family: 'League';
  722. }
  723. }
  724. .en-common {
  725. margin-top: 8px;
  726. // text-align: center;
  727. word-break: break-word;
  728. }
  729. .practiceBox {
  730. position: fixed;
  731. top: 0;
  732. left: 0;
  733. z-index: 101;
  734. box-sizing: border-box;
  735. width: 100%;
  736. height: 100vh;
  737. overflow: hidden;
  738. overflow-y: auto;
  739. background: rgba(0, 0, 0, 19%);
  740. &.practice-box-strock {
  741. display: flex;
  742. align-items: center;
  743. justify-content: center;
  744. padding-top: 0;
  745. }
  746. .miao-box {
  747. position: relative;
  748. width: 332px;
  749. height: 360px;
  750. padding: 30px 16px;
  751. margin: 0 auto;
  752. background: #f3f3f3;
  753. border-radius: 8px;
  754. box-shadow: 0 4px 16px rgba(0, 0, 0, 15%);
  755. .close-icon {
  756. position: absolute;
  757. top: 0;
  758. right: 8px;
  759. z-index: 2;
  760. width: 32px;
  761. height: 32px;
  762. padding: 8px;
  763. cursor: pointer;
  764. }
  765. .strockredBox,
  766. .strockplay-redInner {
  767. width: 300px;
  768. height: 300px;
  769. margin: 0 auto;
  770. }
  771. .strock-red {
  772. position: absolute;
  773. top: 30px;
  774. left: 16px;
  775. &-zindex {
  776. z-index: -1;
  777. }
  778. }
  779. .reset-box {
  780. position: absolute;
  781. right: 22px;
  782. bottom: 22px;
  783. z-index: 100;
  784. display: flex;
  785. align-items: center;
  786. justify-content: center;
  787. width: 11px;
  788. height: 11px;
  789. color: $text-color;
  790. cursor: pointer;
  791. &:hover {
  792. color: #000;
  793. }
  794. }
  795. }
  796. }
  797. .card-box {
  798. display: flex;
  799. flex-flow: wrap;
  800. gap: 5px;
  801. }
  802. .words-left {
  803. display: flex;
  804. gap: 10px;
  805. align-items: center;
  806. margin-bottom: 5px;
  807. }
  808. :deep .strockplay-redInner {
  809. width: 80px;
  810. height: 80px;
  811. border-width: 2px !important;
  812. border-radius: 4px;
  813. }
  814. .words-item {
  815. margin-bottom: 10px;
  816. }
  817. .words-bottom {
  818. margin-top: 3px;
  819. word-break: break-word;
  820. }
  821. .operation {
  822. width: 100%;
  823. }
  824. }
  825. </style>