| | |
| | | <template> |
| | | <div class="connect" id="connect" ref="connect" @mousemove="mousemove" @mouseup="(e) => touchend(e)"> |
| | | <div class="answer" > |
| | | <div class="answer-box"> |
| | | <div |
| | | class="answer-box-item" |
| | | v-for="(item, index) in leftArr" |
| | | :key="index" |
| | | ref="left" |
| | | @mousedown="(e) => touchstart(e, item, index)" |
| | | |
| | | > |
| | | {{ item.label.txt }} |
| | | <div class="matching"> |
| | | <div |
| | | class="connect" |
| | | id="connect" |
| | | ref="connect" |
| | | @mousemove="mousemove" |
| | | @mouseup="(e) => touchend(e)" |
| | | > |
| | | <div class="answer"> |
| | | <div class="answer-box"> |
| | | <div |
| | | class="answer-box-item" |
| | | v-for="(item, index) in leftArr" |
| | | :key="index" |
| | | ref="left" |
| | | @mousedown="(e) => touchstart(e, item, index)" |
| | | :style="{ backgroundColor: primaryColor,border:'1px solid' + bordercolor }" |
| | | v-html="item.label.txt" |
| | | ></div> |
| | | </div> |
| | | <div class="answer-box"> |
| | | <div |
| | | class="answer-box-item tl-le" |
| | | v-for="(item, index) in rightArr" |
| | | :key="index" |
| | | ref="right" |
| | | :style="{ backgroundColor: primaryColor,border:'1px solid' + bordercolor }" |
| | | v-html="item.label.txt" |
| | | ></div> |
| | | </div> |
| | | </div> |
| | | <div class="answer-box"> |
| | | <div |
| | | class="answer-box-item" |
| | | v-for="(item, index) in rightArr" |
| | | :key="index" |
| | | ref="right" |
| | | > |
| | | {{ item.label.txt }} |
| | | </div> |
| | | </div> |
| | | <canvas |
| | | class="connect-canvasA" |
| | | :width="clientWidth" |
| | | :height="clientHeight" |
| | | ref="canvasA" |
| | | ></canvas> |
| | | <canvas |
| | | class="connect-canvasB" |
| | | :width="clientWidth" |
| | | :height="clientHeight" |
| | | ref="canvasB" |
| | | ></canvas> |
| | | </div> |
| | | <canvas |
| | | class="connect-canvasA" |
| | | :width="clientWidth" |
| | | :height="clientHeight" |
| | | ref="canvasA" |
| | | ></canvas> |
| | | <canvas |
| | | class="connect-canvasB" |
| | | :width="clientWidth" |
| | | :height="clientHeight" |
| | | ref="canvasB" |
| | | ></canvas> |
| | | <!-- 按钮 --> |
| | | <div class="btn-bottom"> |
| | | <el-button @click="submitData">提交</el-button> |
| | | <el-button @click="saveData" :style="{ borderColor: bordercolor }" |
| | | >保存</el-button |
| | | > |
| | | <el-button @click="redo">重做</el-button> |
| | | <el-button @click="handleAnswer" :style="{ borderColor: bordercolor }" |
| | | >查看答案</el-button |
| | | > |
| | | </div> |
| | | <!-- 解析 --> |
| | | <ul class="show-answer" v-if="isShowAnswer"> |
| | | <li v-if="isRight !== null"> |
| | | 答案结果: |
| | | <!-- <span v-if="isRight" style="color: #83e089">正确</span> |
| | | <span v-if="isRight == false" style="color: #d81e06">错误</span> --> |
| | | <!-- 正确 --> |
| | | <svg t="1718283080456" class="icon" viewBox="0 0 1024 1024" version="1.1" |
| | | xmlns="http://www.w3.org/2000/svg" p-id="97920" xmlns:xlink="http://www.w3.org/1999/xlink" |
| | | width="20" height="20" v-if="isRight"> |
| | | <path |
| | | d="M1005.038 514.114c0 271.97-220.503 492.457-492.48 492.457-271.962 0-492.449-220.487-492.449-492.457 0-271.984 220.487-492.464 492.449-492.464 271.977 0 492.48 220.48 492.48 492.464z" |
| | | fill="#F5CB2B" p-id="97921"></path> |
| | | <path |
| | | d="M288.394 516.789c-19.68 0-35.773-16.094-35.773-35.773v-85.854c0-19.673 16.093-35.773 35.773-35.773 19.68 0 35.773 16.101 35.773 35.773v85.854c0 19.679-16.093 35.773-35.773 35.773zM736.752 516.789c-19.68 0-35.773-16.094-35.773-35.773v-85.854c0-19.673 16.094-35.773 35.773-35.773 19.681 0 35.773 16.101 35.773 35.773v85.854c0 19.679-16.092 35.773-35.773 35.773z" |
| | | fill="#3E3417" p-id="97922"></path> |
| | | <path |
| | | d="M511.79 702.128c-154.229 0-196.709-88.296-198.441-92.056-5.787-12.56-0.302-27.433 12.266-33.227 12.567-5.778 27.425-0.294 33.227 12.259 1.115 2.253 32.73 62.942 152.949 62.942 120.521 0 153.476-61.549 154.816-64.163 5.967-12.484 20.825-17.616 33.303-11.656 12.492 5.961 17.69 21.067 11.738 33.544-1.809 3.775-45.885 92.357-199.858 92.357z" |
| | | fill="#3E3417" p-id="97923"></path> |
| | | <path |
| | | d="M259.703 569.793c0 39.579-32.096 71.652-71.667 71.652-39.586 0-71.653-32.073-71.653-71.652 0-39.586 32.066-71.659 71.653-71.659 39.571 0 71.667 32.073 71.667 71.659zM949.298 569.793c0 39.579-32.082 71.652-71.652 71.652-39.586 0-71.651-32.073-71.651-71.652 0-39.586 32.065-71.659 71.651-71.659 39.57 0 71.652 32.073 71.652 71.659z" |
| | | fill="#EC7184" p-id="97924"></path> |
| | | </svg> |
| | | <!-- 错误 --> |
| | | <svg t="1718283143947" class="icon" viewBox="0 0 1024 1024" version="1.1" |
| | | xmlns="http://www.w3.org/2000/svg" p-id="110219" xmlns:xlink="http://www.w3.org/1999/xlink" |
| | | width="20" height="20" v-if="isRight == false"> |
| | | <path d="M512 512m-512 0a512 512 0 1 0 1024 0 512 512 0 1 0-1024 0Z" fill="#F9DF1E" p-id="110220"></path> |
| | | <path |
| | | d="M704.984615 433.230769h-7.876923c-27.569231-7.876923-106.338462-47.261538-86.646154-90.584615 11.815385-35.446154 110.276923-59.076923 165.415385-70.892308 11.815385-3.938462 19.692308 3.938462 23.630769 15.753846 3.938462 11.815385-3.938462 19.692308-15.753846 23.63077-66.953846 11.815385-129.969231 35.446154-137.846154 47.261538 3.938462 7.876923 35.446154 27.569231 63.015385 39.384615 11.815385 3.938462 15.753846 15.753846 11.815385 27.569231-3.938462 3.938462-7.876923 7.876923-15.753847 7.876923z" |
| | | fill="#542913" p-id="110221"></path> |
| | | <path |
| | | d="M797.198342 462.421106a78.769231 39.384615 56.995 1 0 66.057691-42.906563 78.769231 39.384615 56.995 1 0-66.057691 42.906563Z" |
| | | fill="#4DCEFF" p-id="110222"></path> |
| | | <path |
| | | d="M512 707.465846m-157.538462 0a157.538462 157.538462 0 1 0 315.076924 0 157.538462 157.538462 0 1 0-315.076924 0Z" |
| | | fill="#542913" p-id="110223"></path> |
| | | <path |
| | | d="M393.846154 809.865846v-11.815384c7.876923-59.076923 59.076923-98.461538 118.153846-94.523077 59.076923-3.938462 110.276923 35.446154 118.153846 94.523077v11.815384c-59.076923 63.015385-157.538462 70.892308-220.553846 11.815385-7.876923 0-11.815385-3.938462-15.753846-11.815385z" |
| | | fill="#EA3B3B" p-id="110224"></path> |
| | | <path |
| | | d="M319.015385 433.230769c-7.876923 0-15.753846-3.938462-19.692308-11.815384-3.938462-11.815385 0-19.692308 11.815385-23.63077 31.507692-11.815385 63.015385-35.446154 63.015384-43.323077-7.876923-11.815385-70.892308-31.507692-137.846154-43.323076-11.815385-3.938462-15.753846-15.753846-15.753846-23.63077 3.938462-11.815385 11.815385-19.692308 23.630769-15.753846 55.138462 11.815385 153.6 35.446154 165.415385 70.892308 15.753846 47.261538-63.015385 82.707692-86.646154 90.584615h-3.938461z" |
| | | fill="#542913" p-id="110225"></path> |
| | | <path |
| | | d="M145.776323 508.859333a39.384615 78.769231 33.005 1 0 85.813125-132.115383 39.384615 78.769231 33.005 1 0-85.813125 132.115383Z" |
| | | fill="#4DCEFF" p-id="110226"></path> |
| | | </svg> |
| | | </li> |
| | | <li class="show-answer-box"> |
| | | <div>答案:</div> |
| | | <div> |
| | | <img :src="question.answerImg" alt="" class="w100" /> |
| | | </div> |
| | | </li> |
| | | </ul> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | scrollTop: 0, |
| | | debounce: false, |
| | | checkItem: null, |
| | | checkItemIndex:null |
| | | checkItemIndex: null, |
| | | isShowAnswer: false, |
| | | isRight: null, |
| | | value: [], |
| | | pageNum: null, |
| | | }; |
| | | }, |
| | | props: { |
| | |
| | | }; |
| | | }, |
| | | }, |
| | | value: { |
| | | type: Array, |
| | | default: () => { |
| | | return []; |
| | | }, |
| | | }, |
| | | item: { |
| | | question: { |
| | | type: Object, |
| | | default: () => { |
| | | return []; |
| | | }, |
| | | }, |
| | | primaryColor: { |
| | | type: String, |
| | | default: "#fff", |
| | | }, |
| | | bordercolor:{ |
| | | type:String, |
| | | default:'#f49a4c' |
| | | } |
| | | }, |
| | | watch: { |
| | | rawData: { |
| | |
| | | }, |
| | | }, |
| | | mounted() { |
| | | // 获取当前页码,用于匹配本次存储题目数据 |
| | | this.pageNum = this.handlePage(); |
| | | // 添加滚动事件 监听 解决因为滚动引起的拖动线不对的问题 |
| | | window.addEventListener( |
| | | "scroll", |
| | |
| | | this.$nextTick(() => { |
| | | this.drawing(); |
| | | }); |
| | | this.getAnswer(); |
| | | }, |
| | | methods: { |
| | | init() { |
| | |
| | | }, |
| | | // 触摸结束 |
| | | touchend(e, index) { |
| | | console.log("抬起", e,this.checkItem); |
| | | this.isDragging = false; |
| | | if (this.item.showAnswer) { |
| | | if (this.question.showAnswer) { |
| | | return false; |
| | | } |
| | | // let event = e.changedTouches[0]; |
| | | // document.elementFromPoint 重点,根据x,y坐标 取当前元素 所有能运行的逻辑 都依托于这里。 |
| | | let dom = document.elementFromPoint(e.pageX, e.pageY); |
| | | let dom = (this.container ? this.container : document).elementFromPoint( |
| | | e.pageX, |
| | | e.pageY |
| | | ); |
| | | // 右边的dom是哪个 |
| | | let right = this.rightDom.find((r) => r.bom === dom); |
| | | // 不管是哪个都清除掉 底部的线 |
| | |
| | | }; |
| | | }) |
| | | .filter((r) => r.right !== undefined); |
| | | // this.$emit("input", model); |
| | | this.item.userChoise = model; |
| | | this.$emit("input", model); |
| | | this.question.userChoise = model; |
| | | // console.log(JSON.stringify(model)); |
| | | }, |
| | | // 触摸开始 |
| | | touchstart(e, item,index) { |
| | | touchstart(e, item, index) { |
| | | this.isDragging = true; |
| | | console.log("按下", e); |
| | | this.checkItem = item |
| | | this.checkItemIndex = index |
| | | this.checkItem = item; |
| | | this.checkItemIndex = index; |
| | | e.stopPropagation(); |
| | | // let event = e.targetTouches[0]; |
| | | item.line = [ |
| | |
| | | // touchmove(e, item) { |
| | | // if(!this.isDragging) return false |
| | | // console.log('移动',e); |
| | | // if (this.item.showAnswer) { |
| | | // if (this.question.showAnswer) { |
| | | // return false; |
| | | // } |
| | | // // let event = e.targetTouches[0]; |
| | |
| | | // 移动中 |
| | | mousemove(e) { |
| | | if (!this.isDragging) return false; |
| | | if (this.item.showAnswer) { |
| | | if (this.question.showAnswer) { |
| | | return false; |
| | | } |
| | | console.log('移动',e); |
| | | this.checkItem.line[2] = e.pageX; |
| | | this.checkItem.line[3] = |
| | | e.pageY - this.$refs.connect.getBoundingClientRect().y + this.scrollTop; |
| | |
| | | canvasA.lineWidth = 2; |
| | | for (let i = 0; i < this.leftArr.length; i++) { |
| | | const line = this.leftArr[i].line; |
| | | console.log(line); |
| | | console.log(this.leftArr[i]); |
| | | // console.log(line); |
| | | // console.log(this.leftArr[i]); |
| | | if (line.length) { |
| | | canvasA.moveTo(line[0], line[1]); |
| | | canvasA.lineTo(line[2], line[3]); |
| | |
| | | let rightY = rightEvent.offsetTop + rightEvent.clientHeight / 2; |
| | | return [leftX, leftY, rightX, rightY]; |
| | | }, |
| | | mouseup() { |
| | | console.log("大盒子抬起", this.isDragging); |
| | | this.isDragging = false; |
| | | areArraysEqual(array1, array2) { |
| | | // 如果两个数组长度不同,则它们不等 |
| | | if (array1.length !== array2.length) { |
| | | return false; |
| | | } |
| | | |
| | | // 遍历数组并比较每个对象的属性 |
| | | for (let i = 0; i < array1.length; i++) { |
| | | const obj1 = array1[i]; |
| | | const obj2 = array2[i]; |
| | | |
| | | // 如果对象的left或right属性不相等,则数组不等 |
| | | if (obj1.left !== obj2.left || obj1.right !== obj2.right) { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | // 如果所有对象都匹配,则数组相等 |
| | | return true; |
| | | }, |
| | | // 查看答案 |
| | | handleAnswer() { |
| | | this.isShowAnswer = !this.isShowAnswer; |
| | | }, |
| | | // 提交 |
| | | submitData() { |
| | | const answerArr = []; |
| | | const values = this.question.options.values; |
| | | for (let index = 0; index < values.length; index++) { |
| | | const item = values[index]; |
| | | const rightIndex = this.question.options.linkValues.findIndex( |
| | | (citem) => citem.oldId == item.oldId |
| | | ); |
| | | |
| | | answerArr.push({ |
| | | left: index, |
| | | right: rightIndex, |
| | | }); |
| | | } |
| | | console.log(this.question.userChoise,answerArr); |
| | | this.isRight = this.areArraysEqual(this.question.userChoise, answerArr); |
| | | this.isShowAnswer = true; |
| | | }, |
| | | // 获取当前页码 |
| | | handlePage() { |
| | | let pageNum = null; |
| | | const element = ( |
| | | this.container ? this.container : document |
| | | ).querySelector("matching"); |
| | | if (element) { |
| | | pageNum = this.getParentWithClass(element, "page-box").getAttribute( |
| | | "page" |
| | | ); |
| | | } |
| | | return pageNum; |
| | | }, |
| | | getParentWithClass(element, className) { |
| | | while (element.parentElement) { |
| | | element = element.parentElement; |
| | | if (element.classList.contains(className)) { |
| | | return element; |
| | | } |
| | | } |
| | | }, |
| | | // 获取本地存储题目答案 |
| | | getAnswer() { |
| | | const data = localStorage.getItem( |
| | | this.config.activeBook.name + "-matching-" + this.pageNum |
| | | ); |
| | | if (data) { |
| | | this.value = JSON.parse(data); |
| | | } |
| | | }, |
| | | // 保存 |
| | | saveData() { |
| | | if (this.question.userChoise.length) |
| | | localStorage.setItem( |
| | | this.config.activeBook.name + "-matching-" + this.pageNum, |
| | | JSON.stringify(this.question.userChoise) |
| | | ); |
| | | // console.log('保存成功',this.config.activeBook.name,this.pageNum); |
| | | }, |
| | | // 重做 |
| | | redo() { |
| | | this.question.showAnswer = false; |
| | | localStorage.removeItem( |
| | | this.config.activeBook.name + "-matching-" + this.pageNum |
| | | ); |
| | | this.value = []; |
| | | for (let index = 0; index < this.leftArr.length; index++) { |
| | | const item = this.leftArr[index]; |
| | | item.value = []; |
| | | item.line = []; |
| | | } |
| | | this.leftArr; |
| | | this.drawing(); |
| | | this.isShowAnswer = false; |
| | | this.isRight = null |
| | | }, |
| | | }, |
| | | }; |
| | |
| | | text-align: center; |
| | | |
| | | &-item { |
| | | cursor: pointer; |
| | | z-index: 2; |
| | | // display: inline-flex; |
| | | padding: 10px; |
| | | border-radius: 4px; |
| | | box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); |
| | | margin-bottom: 20px; |
| | | line-height: 40px; |
| | | padding: 20px 0; |
| | | line-height: 24px; |
| | | padding: 6px; |
| | | } |
| | | |
| | | &-item:last-child { |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | .tl-le { |
| | | text-align: left; |
| | | } |
| | | .connect { |
| | | -webkit-user-select: none; /* Safari */ |
| | | -moz-user-select: none; /* Firefox */ |
| | | -ms-user-select: none; /* IE10+/Edge */ |
| | | user-select: none; /* 标准语法 */ |
| | | } |
| | | .show-answer { |
| | | margin: 30px auto; |
| | | width: 100%; |
| | | height: min-content; |
| | | box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); |
| | | li { |
| | | padding: 10px; |
| | | } |
| | | } |
| | | .btn-bottom { |
| | | width: 70%; |
| | | margin: 70px auto 0 auto; |
| | | display: flex; |
| | | justify-content: space-evenly; |
| | | flex-wrap: wrap; |
| | | .el-button { |
| | | margin-top: 10px; |
| | | } |
| | | } |
| | | .el-button { |
| | | height: 30px; |
| | | padding: 7px; |
| | | min-width: 78px; |
| | | } |
| | | .answer-box-item { |
| | | /deep/ .un1 { |
| | | -webkit-text-emphasis-style: dot; |
| | | -moz-text-emphasis-style: dot; |
| | | -ms-text-emphasis-style: dot; |
| | | text-emphasis-style: dot; |
| | | -webkit-text-emphasis-position: under; |
| | | -moz-text-emphasis-position: under; |
| | | -ms-text-emphasis-position: under; |
| | | text-emphasis-position: under; |
| | | } |
| | | } |
| | | </style> |