|
@@ -0,0 +1,596 @@
|
|
|
+<!-- -->
|
|
|
+<template>
|
|
|
+ <div class="practice practiceSingleNPC">
|
|
|
+ <img class="close-icon" @click="changePraShow()" />
|
|
|
+ <div class="right-content">
|
|
|
+ <div class="right-strockred">
|
|
|
+ <template v-if="!hasPlay && data && data.strokes_image_url">
|
|
|
+ <img class="img" :src="data.strokes_image_url" alt="" />
|
|
|
+ </template>
|
|
|
+ <FreeWriteQP
|
|
|
+ id="esign"
|
|
|
+ ref="esign"
|
|
|
+ :bg-color.sync="bgColor"
|
|
|
+ :height="height"
|
|
|
+ :is-crop="isCrop"
|
|
|
+ :line-color="hanzicolor"
|
|
|
+ :line-width="hanziweight"
|
|
|
+ :width="width"
|
|
|
+ class="vueEsign"
|
|
|
+ />
|
|
|
+ <a class="clean-btn" @click="resetHuahua"></a>
|
|
|
+ </div>
|
|
|
+ <ul class="nav-list">
|
|
|
+ <li :class="currenHzData && currenHzData.history ? '' : 'disabled'" @click="play()">播放</li>
|
|
|
+ <li @click="handleWriteImg">保存</li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import FreeWriteQP from './FreeWriteQP.vue';
|
|
|
+export default {
|
|
|
+ components: {
|
|
|
+ FreeWriteQP,
|
|
|
+ },
|
|
|
+ // props: ['currentTreeID', 'currentHz', 'currenHzData', 'closeifFreeShow', 'rowIndex', 'colIndex'],
|
|
|
+ props: {
|
|
|
+ currentTreeID: {
|
|
|
+ type: String,
|
|
|
+ default: '',
|
|
|
+ },
|
|
|
+ currentHz: {
|
|
|
+ type: String,
|
|
|
+ default: '',
|
|
|
+ },
|
|
|
+ currenHzData: {
|
|
|
+ type: Object,
|
|
|
+ default: () => ({
|
|
|
+ strokes_image_url: '',
|
|
|
+ history: [],
|
|
|
+ }),
|
|
|
+ },
|
|
|
+ rowIndex: {
|
|
|
+ type: Number,
|
|
|
+ default: 0,
|
|
|
+ },
|
|
|
+ colIndex: {
|
|
|
+ type: Number,
|
|
|
+ default: 0,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ width: 256,
|
|
|
+ height: 256,
|
|
|
+ bgColor: '',
|
|
|
+ isCrop: false,
|
|
|
+ // learn_mode: "",
|
|
|
+ playStorkes: false,
|
|
|
+ navIndex: 0,
|
|
|
+ colorsList: ['#404040', '#f65d4d', '#19b068', '#52a1ea', '#ff8c49'],
|
|
|
+ weightList: [6, 10],
|
|
|
+ colorIndex: 0,
|
|
|
+ penIndex: 0,
|
|
|
+ hanzicolor: '',
|
|
|
+ hanziweight: '',
|
|
|
+ imgOrCans: false,
|
|
|
+ hasPlay: false,
|
|
|
+ data: null,
|
|
|
+ };
|
|
|
+ },
|
|
|
+ computed: {},
|
|
|
+ watch: {},
|
|
|
+ // 生命周期 - 创建完成(可以访问当前this实例)
|
|
|
+ created() {
|
|
|
+ let _this = this;
|
|
|
+ let color = _this.colorsList[_this.colorIndex];
|
|
|
+ _this.hanzicolor = color;
|
|
|
+ _this.hanziweight = 6;
|
|
|
+ if (_this.currenHzData && _this.currenHzData.strokes_image_url) {
|
|
|
+ _this.imgOrCans = true;
|
|
|
+ }
|
|
|
+ _this.data = JSON.parse(JSON.stringify(_this.currenHzData));
|
|
|
+ },
|
|
|
+ // 生命周期 - 挂载完成(可以访问DOM元素)
|
|
|
+ mounted() {},
|
|
|
+ beforeCreate() {}, // 生命周期 - 创建之前
|
|
|
+ beforeMount() {}, // 生命周期 - 挂载之前
|
|
|
+ beforeUpdate() {}, // 生命周期 - 更新之前
|
|
|
+ updated() {}, // 生命周期 - 更新之后
|
|
|
+ beforeDestroy() {}, // 生命周期 - 销毁之前
|
|
|
+ destroyed() {}, // 生命周期 - 销毁完成
|
|
|
+ activated() {},
|
|
|
+ // 方法集合
|
|
|
+ methods: {
|
|
|
+ play() {
|
|
|
+ let _this = this;
|
|
|
+ if (this.currenHzData.history) {
|
|
|
+ if (this.hasPlay) {
|
|
|
+ this.$message.warning('请等待播放完成');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.$refs.esign.reset();
|
|
|
+ this.hasPlay = true;
|
|
|
+ let c = document.getElementById('esign');
|
|
|
+ let cxt = document.getElementById('esign').getContext('2d');
|
|
|
+ cxt.clearRect(0, 0, c.width, c.height);
|
|
|
+ let history = null;
|
|
|
+ history = _this.currenHzData.history;
|
|
|
+ const len = history.length;
|
|
|
+ let i = 0;
|
|
|
+ const runner = () => {
|
|
|
+ i += 1;
|
|
|
+ if (i < len) {
|
|
|
+ _this.$refs.esign.draw(null, history[i][0], history[i][1]);
|
|
|
+ requestAnimationFrame(runner);
|
|
|
+ } else {
|
|
|
+ _this.hasPlay = false;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ requestAnimationFrame(runner);
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ changeNav(index) {
|
|
|
+ this.navIndex = index;
|
|
|
+ },
|
|
|
+ changeColor(index) {
|
|
|
+ let _this = this;
|
|
|
+ _this.colorIndex = index;
|
|
|
+ let color = _this.colorsList[index];
|
|
|
+ _this.hanzicolor = color;
|
|
|
+ },
|
|
|
+ // changePen(index) {
|
|
|
+ // let _this = this;
|
|
|
+ // _this.penIndex = index;
|
|
|
+ // _this.hanziweight = _this.weightList[_this.penIndex];
|
|
|
+ // },
|
|
|
+ changeLearnMode(mode) {
|
|
|
+ this.learn_mode = mode;
|
|
|
+ },
|
|
|
+ resetHuahua() {
|
|
|
+ let _this = this;
|
|
|
+ if (_this.hasPlay) {
|
|
|
+ _this.$message.warning('请等待播放完成');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ _this.imgOrCans = false;
|
|
|
+ _this.$refs.esign.reset();
|
|
|
+ if (_this.data) {
|
|
|
+ _this.data.strokes_image_url = '';
|
|
|
+ }
|
|
|
+ _this.$emit('deleteWriteRecord', _this.rowIndex, _this.colIndex, _this.currentHz);
|
|
|
+ // this.removeImage();
|
|
|
+ },
|
|
|
+ removeImage() {
|
|
|
+ let _this = this;
|
|
|
+ if (_this.data) {
|
|
|
+ // let MethodName = 'teaching-practice_manager-DeleteMyHZHandwrittenRecord';
|
|
|
+ // let data = {
|
|
|
+ // hz_handwritten_record_id: this.data.hz_handwritten_record_id,
|
|
|
+ // };
|
|
|
+ // LearnWebSI(MethodName, data).then((res) => {
|
|
|
+ _this.$message.success('删除成功');
|
|
|
+ _this.data = {};
|
|
|
+ _this.$emit('deleteWriteRecord', _this.rowIndex, _this.colIndex);
|
|
|
+ // });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 不保存到记录列表
|
|
|
+ handleWriteImg() {
|
|
|
+ this.$refs.esign.generate().then((res) => {
|
|
|
+ let Book_img = res.replace('data:image/png;base64,', '');
|
|
|
+ let write_img = `data:image/png;base64,${Book_img}`;
|
|
|
+ let answer = {};
|
|
|
+ answer = {
|
|
|
+ hz: this.currentHz,
|
|
|
+ strokes_content: JSON.stringify(this.$refs.esign.history),
|
|
|
+ strokes_image_url: write_img,
|
|
|
+ };
|
|
|
+ this.$emit('changeCurQue', answer, this.colIndex);
|
|
|
+ let obj = {
|
|
|
+ history: this.$refs.esign.history,
|
|
|
+ strokes_image_url: write_img,
|
|
|
+ };
|
|
|
+ this.$emit('closeIfFreeShow', obj, this.rowIndex, this.colIndex);
|
|
|
+ // this.$message.warning("请先书写在保存");
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 保存到记录列表
|
|
|
+ handleWriteImg_save() {
|
|
|
+ this.$refs.esign
|
|
|
+ .generate()
|
|
|
+ .then((res) => {
|
|
|
+ let Book_img = res.replace('data:image/png;base64,', '');
|
|
|
+ let write_img = `data:image/png;base64,${Book_img}`;
|
|
|
+ let answer = {};
|
|
|
+ answer = {
|
|
|
+ hz: this.currentHz,
|
|
|
+ strokes_content: JSON.stringify(this.$refs.esign.history),
|
|
|
+ strokes_image_url: write_img,
|
|
|
+ };
|
|
|
+ this.$emit('changeCurQue', answer, this.colIndex);
|
|
|
+
|
|
|
+ // let data = {
|
|
|
+ // courseware_id: this.currentTreeID,
|
|
|
+ // hz: this.currentHz,
|
|
|
+ // strokes_content: JSON.stringify(this.$refs.esign.history),
|
|
|
+ // strokes_image_base64: Book_img,
|
|
|
+ // };
|
|
|
+ // let MethodName = 'teaching-practice_manager-SaveMyHZHandwrittenRecord';
|
|
|
+ // LearnWebSI(MethodName, data).then((res) => {
|
|
|
+ this.$message.success('保存成功!');
|
|
|
+ let obj = {
|
|
|
+ hz_handwritten_record_id: res.hz_handwritten_record_id,
|
|
|
+ history: this.$refs.esign.history,
|
|
|
+ strokes_image_url: write_img,
|
|
|
+ };
|
|
|
+ this.$emit('closeIfFreeShow', obj, this.rowIndex, this.colIndex);
|
|
|
+ // });
|
|
|
+ })
|
|
|
+ .catch(() => {
|
|
|
+ this.$message.warning('请先书写在保存');
|
|
|
+ });
|
|
|
+ },
|
|
|
+ changePraShow() {
|
|
|
+ this.$emit('changePraShow');
|
|
|
+ },
|
|
|
+ }, // 如果页面有keep-alive缓存功能,这个函数会触发
|
|
|
+};
|
|
|
+</script>
|
|
|
+<style lang="scss" scoped>
|
|
|
+.practice {
|
|
|
+ position: relative;
|
|
|
+ width: 320px;
|
|
|
+ max-height: 400px;
|
|
|
+ margin: 0 auto;
|
|
|
+ background: #f3f3f3;
|
|
|
+ border-radius: 8px;
|
|
|
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 15%);
|
|
|
+
|
|
|
+ .clean-btn {
|
|
|
+ position: absolute;
|
|
|
+ right: 8px;
|
|
|
+ bottom: 8px;
|
|
|
+ width: 16px;
|
|
|
+ height: 16px;
|
|
|
+ margin: 0 4px;
|
|
|
+ cursor: pointer;
|
|
|
+
|
|
|
+ // background: url('../../../../assets/icon/Undo-16-disable-Black.png') center no-repeat;
|
|
|
+ // background-size: cover;
|
|
|
+ // display: block;
|
|
|
+ // &:hover {
|
|
|
+ // background: url('../../../../assets/icon/Undo-16-normal-Black.png') center no-repeat;
|
|
|
+ // background-size: cover;
|
|
|
+ // }
|
|
|
+ }
|
|
|
+
|
|
|
+ .close-icon {
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ right: 8px;
|
|
|
+ z-index: 2;
|
|
|
+ width: 32px;
|
|
|
+ height: 32px;
|
|
|
+ padding: 8px;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+
|
|
|
+ .Book_content {
|
|
|
+ position: relative;
|
|
|
+ box-sizing: border-box;
|
|
|
+ display: flex;
|
|
|
+ align-items: flex-start;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .left-content {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: center;
|
|
|
+ width: 144px;
|
|
|
+
|
|
|
+ .left-content-pra {
|
|
|
+ height: 162px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .right-content {
|
|
|
+ position: relative;
|
|
|
+ box-sizing: border-box;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: flex-start;
|
|
|
+ width: 288px;
|
|
|
+ height: 360px;
|
|
|
+ padding: 30px 16px;
|
|
|
+ margin: 0 auto;
|
|
|
+ background: #f3f3f3;
|
|
|
+ border-radius: 16px;
|
|
|
+
|
|
|
+ .nav-list {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ width: 100%;
|
|
|
+ height: 34px;
|
|
|
+ padding: 0;
|
|
|
+ margin-top: 16px;
|
|
|
+ list-style: none;
|
|
|
+
|
|
|
+ > li {
|
|
|
+ width: 124px;
|
|
|
+ height: 34px;
|
|
|
+ font-size: 14px;
|
|
|
+ font-style: normal;
|
|
|
+ font-weight: bold;
|
|
|
+ line-height: 34px;
|
|
|
+ color: #fff;
|
|
|
+ text-align: center;
|
|
|
+ cursor: pointer;
|
|
|
+ background: #de4444;
|
|
|
+ border-radius: 8px;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background: #f76565;
|
|
|
+ }
|
|
|
+
|
|
|
+ &:active {
|
|
|
+ background: #c43c3c;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.disabled {
|
|
|
+ color: #fff;
|
|
|
+ cursor: not-allowed;
|
|
|
+ background-color: #c8c9cc;
|
|
|
+ background-image: none;
|
|
|
+ border-color: #c8c9cc;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .right-strockred {
|
|
|
+ position: relative;
|
|
|
+ width: 256px;
|
|
|
+ height: 256px;
|
|
|
+ overflow: hidden;
|
|
|
+
|
|
|
+ // background: #fff url('../../../../assets/NPC/chinaTianRed.png') center no-repeat;
|
|
|
+ background-size: 100% 100%;
|
|
|
+ border-radius: 8px;
|
|
|
+
|
|
|
+ .img {
|
|
|
+ position: absolute;
|
|
|
+ }
|
|
|
+
|
|
|
+ // .strock-play-box {
|
|
|
+ // position: absolute;
|
|
|
+ // width: 32px;
|
|
|
+ // height: 32px;
|
|
|
+ // background: #fff
|
|
|
+ // url("../../../../assets/NPC/strock-play-red-click-big.png") center
|
|
|
+ // no-repeat;
|
|
|
+ // background-size: 100% 100%;
|
|
|
+ // cursor: pointer;
|
|
|
+ // right: 0;
|
|
|
+ // top: 0;
|
|
|
+ // z-index: 2;
|
|
|
+ // }
|
|
|
+ }
|
|
|
+
|
|
|
+ .footer {
|
|
|
+ position: absolute;
|
|
|
+ bottom: 80px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: flex-end;
|
|
|
+ width: 100%;
|
|
|
+ padding-right: 40px;
|
|
|
+
|
|
|
+ .pen-colors {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: flex-start;
|
|
|
+
|
|
|
+ .write-icon-3 {
|
|
|
+ width: 20px;
|
|
|
+ height: 20px;
|
|
|
+ margin-right: 12px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .colors-list {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: flex-start;
|
|
|
+ padding: 0;
|
|
|
+ margin: 0;
|
|
|
+
|
|
|
+ > li {
|
|
|
+ box-sizing: border-box;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ width: 20px;
|
|
|
+ height: 20px;
|
|
|
+ margin: 0 4px;
|
|
|
+ cursor: pointer;
|
|
|
+ background: #fff;
|
|
|
+ border: 2px solid #fff;
|
|
|
+ border-radius: 50%;
|
|
|
+
|
|
|
+ > span {
|
|
|
+ width: 14px;
|
|
|
+ height: 14px;
|
|
|
+ border-radius: 100%;
|
|
|
+
|
|
|
+ &.color-item0 {
|
|
|
+ background: #404040;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.color-item1 {
|
|
|
+ background: #f65d4d;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.color-item2 {
|
|
|
+ background: #19b068;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.color-item3 {
|
|
|
+ background: #52a1ea;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.color-item4 {
|
|
|
+ background: #ff8c49;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &.color-item-active0 {
|
|
|
+ border: 2px solid #404040;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.color-item-active1 {
|
|
|
+ border: 2px solid #f65d4d;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.color-item-active2 {
|
|
|
+ border: 2px solid #19b068;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.color-item-active3 {
|
|
|
+ border: 2px solid #52a1ea;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.color-item-active4 {
|
|
|
+ border: 2px solid #ff8c49;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .pen {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: flex-start;
|
|
|
+
|
|
|
+ > img {
|
|
|
+ width: 21px;
|
|
|
+ height: 19px;
|
|
|
+ margin-left: 4px;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.strockplay {
|
|
|
+ box-sizing: border-box;
|
|
|
+ width: 144px;
|
|
|
+ height: 144px;
|
|
|
+ overflow: hidden;
|
|
|
+ border: 2px solid #de4444;
|
|
|
+ border-radius: 8px;
|
|
|
+
|
|
|
+ .strockplayRedInner {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.left-content .footer {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ width: 100%;
|
|
|
+ cursor: pointer;
|
|
|
+
|
|
|
+ .bg-box {
|
|
|
+ box-sizing: border-box;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ width: 76px;
|
|
|
+ height: 32px;
|
|
|
+ padding: 4px 8px;
|
|
|
+ font-size: 16px;
|
|
|
+ line-height: 150%;
|
|
|
+ color: #000;
|
|
|
+ text-align: center;
|
|
|
+ background: #fff;
|
|
|
+ border: 1px solid rgba(0, 0, 0, 10%);
|
|
|
+ border-radius: 4px;
|
|
|
+
|
|
|
+ // &:nth-child(2) {
|
|
|
+ // margin: 0 24px;
|
|
|
+ // }
|
|
|
+ img {
|
|
|
+ width: 24px;
|
|
|
+ height: 24px;
|
|
|
+ margin: 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .practice-icon {
|
|
|
+ height: 36px;
|
|
|
+ margin-top: 12px;
|
|
|
+ }
|
|
|
+
|
|
|
+ > span {
|
|
|
+ margin-bottom: 9px;
|
|
|
+ font-family: 'FZJCGFKTK';
|
|
|
+ font-size: 24px;
|
|
|
+ font-weight: 600;
|
|
|
+ line-height: 34px;
|
|
|
+ color: #ba7d21;
|
|
|
+
|
|
|
+ /* identical to box height */
|
|
|
+
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.el-tabs {
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+</style>
|
|
|
+<style lang="scss">
|
|
|
+.practiceSingleNPC {
|
|
|
+ .el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active {
|
|
|
+ color: #000;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-tabs--border-card > .el-tabs__header .el-tabs__item:not(.is-disabled):hover {
|
|
|
+ color: #000;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-tabs__item,
|
|
|
+ .el-tabs--border-card > .el-tabs__header .el-tabs__item {
|
|
|
+ width: 80px;
|
|
|
+ height: 48px;
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: normal;
|
|
|
+ line-height: 150%;
|
|
|
+ line-height: 48px;
|
|
|
+ color: #000;
|
|
|
+ text-align: center;
|
|
|
+ border: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-tabs--border-card > .el-tabs__header {
|
|
|
+ background: #f3f3f3;
|
|
|
+ border: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-tabs--border-card > .el-tabs__content {
|
|
|
+ padding: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-tab-pane {
|
|
|
+ display: flex;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|