瀏覽代碼

添加拖拽

lex 10 月之前
父節點
當前提交
980d58fa2b

+ 25 - 1
src/views/tempo-practice/index.module.less

@@ -160,6 +160,8 @@
     }
   }
 
+
+
   .beat {
     display: flex;
     align-items: center;
@@ -173,6 +175,20 @@
     background: #FFFFFF;
     position: relative;
 
+
+    &>div {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      flex: 1;
+    }
+
+    :global {
+      .sortable-chosen.sortable-ghost {
+        display: none !important;
+      }
+    }
+
     .direction {
       position: absolute;
       left: 0;
@@ -232,6 +248,14 @@
       transform: rotate(180deg);
     }
   }
+
+  :global {
+    .onstart {
+      .sortable-chosen.sortable-ghost {
+        display: inherit !important;
+      }
+    }
+  }
 }
 
 .footer {
@@ -581,4 +605,4 @@
       transition: all 0.03s ease;
     }
   }
-}
+}

+ 115 - 69
src/views/tempo-practice/index.tsx

@@ -43,6 +43,7 @@ import useDrag from '@/hooks/useDrag';
 import useDragGuidance from '@/hooks/useDrag/useDragGuidance';
 import { state as stateData } from '@/state';
 import SettingPcModal from './setting-pc-modal';
+import Draggable from 'vuedraggable';
 
 export default defineComponent({
   name: 'tempo-practice',
@@ -90,6 +91,8 @@ export default defineComponent({
       dataJson: {} as any,
       playPos: (route.query.imagePos || 'left') as 'left' | 'right' // 数字课堂老师端上课 镜像字段
     });
+    // 拖拽临时数据
+    const tempDragData = ref<any>({});
     // 返回
     const goback = (e: any) => {
       e.stopPropagation();
@@ -396,37 +399,55 @@ export default defineComponent({
                       styles.small
                   ]}>
                   {item.map((child: any, jIndex: number) => (
-                    <div
-                      class={[
-                        styles.beat,
-                        child.selected ? styles.active : '',
-                        state.settingStatus && styles.disabledChange
-                      ]}
-                      // draggable={true}
-                      // onDragenter={(e: any) => {
-                      //   e.preventDefault();
-                      // }}
-                      // onDragover={(e: any) => {
-                      //   e.preventDefault();
-                      // }}
-                      // onDrop={(e: any) => {
-                      //   let dropItem = e.dataTransfer.getData('text');
-                      //   dropItem = dropItem ? JSON.parse(dropItem) : {};
-                      //   // 判断是否有数据
-                      //   if (dropItem.url) {
-                      //     handleStop();
-                      //     setting_modal.scorePart.forEach(
-                      //       (part: Array<any>, ci: number) => {
-                      //         part.forEach((child: any, cj: number) => {
-                      //           if (i === ci && jIndex === cj) {
-                      //             child.url = dropItem.url;
-                      //             child.index = dropItem.index;
-                      //           }
-                      //         });
-                      //       }
-                      //     );
-                      //   }
-                      // }}
+                    <Draggable
+                      modelValue={[child]}
+                      itemKey="index"
+                      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+                      // @ts-ignore
+                      group={{
+                        name: 'description',
+                        pull: 'clone',
+                        put: true
+                      }}
+                      animation={200}
+                      sort={false}
+                      componentData={{
+                        draggable: 'row-nav',
+                        itemKey: 'index',
+                        tag: 'div',
+                        pull: 'clone',
+                        put: true,
+                        animation: 200,
+                        group: 'description'
+                      }}
+                      onChange={(evt: any) => {
+                        tempDragData.value = evt.added || '';
+                      }}
+                      onAdd={() => {
+                        const added = tempDragData.value?.element || {};
+                        // 判断是否有数据
+                        if (added.url && added.sourceFrom === 'setting-modal') {
+                          handleStop();
+                          setting_modal.scorePart.forEach(
+                            (part: Array<any>, ci: number) => {
+                              part.forEach((child: any, cj: number) => {
+                                if (i === ci && jIndex === cj) {
+                                  child.url = added.url;
+                                  child.index = added.index;
+                                }
+                              });
+                            }
+                          );
+                        }
+                      }}
+                      onStart={(evt: any) => {
+                        evt.from.classList.add('onstart');
+                        tempDragData.value = {};
+                      }}
+                      onEnd={(evt: any) => {
+                        evt.from.classList.remove('onstart');
+                        tempDragData.value = {};
+                      }}
                       onClick={(e: any) => {
                         e.stopPropagation();
                         // 编辑时可以操作
@@ -438,44 +459,69 @@ export default defineComponent({
                             initSelectScorePartModal(i, jIndex);
                           }
                         }
-                      }}>
-                      {/* 编辑时不可上下切换 */}
-                      {!state.settingStatus && (
-                        <div class={styles.direction}>
-                          <div
-                            class={styles.up}
-                            style={{ cursor: 'pointer' }}
-                            onClick={() => {
-                              if (setting.playState === 'play') return;
-                              if (setting.tempo.length <= 1) {
-                                showToast('无法切换,请选择至少2种节奏型');
-                                return;
-                              }
-                              // const obj = randomScoreElement(child.index);
-                              const obj = elementDirection('up', child.index);
-                              child.index = obj.index;
-                              child.url = obj.url;
-                            }}></div>
-                          <div
-                            class={styles.down}
-                            style={{ cursor: 'pointer' }}
-                            onClick={() => {
-                              if (setting.playState === 'play') return;
-                              if (setting.tempo.length <= 1) {
-                                showToast('无法切换,请选择至少2种节奏型');
-                                return;
-                              }
-                              // const obj = randomScoreElement(child.index);
-                              const obj = elementDirection('down', child.index);
-                              child.index = obj.index;
-                              child.url = obj.url;
-                            }}></div>
-                        </div>
-                      )}
-                      <div class={styles.imgSection}>
-                        <img src={getImage(child.url)} />
-                      </div>
-                    </div>
+                      }}
+                      class={[
+                        styles.beat,
+                        child.selected ? styles.active : '',
+                        state.settingStatus && styles.disabledChange
+                      ]}>
+                      {{
+                        item: (element: any) => {
+                          const child = element.element;
+                          const jIndex = element.index;
+                          return (
+                            <div>
+                              {/* 编辑时不可上下切换 */}
+                              {!state.settingStatus && (
+                                <div class={styles.direction}>
+                                  <div
+                                    class={styles.up}
+                                    style={{ cursor: 'pointer' }}
+                                    onClick={() => {
+                                      if (setting.playState === 'play') return;
+                                      if (setting.tempo.length <= 1) {
+                                        showToast(
+                                          '无法切换,请选择至少2种节奏型'
+                                        );
+                                        return;
+                                      }
+                                      // const obj = randomScoreElement(child.index);
+                                      const obj = elementDirection(
+                                        'up',
+                                        child.index
+                                      );
+                                      child.index = obj.index;
+                                      child.url = obj.url;
+                                    }}></div>
+                                  <div
+                                    class={styles.down}
+                                    style={{ cursor: 'pointer' }}
+                                    onClick={() => {
+                                      if (setting.playState === 'play') return;
+                                      if (setting.tempo.length <= 1) {
+                                        showToast(
+                                          '无法切换,请选择至少2种节奏型'
+                                        );
+                                        return;
+                                      }
+                                      // const obj = randomScoreElement(child.index);
+                                      const obj = elementDirection(
+                                        'down',
+                                        child.index
+                                      );
+                                      child.index = obj.index;
+                                      child.url = obj.url;
+                                    }}></div>
+                                </div>
+                              )}
+                              <div class={styles.imgSection}>
+                                <img src={getImage(child.url)} />
+                              </div>
+                            </div>
+                          );
+                        }
+                      }}
+                    </Draggable>
                   ))}
                 </div>
               ))}

+ 60 - 27
src/views/tempo-practice/setting-modal/index.tsx

@@ -26,7 +26,7 @@ import { hendleEndBeat } from '../beat-tick';
 import { useRoute } from 'vue-router';
 import settingArrowActive from '../images/setting-arrow-active.png';
 import settingArrowDefault from '../images/setting-arrow-default.png';
-import deepClone from '@/helpers/deep-clone';
+import Draggable from 'vuedraggable';
 
 export default defineComponent({
   emits: ['close'],
@@ -177,6 +177,18 @@ export default defineComponent({
       emit('close');
     };
 
+    const tempoListData = computed(() => {
+      const list = Object.keys(tempoList.value);
+      return list.map(key => {
+        return {
+          index: key,
+          key: key,
+          url: getBeatUrl(key),
+          sourceFrom: 'setting-modal'
+        };
+      });
+    });
+
     expose({
       onSubmit
     });
@@ -308,32 +320,53 @@ export default defineComponent({
                 default: () => (
                   <>
                     {/* <div class={styles.parmaTitle}>节奏型筛选</div> */}
-                    <div class={[styles.paramContent, styles.tempo]}>
-                      {Object.keys(tempoList.value).map((item: any) => (
-                        <div
-                          draggable={true}
-                          onDragstart={(e: any) => {
-                            // console.log('1111');
-                            e.dataTransfer.setData(
-                              'text',
-                              JSON.stringify({
-                                index: item,
-                                url: getBeatUrl(item)
-                              })
-                            );
-                          }}
-                          onClick={() => onChangeTempo(item)}>
-                          <img
-                            class={'draggable'}
-                            // class={state.tempo.includes(item) && styles.active}
-                            src={getImage(
-                              (state.element === 'jianpu' ? 'j-' : 'f-') +
-                                tempoList.value[item]
-                            )}
-                          />
-                        </div>
-                      ))}
-                    </div>
+
+                    <Draggable
+                      modelValue={tempoListData.value}
+                      itemKey="id"
+                      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+                      // @ts-ignore
+                      // group="description"
+                      group={{
+                        name: 'description',
+                        pull: 'clone',
+                        put: false
+                      }}
+                      animation={200}
+                      sort={false}
+                      onMove={(evt: any) => {
+                        return evt.from !== evt.to;
+                      }}
+                      componentData={{
+                        draggable: 'row-nav',
+                        itemKey: 'id',
+                        tag: 'div',
+                        pull: 'clone',
+                        put: false,
+                        animation: 200,
+                        group: 'description'
+                      }}
+                      class={[styles.paramContent, styles.tempo]}>
+                      {{
+                        item: (element: any) => {
+                          const item = element.element;
+                          return (
+                            <div
+                              data-id={item.key}
+                              onClick={() => onChangeTempo(item.key)}>
+                              <img
+                                class={'draggable'}
+                                // class={state.tempo.includes(item) && styles.active}
+                                src={getImage(
+                                  (state.element === 'jianpu' ? 'j-' : 'f-') +
+                                    tempoList.value[item.key]
+                                )}
+                              />
+                            </div>
+                          );
+                        }
+                      }}
+                    </Draggable>
                   </>
                 )
               }}