|
@@ -0,0 +1,209 @@
|
|
|
+import { Tag, Image, Button } from 'vant'
|
|
|
+import { defineComponent, nextTick, onMounted, PropType, reactive } from 'vue'
|
|
|
+import { labelOptions } from '../../unit'
|
|
|
+import styles from './index.module.less'
|
|
|
+import Sortable from 'sortablejs'
|
|
|
+import deepClone from '@/helpers/deep-clone'
|
|
|
+import { useRect } from '@vant/use'
|
|
|
+
|
|
|
+// 单选和多选题
|
|
|
+export default defineComponent({
|
|
|
+ name: 'keep-look-question',
|
|
|
+ props: {
|
|
|
+ value: {
|
|
|
+ type: [String, Number, Array],
|
|
|
+ default: ''
|
|
|
+ },
|
|
|
+ type: {
|
|
|
+ type: String as PropType<'radio' | 'checkbox'>,
|
|
|
+ default: 'radio'
|
|
|
+ },
|
|
|
+ answers: {
|
|
|
+ type: Object,
|
|
|
+ default: {}
|
|
|
+ },
|
|
|
+ /* 只读 */
|
|
|
+ readOnly: {
|
|
|
+ type: Boolean,
|
|
|
+ default: true
|
|
|
+ }
|
|
|
+ },
|
|
|
+ emits: ['update:value'],
|
|
|
+ setup(props, { emit }) {
|
|
|
+ const state = reactive({
|
|
|
+ answerDomId: 'answer' + +new Date(),
|
|
|
+ answerObj: {
|
|
|
+ height: 100,
|
|
|
+ width: 100
|
|
|
+ },
|
|
|
+ canvasDomId: 'canvas' + +new Date(),
|
|
|
+ sortable: null as any,
|
|
|
+ list: [] as any,
|
|
|
+ options: [
|
|
|
+ {
|
|
|
+ index: 1,
|
|
|
+ value: 'Sol',
|
|
|
+ left: false,
|
|
|
+ right: false,
|
|
|
+ locked: false // 是否已经连线
|
|
|
+ },
|
|
|
+ {
|
|
|
+ index: 2,
|
|
|
+ value: 'Sal',
|
|
|
+ left: false,
|
|
|
+ right: false,
|
|
|
+ locked: false
|
|
|
+ },
|
|
|
+ {
|
|
|
+ index: 3,
|
|
|
+ value: 'La',
|
|
|
+ left: false,
|
|
|
+ right: false,
|
|
|
+ locked: false
|
|
|
+ },
|
|
|
+ {
|
|
|
+ index: 4,
|
|
|
+ value: 'Si',
|
|
|
+ left: false,
|
|
|
+ right: false,
|
|
|
+ locked: false
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ selectItem: [] as any
|
|
|
+ })
|
|
|
+
|
|
|
+ const onLeftClick = (e: any, item: any) => {
|
|
|
+ const obj = useRect(e.target)
|
|
|
+ console.log(e, obj)
|
|
|
+ state.options.forEach((item: any) => {
|
|
|
+ item.left = false
|
|
|
+ })
|
|
|
+ item.left = !item.left
|
|
|
+
|
|
|
+ // 为true时添加定位
|
|
|
+ if (item.left) {
|
|
|
+ state.selectItem[0] = obj
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const onRightClick = (e: any, item: any) => {
|
|
|
+ const obj = useRect(e.target)
|
|
|
+ console.log(e, obj)
|
|
|
+ state.options.forEach((item: any) => {
|
|
|
+ item.right = false
|
|
|
+ })
|
|
|
+ item.right = !item.right
|
|
|
+
|
|
|
+ // 为true时添加定位
|
|
|
+ if (item.right) {
|
|
|
+ state.selectItem[1] = obj
|
|
|
+
|
|
|
+ if (state.selectItem.length >= 2) {
|
|
|
+ drawLine()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const drawLine = () => {
|
|
|
+ const canvas: any = document.getElementById(state.canvasDomId)
|
|
|
+ const canvasPostion = useRect(canvas)
|
|
|
+ console.log(canvasPostion, 'canvasPostion')
|
|
|
+
|
|
|
+ const firstPostion = state.selectItem[0]
|
|
|
+ const secondPostion = state.selectItem[1]
|
|
|
+
|
|
|
+ const startPoint = {
|
|
|
+ x: firstPostion.width,
|
|
|
+ y: firstPostion.top + firstPostion.height / 2 - canvasPostion.top
|
|
|
+ }
|
|
|
+
|
|
|
+ const endPoint = {
|
|
|
+ x: secondPostion.left - canvasPostion.left,
|
|
|
+ y: secondPostion.top + secondPostion.height / 2 - canvasPostion.top
|
|
|
+ }
|
|
|
+
|
|
|
+ const ctx = canvas.getContext('2d')
|
|
|
+ console.log(startPoint, endPoint, ctx)
|
|
|
+
|
|
|
+ ctx.beginPath()
|
|
|
+ ctx.moveTo(startPoint.x, startPoint.y)
|
|
|
+ ctx.lineTo(endPoint.x, endPoint.y)
|
|
|
+ ctx.lineWidth = 2
|
|
|
+ ctx.strokeStyle = '#FF8057'
|
|
|
+ ctx.stroke()
|
|
|
+ }
|
|
|
+
|
|
|
+ // const onSelect = (item: any) => {
|
|
|
+ // if (props.type === 'checkbox') {
|
|
|
+ // // 判断是否已选过
|
|
|
+ // const value: any = props.value
|
|
|
+ // if (value.includes(item.index)) {
|
|
|
+ // const index = value.findIndex((v: any) => v === item.index)
|
|
|
+ // value.splice(index, 1)
|
|
|
+ // emit('update:value', [...value])
|
|
|
+ // } else {
|
|
|
+ // emit('update:value', [item.index, ...value])
|
|
|
+ // }
|
|
|
+ // } else {
|
|
|
+ // emit('update:value', item.index)
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+
|
|
|
+ onMounted(() => {
|
|
|
+ const answer: any = document.getElementById(state.answerDomId)
|
|
|
+ const { width, height } = useRect(answer)
|
|
|
+ console.log(width, height)
|
|
|
+ state.answerObj = {
|
|
|
+ height,
|
|
|
+ width
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ return () => (
|
|
|
+ <div class={styles.unitSubject}>
|
|
|
+ <div class={styles.unitSubjectTitle}>
|
|
|
+ 1、选出与方框内音符时值相同的节奏阶段 <span class={styles.unitScore}>(5分)</span>
|
|
|
+ <Tag type="primary">连连看</Tag>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <Image
|
|
|
+ class={styles.unitTitleImg}
|
|
|
+ src="https://lanhu-dds-backend.oss-cn-beijing.aliyuncs.com/merge_image/imgs/dbb27307d428424c8efb9f26032cfa1a_mergeImage.png"
|
|
|
+ />
|
|
|
+
|
|
|
+ <div class={[styles.unitAnswers]} id={state.answerDomId}>
|
|
|
+ <div class={styles.leftSection}>
|
|
|
+ {state.options.map((item: any) => (
|
|
|
+ <div
|
|
|
+ class={[styles.unitItem, item.left && styles.active]}
|
|
|
+ onClick={(e: any) => onLeftClick(e, item)}
|
|
|
+ >
|
|
|
+ <Image
|
|
|
+ src="https://lanhu-dds-backend.oss-cn-beijing.aliyuncs.com/merge_image/imgs/dbb27307d428424c8efb9f26032cfa1a_mergeImage.png"
|
|
|
+ class={styles.img}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ <div class={styles.rightSection}>
|
|
|
+ {state.options.map((item: any) => (
|
|
|
+ <div
|
|
|
+ class={[styles.unitItem, item.right && styles.active]}
|
|
|
+ onClick={(e: any) => onRightClick(e, item)}
|
|
|
+ >
|
|
|
+ Re{item.index}
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <canvas
|
|
|
+ id={state.canvasDomId}
|
|
|
+ class={styles.canvasSection}
|
|
|
+ width={state.answerObj.width}
|
|
|
+ height={state.answerObj.height}
|
|
|
+ ></canvas>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }
|
|
|
+})
|