| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491 |
- <!-- eslint-disable vue/no-v-html -->
- <template>
- <div v-if="show_preview" class="character-preview" :style="getAreaStyle()">
- <SerialNumberPosition v-if="isEnable(data.property.sn_display_mode)" :property="data.property" />
- <div class="main">
- <div class="main-top" :style="{ width: data.hz_strokes_list.length * 64 + 'px' }">
- <AudioPlay
- v-if="isEnable(data.property.is_enable_voice)"
- :file-id="data.audio_file_id"
- :theme-color="data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : ''"
- />
- <span v-if="isEnable(data.property.view_pinyin)" class="pinyin">{{ data.pinyin }}</span>
- </div>
- <div class="strock-chinese-box">
- <template v-if="data.property.fun_type === 'show'">
- <Strockplayredline
- v-for="(items, indexs) in data.hz_strokes_list"
- :key="indexs"
- :play-storkes="true"
- :book-text="data.content"
- :target-div="'pre' + data.content + indexs"
- :book-strokes="items.strokes"
- :class="['strock-chinese', indexs !== data.hz_strokes_list.length - 1 ? 'border-right-none' : '']"
- :bg-type="data.property.frame_type"
- :play-color="data.property.frame_color"
- />
- </template>
- <template v-else>
- <template v-if="isEnable(data.property.is_enable_miao)">
- <div
- v-for="(itemI, indexI) in miao_arr[0]"
- :key="indexI + data.property.fun_type + 0"
- style="display: flex"
- @click="miaoStorkes(0, indexI, data.mark, data.content, itemI.strokes)"
- >
- <Strockplayredline
- v-if="data.imgArr[indexI] && data.imgArr[indexI] === 'true'"
- :play-storkes="false"
- :book-text="data.content"
- :target-div="'write-praT' + data.content + itemI + Math.random().toString(36).substring(2, 10)"
- :book-strokes="itemI.strokes"
- :class="['strock-chinese', indexI !== miao_arr[0].length - 1 ? 'border-right-none' : '']"
- />
- <Strockplayredline
- v-else
- :play-storkes="false"
- :book-text="data.content"
- :target-div="'write-praT' + data.content + itemI + Math.random().toString(36).substring(2, 10)"
- :book-strokes="itemI.strokes"
- :stroke-color="'#ddd'"
- :class="['strock-chinese', indexI !== miao_arr[0].length - 1 ? 'border-right-none' : '']"
- />
- </div>
- </template>
- <template v-else>
- <div v-for="(items, indexs) in data.imgArr" :key="indexs" class="con-box">
- <div
- :class="['strockplay-newWord', indexs !== data.imgArr.length - 1 ? 'border-right-none' : '']"
- :style="{ borderColor: data.property.frame_color }"
- @click="freeWrite(items ? JSON.parse(items) : null, 0, indexs, data.mark)"
- >
- <SvgIcon icon-class="hanzi-writer-bg" class="character-target-bg" />
- <img
- v-if="!play_status && items && JSON.parse(items).strokes_image"
- class="hanzi-writer-img"
- :src="JSON.parse(items).strokes_image"
- alt=""
- />
- </div>
- </div>
- </template>
- <!-- <Strockred
- v-if="data.answer.answer_list[0]"
- :class="[
- 'strock-red',
- data.answer.answer_list[0].strokes_content_list[active_col_index] &&
- data.answer.answer_list[0].strokes_content_list[active_col_index] === 'true'
- ? 'strock-red-zindex'
- : '',
- ]"
- :book-text="current_hz"
- :hanzi-color="hanzi_color"
- :target-div="'write-praT' + current_hz + active_col_index + Math.random().toString(36).substring(2, 10)"
- :book-strokes="current_hz_data"
- :is-answer.sync="data.answer.answer_list[0].strokes_content_list[active_col_index]"
- ref="strockRed"
- /> -->
- </template>
- </div>
- <p v-if="data.definition" class="words-right">{{ data.definition }}</p>
- <template v-if="isEnable(data.property.is_enable_voice_answer)">
- <SoundRecord
- ref="record"
- type="normal"
- class="record-box"
- :answer-record-list="data.record_list"
- :task-model="isJudgingRightWrong ? 'ANSWER' : ''"
- @handleWav="handleWav"
- />
- </template>
- </div>
- <div v-if="if_free_show" class="practiceBox practice-box-strock">
- <FreewriteLettle
- ref="freePaint"
- :current-tree-i-d="'1234456'"
- :current-hz="current_hz"
- :curren-hz-data="current_hz_data"
- :row-index="0"
- :col-index="active_col_index"
- :show-play="isEnable(data.property.is_enable_play_back)"
- :disabled="disabled"
- @closeIfFreeShow="closeIfFreeShow"
- @changePraShow="changePraShow"
- @changeCurQue="changeCurQue"
- @deleteWriteRecord="deleteWriteRecord"
- />
- </div>
- <div v-if="if_miao_show" class="practiceBox practice-box-strock">
- <div class="miao-box">
- <i class="el-icon-close close-icon" @click="if_miao_show = false"></i>
- <Strockplayredline
- v-if="
- (data.answer.answer_list[0].strokes_content_list[active_col_index] &&
- data.answer.answer_list[0].strokes_content_list[active_col_index] === 'true') ||
- disabled
- "
- :play-storkes="false"
- :book-text="current_hz"
- :target-div="'write-praT' + current_hz + active_col_index + Math.random().toString(36).substring(2, 10)"
- :book-strokes="current_hz_data"
- :stroke-color="
- disabled &&
- (!data.answer.answer_list[0].strokes_content_list[active_col_index] ||
- (data.answer.answer_list[0].strokes_content_list[active_col_index] &&
- data.answer.answer_list[0].strokes_content_list[active_col_index] === 'false'))
- ? '#ddd'
- : ''
- "
- />
- <Strockred
- ref="strockRed"
- :class="[
- 'strock-red',
- data.answer.answer_list[0].strokes_content_list[active_col_index] &&
- data.answer.answer_list[0].strokes_content_list[active_col_index] === 'true'
- ? 'strock-red-zindex'
- : '',
- ]"
- :book-text="current_hz"
- :hanzi-color="hanzi_color"
- :target-div="'write-praT' + current_hz + active_col_index + Math.random().toString(36).substring(2, 10)"
- :book-strokes="current_hz_data"
- :is-answer.sync="data.answer.answer_list[0].strokes_content_list[active_col_index]"
- :show-error-tip="isEnable(data.property.is_enable_error)"
- />
- <div v-if="!disabled" :class="['reset-box']" @click="resetHanzi">
- <SvgIcon icon-class="reset" class="reset-btn" />
- </div>
- </div>
- </div>
- </div>
- </template>
- <script>
- import { getCharacterBaseData } from '@/views/book/courseware/data/characterBase';
- import PreviewMixin from '../common/PreviewMixin';
- import AudioPlay from './components/AudioPlay.vue';
- import Strockplayredline from './components/Strockplayredline.vue';
- import Strockred from './components/Strockred.vue';
- import SoundRecord from '../../common/SoundRecord.vue';
- import FreewriteLettle from './components/FreewriteLettle.vue';
- export default {
- name: 'CharacterBasePreview',
- components: {
- AudioPlay,
- Strockplayredline,
- SoundRecord,
- Strockred,
- FreewriteLettle,
- },
- mixins: [PreviewMixin],
- inject: {
- bookStatus: {
- default: 'online',
- },
- },
- data() {
- return {
- data: getCharacterBaseData(),
- if_free_show: false,
- active_col_index: null,
- current_hz: '', // 当前汉字
- current_hz_data: null, // 当前汉字数据
- play_status: false, // 播放状态
- active_mark: '',
- option_list: [],
- show_preview: false,
- miao_arr: [],
- if_miao_show: false, // 描红模块
- hanzi_color: '#404040', // 描红汉字底色
- };
- },
- computed: {},
- watch: {
- 'data.record_list'(val) {
- this.data.record_list = val;
- },
- 'data.content': {
- handler(val) {
- if (val) {
- this.handleData();
- }
- },
- deep: true,
- immediate: true,
- },
- isJudgingRightWrong: {
- handler(val) {
- if (!val) return;
- this.handleData();
- },
- immediate: true,
- },
- },
- created() {
- // if (this.bookStatus === 'offline') {
- // this.$message.warning('播放笔画动画功能只有在线教材可以支持,请使用在线教材');
- // }
- },
- methods: {
- handleWav(data) {
- this.data.record_list = data;
- },
- handleData() {
- this.show_preview = false;
- if (!this.isJudgingRightWrong) {
- this.data.answer.answer_list = [];
- }
- this.miao_arr = [];
- this.miao_arr.push([]);
- let arr = [];
- this.data.hz_strokes_list.forEach((items) => {
- if (this.data.property.fun_type === 'write' && this.isEnable(this.data.property.is_enable_miao)) {
- this.miao_arr[0].push({
- strokes: items && items.strokes ? items.strokes : null,
- length: this.data.hz_strokes_list.length,
- });
- }
- arr.push(null);
- });
- this.data.imgArr = arr;
- if (this.isJudgingRightWrong) {
- this.data.imgArr = this.data.answer.answer_list[0].strokes_content_list;
- }
- let obj = {
- mark: this.data.mark,
- strokes_content_list: arr,
- };
- if (!this.isJudgingRightWrong) {
- this.data.answer.answer_list.push(obj);
- }
- this.show_preview = true;
- },
- changePraShow() {
- this.if_free_show = false;
- },
- closeIfFreeShow(data, rowIndex, colIndex, mark) {
- this.data.imgArr[colIndex] = JSON.stringify(data);
- this.if_free_show = false;
- this.freeWrite(data, rowIndex, colIndex, mark);
- this.$forceUpdate();
- },
- freeWrite(imgUrl, index, indexs, mark) {
- this.if_free_show = true;
- this.active_col_index = indexs;
- this.active_mark = mark;
- this.current_hz = this.data.content;
- this.current_hz_data = imgUrl;
- },
- // 删除记录
- deleteWriteRecord(rowIndex, colIndex) {
- this.$set(this.data.imgArr, colIndex, JSON.stringify({}));
- this.changeCurQue(null, colIndex, this.active_mark);
- this.current_hz_data = null;
- this.active_mark = '';
- this.$forceUpdate();
- },
- changeCurQue(answer, colIndex, mark) {
- if (answer) {
- let write_model = [];
- this.answer.answer_list.forEach((itema) => {
- if (itema.mark === mark) {
- write_model = itema.strokes_content_list;
- }
- });
- write_model[colIndex] = JSON.stringify(answer);
- }
- },
- // 点击描红模块
- miaoStorkes(index, indexs, mark, content, storkes) {
- this.if_miao_show = true;
- this.active_col_index = indexs;
- this.active_mark = mark;
- this.current_hz = content;
- this.current_hz_data = storkes;
- },
- // 保存描红
- saveComplete(flag) {
- this.answer.answer_list[0].strokes_content_list[this.active_col_index] = flag;
- },
- resetHanzi() {
- this.$refs.strockRed.resetHanzi();
- },
- updateColor(color) {
- this.writer.updateColor('strokeColor', color);
- this.writer.updateColor('drawingColor', color);
- },
- },
- };
- </script>
- <style lang="scss" scoped>
- @use '@/styles/mixin.scss' as *;
- .character-preview {
- @include preview-base;
- .audio-wrapper-nobg {
- height: 16px;
- :deep .audio-play {
- width: 16px;
- height: 16px;
- color: #000;
- background-color: initial;
- }
- :deep .audio-play.not-url {
- color: #a1a1a1;
- }
- :deep .voice-play {
- width: 16px;
- height: 16px;
- }
- }
- .main-top {
- display: flex;
- column-gap: 4px;
- align-items: center;
- justify-content: center;
- }
- .pinyin {
- font-family: 'League';
- font-size: 12px;
- font-weight: 500;
- color: #000;
- }
- .words-right {
- padding: 8px 4px;
- margin: 0;
- font-size: 14px;
- line-height: 14px;
- color: #000;
- }
- .strock-chinese-box {
- display: flex;
- flex-wrap: wrap;
- margin: 8px 0;
- }
- .record-box {
- padding: 7px 12px;
- margin-top: 8px;
- background: #f2f3f5;
- border-radius: 2px;
- }
- .strockplay-newWord {
- position: relative;
- box-sizing: border-box;
- flex-shrink: 0;
- width: 64px;
- height: 64px;
- border: 1px solid #e81b1b;
- .character-target-bg,
- .hanzi-writer-img {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- color: #dedede;
- }
- .hanzi-writer-img {
- z-index: 1;
- }
- }
- .border-right-none {
- border-right: none;
- }
- .practiceBox {
- position: fixed;
- top: 0;
- left: 0;
- z-index: 101;
- box-sizing: border-box;
- width: 100%;
- height: 100vh;
- overflow: hidden;
- overflow-y: auto;
- background: rgba(0, 0, 0, 19%);
- &.practice-box-strock {
- display: flex;
- align-items: center;
- justify-content: center;
- padding-top: 0;
- }
- .miao-box {
- position: relative;
- width: 332px;
- height: 360px;
- padding: 30px 16px;
- margin: 0 auto;
- background: #f3f3f3;
- border-radius: 8px;
- box-shadow: 0 4px 16px rgba(0, 0, 0, 15%);
- .close-icon {
- position: absolute;
- top: 0;
- right: 8px;
- z-index: 2;
- width: 32px;
- height: 32px;
- padding: 8px;
- cursor: pointer;
- }
- .strockredBox,
- .strockplay-redInner {
- width: 300px;
- height: 300px;
- margin: 0 auto;
- }
- .strock-red {
- position: absolute;
- top: 30px;
- left: 16px;
- &-zindex {
- z-index: -1;
- }
- }
- .reset-box {
- position: absolute;
- right: 22px;
- bottom: 22px;
- z-index: 100;
- display: flex;
- align-items: center;
- justify-content: center;
- width: 11px;
- height: 11px;
- color: $text-color;
- cursor: pointer;
- &:hover {
- color: #000;
- }
- }
- }
- }
- }
- </style>
|