|  | @@ -0,0 +1,189 @@
 | 
	
		
			
				|  |  | +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({
 | 
	
		
			
				|  |  | +      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 = 1
 | 
	
		
			
				|  |  | +      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)
 | 
	
		
			
				|  |  | +    //   }
 | 
	
		
			
				|  |  | +    // }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    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]}>
 | 
	
		
			
				|  |  | +          <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}></canvas>
 | 
	
		
			
				|  |  | +        </div>
 | 
	
		
			
				|  |  | +      </div>
 | 
	
		
			
				|  |  | +    )
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +})
 |