bianjiang 1 year ago
parent
commit
dd2c725af9

+ 65 - 303
src/modules/list/actions/canvas.ts

@@ -1,166 +1,110 @@
 // import item from "@/pages/website/routes/list/item";
+import { cloneDeep } from "lodash";
 import ListModule from "..";
 import { ShowItem, ColDataType } from "../objects/item";
+import { InitCanvasDragEvent, ListDraw } from "../objects/canvas";
 
-const cols: ColDataType[] = []; //{offset, items:[], halfOffset: 0, dragging: false}
-
-let CanvasWidth = 0;
-let CanvasHeight = 0;
-const textH = 0;
-let paddingOffset = 0;
-let totalSizeCount = 0; //每行或每列的数量
-let itemOffset = 0;
-
-let ctx: CanvasRenderingContext2D | null;
-let scale = 1;
-function listDraw(this: ListModule, col: ColDataType, row: number, ctx: any) {
-  const scrollType = this.store.scrollType;
-  let x = 0,
-    y = 0;
-  const offseStep = itemOffset + paddingOffset;
-
-  if (scrollType == "vertical") {
-    x = row > 0 ? Math.floor(row * offseStep) + paddingOffset : paddingOffset;
-    y = col.offset + CanvasHeight;
-  }
-  if (scrollType == "horizontal") {
-    x = col.offset + CanvasWidth;
-    y = row > 0 ? Math.floor(row * offseStep) + paddingOffset : paddingOffset;
-  }
-
-  const items = col.items;
-  const total = items.length;
-
-  for (let k = 0; k < total; k++) {
-    //绘制
-    const item = items[k];
-
-    if (scrollType == "vertical") {
-      y -= item.offsetY; //从下往上绘制
-      if (y > CanvasHeight || y < -item.offsetY) continue; //超出部分,不进行绘制提交
-      ctx.drawImage(
-        item.img,
-        0,
-        0,
-        item.w,
-        item.h,
-        Math.floor(x),
-        Math.floor(y),
-        Math.floor(itemOffset),
-        Math.floor(item.offsetY - textH - paddingOffset)
-      );
-    }
-    if (scrollType == "horizontal") {
-      x -= item.offsetX;
-      if (x > CanvasWidth || x < -item.offsetX) continue;
-      ctx.drawImage(
-        item.img,
-        0,
-        0,
-        item.w,
-        item.h,
-        Math.floor(x),
-        Math.floor(y),
-        Math.floor(item.offsetX - textH - paddingOffset),
-        Math.floor(itemOffset)
-      );
-    }
-
-    // let text =
-    //   item.name.length > 20
-    //     ? item.name.substring(0, 19) + "..."
-    //     : item.name;
-    // ctx.fillText(text, x, Math.round(y + item.offsetY - textH * 1.2));
-  }
-}
 export default ListModule.action({
-  async initListCanvasDatas(wWidth: number, wHeight: number) {
-    const totalRow = this.store.totalRow;
-    const scrollType = this.store.scrollType;
-    const items = await this.actions.loadData(wWidth, wHeight);
-    scale = Math.max(devicePixelRatio, 2);
-
-    // textH = 24 * scale;
-    CanvasWidth = wWidth * scale;
-    CanvasHeight = wHeight * scale;
-    paddingOffset = 12 * scale;
-    totalSizeCount = Math.ceil(items.length / totalRow) * 2;
+  async initListCanvasData(wWidth: number, wHeight: number) {
+    const totalLines = this.store.animate.totalLines;
+    const scrollType = this.store.animate.scrollType;
+    const items = await this.actions.loadData();
+    const scale = Math.max(devicePixelRatio, 2);
+
+    const canvas = {
+      width: wWidth * scale,
+      height: wHeight * scale,
+      padding: this.store.canvas.padding * scale,
+      linesCount: Math.ceil(items.length / totalLines) * 2,
+    };
+    this.store.canvas = { ...this.store.canvas, ...canvas };
 
     if (scrollType == "vertical") {
-      this.actions.initVerticalList(items);
+      await this.actions.initVerticalList(items);
     }
     if (scrollType == "horizontal") {
-      this.actions.initHorizontalList(items);
+      await this.actions.initHorizontalList(items);
     }
   },
-  initVerticalList(items) {
-    const totalRow = this.store.totalRow;
-    itemOffset = (CanvasWidth - paddingOffset * (totalRow + 1)) / totalRow;
-    for (let i = 0; i < totalRow; i++) {
-      const off = i * totalSizeCount;
+  async initVerticalList(items) {
+    const totalLines = this.store.animate.totalLines;
+    const canvas = cloneDeep(this.store.canvas);
+    const itemOffset =
+      (canvas.width - canvas.padding * (totalLines + 1)) / totalLines;
+    this.store.canvas.itemOffset = itemOffset;
+    const lines = [];
+    for (let i = 0; i < totalLines; i++) {
+      const off = i * canvas.linesCount;
       const arr: ShowItem[] = [];
-      for (let k = 0; k < totalSizeCount; k++) {
+      for (let k = 0; k < canvas.linesCount; k++) {
         arr.push(items[(off + k) % items.length]);
       }
-      this.actions.shuffleSelf(arr, totalSizeCount);
+      this.actions.shuffleSelf(arr, totalLines);
       //计算总高度
       let halfOffset = 0;
       arr.forEach((item) => {
         const h = ((item.h * 1.0) / item.w) * itemOffset;
-        item.offsetY = h + textH + paddingOffset; //y step;
+        item.offsetY = h + canvas.padding;
         halfOffset += item.offsetY;
       });
 
-      const colData = {
+      const linesItem = {
         items: [...arr, ...arr],
         offset: 0,
         halfOffset: halfOffset,
         dragging: false,
         speed: i % 2 == 0 ? 1 : 2,
       };
-      cols.push(colData);
+      lines.push(linesItem);
     }
+    this.store.canvas.linesData = lines;
   },
-  initHorizontalList(items) {
-    const totalRow = this.store.totalRow;
-    itemOffset = (CanvasHeight - paddingOffset * (totalRow + 1)) / totalRow;
-    for (let i = 0; i < totalRow; i++) {
-      const off = i * totalSizeCount;
+  async initHorizontalList(items) {
+    const totalLines = this.store.animate.totalLines;
+    const canvas = cloneDeep(this.store.canvas);
+    const itemOffset =
+      (canvas.height - canvas.padding * (totalLines + 1)) / totalLines;
+    this.store.canvas.itemOffset = itemOffset;
+    const lines = [];
+    for (let i = 0; i < totalLines; i++) {
+      const off = i * totalLines;
       const arr: ShowItem[] = [];
-      for (let k = 0; k < totalSizeCount; k++) {
+      for (let k = 0; k < canvas.linesCount; k++) {
         arr.push(items[(off + k) % items.length]);
       }
-      this.actions.shuffleSelf(arr, totalSizeCount);
+      this.actions.shuffleSelf(arr, canvas.linesCount);
 
       //计算总高度
       let halfOffset = 0;
       arr.forEach((item) => {
         const w = ((item.w * 1.0) / item.h) * itemOffset;
-        item.offsetX = w + textH + paddingOffset; //y step;
+        item.offsetX = w + canvas.padding;
         halfOffset += item.offsetX;
       });
 
-      const colData = {
+      const linesItem = {
         items: [...arr, ...arr],
         offset: 0,
         halfOffset: halfOffset,
         dragging: false,
         speed: i % 2 == 0 ? 1 : 2,
       };
-      cols.push(colData);
+      lines.push(linesItem);
     }
+    this.store.canvas.linesData = lines;
   },
   async startListRunning(canvas: HTMLCanvasElement) {
-    this.actions.initDragEvents(canvas);
-    canvas.width = CanvasWidth;
-    canvas.height = CanvasHeight;
+    InitCanvasDragEvent.call(this, canvas);
+    const storeCanvas = cloneDeep(this.store.canvas);
+    canvas.width = storeCanvas.width;
+    canvas.height = storeCanvas.height;
 
-    ctx = canvas.getContext("2d");
+    const ctx = canvas.getContext("2d");
 
-    const cache = document.createElement("canvas");
-    cache.width = CanvasWidth;
-    cache.height = CanvasHeight;
-    const cacheCtx = cache.getContext("2d");
+    const cacheCanvas = document.createElement("canvas");
+    cacheCanvas.width = storeCanvas.width;
+    cacheCanvas.height = storeCanvas.height;
+    const cacheCtx = cacheCanvas.getContext("2d");
     if (!cacheCtx) {
       return;
     }
@@ -170,16 +114,16 @@ export default ListModule.action({
 
     let loopId = 0;
 
-    let n = cols.length;
+    let n = storeCanvas.linesData.length;
     let i = 0;
     let lastTime = Date.now();
     let dtaTime = 0;
     const loop = () => {
       dtaTime = Date.now() - lastTime;
       lastTime = Date.now();
-      n = cols.length;
+      n = storeCanvas.linesData.length;
       while (n--) {
-        const item = cols[n];
+        const item = storeCanvas.linesData[n];
         if (!item.dragging) {
           //没有拖拽进行累积
           item.offset = Math.floor(item.offset + item.speed);
@@ -188,198 +132,16 @@ export default ListModule.action({
         if (item.offset >= item.halfOffset) item.offset -= item.halfOffset;
         if (item.offset < 0) item.offset += item.halfOffset;
       }
-      cacheCtx?.clearRect(0, 0, CanvasWidth, CanvasHeight);
-      n = cols.length;
+      cacheCtx?.clearRect(0, 0, storeCanvas.width, storeCanvas.height);
+      n = storeCanvas.linesData.length;
       for (i = 0; i < n; i++) {
-        listDraw.call(this, cols[i], i, cacheCtx);
+        ListDraw.call(this, storeCanvas.linesData[i], i, cacheCtx);
       }
-      ctx?.clearRect(0, 0, CanvasWidth, CanvasHeight);
-      ctx?.drawImage(cache, 0, 0);
+      ctx?.clearRect(0, 0, storeCanvas.width, storeCanvas.height);
+      ctx?.drawImage(cacheCanvas, 0, 0);
       loopId = requestAnimationFrame(loop);
     };
     loop();
   },
-
-  initDragEvents(canvas: HTMLCanvasElement) {
-    let down = false;
-    let downIndex = -1;
-    let downY = 0;
-    let downX = 0;
-
-    let initOffset = 0;
-    let downTime = 0;
-    let moving = false;
-    const fingers: { [name: number]: any } = {};
-    const scrollType = this.store.scrollType;
-
-    const onMouseDown = (e: MouseEvent) => {
-      const x = e.clientX * scale;
-      const y = e.clientY * scale;
-      downY = e.clientY * scale;
-      downX = e.clientX * scale;
-      down = true;
-      downIndex =
-        scrollType == "vertical"
-          ? Math.floor(x / (itemOffset + paddingOffset))
-          : Math.floor(y / (itemOffset + paddingOffset));
-
-      cols[downIndex].dragging = true;
-      initOffset = cols[downIndex].offset;
-      downTime = Date.now();
-    };
-
-    const onMouseMove = (e: MouseEvent) => {
-      if (!down || downIndex < 0) return;
-      moving = true;
-
-      console.log("move");
-      let dtaOffset = 0;
-      if (scrollType == "vertical") {
-        dtaOffset = e.clientY * scale - dtaOffset;
-      }
-      if (scrollType == "horizontal") {
-        dtaOffset = e.clientX * scale - dtaOffset;
-      }
-
-      cols[downIndex].offset = initOffset + dtaOffset;
-    };
-    const onMouseUp = (e: MouseEvent) => {
-      console.log("up");
-      down = false;
-      if (downIndex >= 0) {
-        cols[downIndex].dragging = false;
-        const dtaTime = Date.now() - downTime;
-        if (dtaTime < 200 && !moving) {
-          const col = cols[downIndex];
-          let offset = col.offset;
-          if (offset >= col.halfOffset) offset -= col.halfOffset;
-          if (offset < 0) offset += col.halfOffset;
-
-          const n = col.items.length;
-          let z =
-            scrollType == "vertical"
-              ? offset + CanvasHeight
-              : offset + CanvasWidth;
-          for (let k = 0; k < n; k++) {
-            const item = col.items[k];
-            if (scrollType == "vertical") {
-              z -= item.offsetY;
-              if (downY > z && downY < z + item.offsetY) {
-                console.log("click->", item.name);
-                this.actions.popDialog(e, item);
-                break;
-              }
-            }
-            if (scrollType == "horizontal") {
-              z -= item.offsetX;
-              if (downX > z && downX < z + item.offsetX) {
-                console.log("click->", item.name);
-                this.actions.popDialog(e, item);
-                break;
-              }
-            }
-          }
-        }
-      }
-      downIndex = -1;
-      moving = false;
-    };
-    const onTouchstart = (e: TouchEvent) => {
-      const touches = e.touches;
-      for (let i = 0; i < touches.length; i++) {
-        const touch = touches[i];
-        if (fingers[touch.identifier]) {
-          continue;
-        }
-        const x = touch.clientX * scale;
-        const y = touch.clientY * scale;
-        const downIndex =
-          scrollType == "vertical"
-            ? Math.floor(x / (itemOffset + paddingOffset))
-            : Math.floor(y / (itemOffset + paddingOffset));
-        cols[downIndex].dragging = true;
-        const offset = cols[downIndex].offset;
-        fingers[touch.identifier] = {
-          identifier: touch.identifier,
-          downY: y,
-          downX: x,
-          downIndex: downIndex,
-          offset: offset,
-          downTime: Date.now(),
-        };
-      }
-    };
-    const onTouchMove = (e: TouchEvent) => {
-      const touches = e.changedTouches;
-      for (let i = 0; i < touches.length; i++) {
-        const touch = touches[i];
-        const finger = fingers[touch.identifier];
-        if (!finger) {
-          continue;
-        }
-        finger.moving = true;
-        let dtaOffset = 0;
-        if (scrollType == "vertical") {
-          dtaOffset = touch.clientY * scale - finger.downY;
-        }
-        if (scrollType == "horizontal") {
-          dtaOffset = touch.clientX * scale - finger.downY;
-        }
-        cols[finger.downIndex].offset = finger.offset + dtaOffset;
-      }
-    };
-
-    const onTouchEnd = (e: TouchEvent) => {
-      const touches = e.changedTouches;
-      for (let i = 0; i < touches.length; i++) {
-        const touch = touches[i];
-        const finger = fingers[touch.identifier];
-
-        if (!finger) {
-          continue;
-        }
-
-        cols[finger.downIndex].dragging = false;
-        const dtaTime = Date.now() - finger.downTime;
-        if (dtaTime < 200 && !finger.moving) {
-          const col = cols[finger.downIndex];
-          let offset = col.offset;
-          if (offset >= col.halfOffset) offset -= col.halfOffset;
-          if (offset < 0) offset += col.halfOffset;
-          const n = col.items.length;
-          let z =
-            scrollType == "vertical"
-              ? offset + CanvasHeight
-              : offset + CanvasWidth;
-          for (let k = 0; k < n; k++) {
-            const item = col.items[k];
-
-            if (scrollType == "vertical") {
-              z -= item.offsetY;
-              if (finger.downY > z && finger.downY < z + item.offsetY) {
-                this.actions.popDialog(touch, item);
-                break;
-              }
-            }
-            if (scrollType == "horizontal") {
-              z -= item.offsetX;
-              if (finger.downX > z && finger.downX < z + item.offsetX) {
-                this.actions.popDialog(touch, item);
-                break;
-              }
-            }
-          }
-        }
-        delete fingers[touch.identifier];
-      }
-    };
-
-    canvas.addEventListener("mousedown", onMouseDown, false);
-    canvas.addEventListener("mousemove", onMouseMove, false);
-    document.addEventListener("mouseup", onMouseUp, false);
-
-    canvas.addEventListener("touchstart", onTouchstart, false);
-    canvas.addEventListener("touchmove", onTouchMove, false);
-    document.addEventListener("touchend", onTouchEnd, false);
-  },
+  // loopRunning() {},
 });

+ 2 - 2
src/modules/list/actions/dialog.ts

@@ -18,8 +18,8 @@ export default ListModule.action({
     lastDialogTime = Date.now();
     lastDialogId = item.id;
 
-    const height = this.store.parentHeight;
-    const width = this.store.parentWidth;
+    const height = this.store.canvas.height;
+    const width = this.store.canvas.width;
     let x = e.clientX;
     let y = e.clientY;
     const conNum = 800 / 4 + 120;

+ 2 - 5
src/modules/list/actions/load.ts

@@ -34,7 +34,7 @@ function loadImg(url: string, id: string, name: string): Promise<ShowItem> {
 }
 export default ListModule.action({
   async initListData(wWidth: number, wHeight: number) {
-    const items = await this.actions.loadData(wWidth, wHeight);
+    const items = await this.actions.loadData();
 
     this.actions.initLoadShowItems(items);
   },
@@ -53,10 +53,7 @@ export default ListModule.action({
     arr.length = size;
     return arr;
   },
-  async loadData(wWidth: number, wHeight: number) {
-    this.store.parentWidth = wWidth;
-    this.store.parentHeight = wHeight;
-
+  async loadData() {
     const list = await this.https.loadLocal(artifacts);
     this.store.list = list.data;
     const ps = this.store.list.map((item: ItemObject, index) =>

+ 1 - 3
src/modules/list/index.ts

@@ -8,17 +8,15 @@ import { stores } from "./stores";
 export default class ListModule extends ModuleRoot {
   config = this.setConfig({
     httpConfig: {
-      baseURL:"./",
+      baseURL: "./",
     },
   });
-
   store = this.createStore([stores]);
   actions = this.createActions(actions);
   https = this.createHttps([https]);
   controls = {
     backendList: new PageListController(this.config.httpConfig),
   };
-  list: ItemObject[] = [];
 
   onReady() {
     this.controls.backendList.setCrudPrefix("/antique");

+ 260 - 0
src/modules/list/objects/canvas.ts

@@ -0,0 +1,260 @@
+import ListModule from "..";
+import { ColDataType } from "./item";
+
+export function InitCanvasDragEvent(
+  this: ListModule,
+  canvas: HTMLCanvasElement
+) {
+  let down = false;
+  let downIndex = -1;
+  let downY = 0;
+  let downX = 0;
+
+  let initOffset = 0;
+  let downTime = 0;
+  let moving = false;
+  const fingers: { [name: number]: any } = {};
+  const scrollType = this.store.animate.scrollType;
+  const canvasData = this.store.canvas;
+  const onMouseDown = (e: MouseEvent) => {
+    const x = e.clientX * canvasData.scale;
+    const y = e.clientY * canvasData.scale;
+    downY = e.clientY * canvasData.scale;
+    downX = e.clientX * canvasData.scale;
+    down = true;
+    downIndex =
+      scrollType == "vertical"
+        ? Math.floor(x / (canvasData.itemOffset + canvasData.padding))
+        : Math.floor(y / (canvasData.itemOffset + canvasData.padding));
+
+    canvasData.linesData[downIndex].dragging = true;
+    initOffset = canvasData.linesData[downIndex].offset;
+    downTime = Date.now();
+  };
+
+  const onMouseMove = (e: MouseEvent) => {
+    if (!down || downIndex < 0) return;
+    moving = true;
+
+    console.log("move");
+    let dtaOffset = 0;
+    if (scrollType == "vertical") {
+      dtaOffset = e.clientY * canvasData.scale - dtaOffset;
+    }
+    if (scrollType == "horizontal") {
+      dtaOffset = e.clientX * canvasData.scale - dtaOffset;
+    }
+
+    canvasData.linesData[downIndex].offset = initOffset + dtaOffset;
+  };
+  const onMouseUp = (e: MouseEvent) => {
+    console.log("up");
+    down = false;
+    if (downIndex >= 0) {
+      canvasData.linesData[downIndex].dragging = false;
+      const dtaTime = Date.now() - downTime;
+      if (dtaTime < 200 && !moving) {
+        const line = canvasData.linesData[downIndex];
+        let offset = line.offset;
+        if (offset >= line.halfOffset) offset -= line.halfOffset;
+        if (offset < 0) offset += line.halfOffset;
+
+        const n = line.items.length;
+        let z =
+          scrollType == "vertical"
+            ? offset + canvasData.height
+            : offset + canvasData.width;
+        for (let k = 0; k < n; k++) {
+          const item = line.items[k];
+          if (scrollType == "vertical") {
+            z -= item.offsetY;
+            if (downY > z && downY < z + item.offsetY) {
+              console.log("click->", item.name);
+              this.actions.popDialog(e, item);
+              break;
+            }
+          }
+          if (scrollType == "horizontal") {
+            z -= item.offsetX;
+            if (downX > z && downX < z + item.offsetX) {
+              console.log("click->", item.name);
+              this.actions.popDialog(e, item);
+              break;
+            }
+          }
+        }
+      }
+    }
+    downIndex = -1;
+    moving = false;
+  };
+  const onTouchstart = (e: TouchEvent) => {
+    const touches = e.touches;
+    for (let i = 0; i < touches.length; i++) {
+      const touch = touches[i];
+      if (fingers[touch.identifier]) {
+        continue;
+      }
+      const x = touch.clientX * canvasData.scale;
+      const y = touch.clientY * canvasData.scale;
+      const downIndex =
+        scrollType == "vertical"
+          ? Math.floor(x / (canvasData.itemOffset + canvasData.padding))
+          : Math.floor(y / (canvasData.itemOffset + canvasData.padding));
+      canvasData.linesData[downIndex].dragging = true;
+      const offset = canvasData.linesData[downIndex].offset;
+      fingers[touch.identifier] = {
+        identifier: touch.identifier,
+        downY: y,
+        downX: x,
+        downIndex: downIndex,
+        offset: offset,
+        downTime: Date.now(),
+      };
+    }
+  };
+  const onTouchMove = (e: TouchEvent) => {
+    const touches = e.changedTouches;
+    for (let i = 0; i < touches.length; i++) {
+      const touch = touches[i];
+      const finger = fingers[touch.identifier];
+      if (!finger) {
+        continue;
+      }
+      finger.moving = true;
+      let dtaOffset = 0;
+      if (scrollType == "vertical") {
+        dtaOffset = touch.clientY * canvasData.scale - finger.downY;
+      }
+      if (scrollType == "horizontal") {
+        dtaOffset = touch.clientX * canvasData.scale - finger.downY;
+      }
+      canvasData.linesData[finger.downIndex].offset = finger.offset + dtaOffset;
+    }
+  };
+
+  const onTouchEnd = (e: TouchEvent) => {
+    const touches = e.changedTouches;
+    for (let i = 0; i < touches.length; i++) {
+      const touch = touches[i];
+      const finger = fingers[touch.identifier];
+
+      if (!finger) {
+        continue;
+      }
+
+      canvasData.linesData[finger.downIndex].dragging = false;
+      const dtaTime = Date.now() - finger.downTime;
+      if (dtaTime < 200 && !finger.moving) {
+        const line = canvasData.linesData[finger.downIndex];
+        let offset = line.offset;
+        if (offset >= line.halfOffset) offset -= line.halfOffset;
+        if (offset < 0) offset += line.halfOffset;
+        const n = line.items.length;
+        let z =
+          scrollType == "vertical"
+            ? offset + canvasData.height
+            : offset + canvasData.width;
+        for (let k = 0; k < n; k++) {
+          const item = line.items[k];
+
+          if (scrollType == "vertical") {
+            z -= item.offsetY;
+            if (finger.downY > z && finger.downY < z + item.offsetY) {
+              this.actions.popDialog(touch, item);
+              break;
+            }
+          }
+          if (scrollType == "horizontal") {
+            z -= item.offsetX;
+            if (finger.downX > z && finger.downX < z + item.offsetX) {
+              this.actions.popDialog(touch, item);
+              break;
+            }
+          }
+        }
+      }
+      delete fingers[touch.identifier];
+    }
+  };
+  canvas.addEventListener("mousedown", onMouseDown, false);
+  canvas.addEventListener("mousemove", onMouseMove, false);
+  document.addEventListener("mouseup", onMouseUp, false);
+
+  canvas.addEventListener("touchstart", onTouchstart, false);
+  canvas.addEventListener("touchmove", onTouchMove, false);
+  document.addEventListener("touchend", onTouchEnd, false);
+}
+
+export function ListDraw(
+  this: ListModule,
+  line: ColDataType,
+  row: number,
+  ctx: any
+) {
+  const scrollType = this.store.animate.scrollType;
+  const canvasData = this.store.canvas;
+  let x = 0,
+    y = 0;
+  const offseStep = canvasData.itemOffset + canvasData.padding;
+
+  if (scrollType == "vertical") {
+    x =
+      row > 0
+        ? Math.floor(row * offseStep) + canvasData.padding
+        : canvasData.padding;
+    y = line.offset + canvasData.height;
+  }
+  if (scrollType == "horizontal") {
+    x = line.offset + canvasData.width;
+    y =
+      row > 0
+        ? Math.floor(row * offseStep) + canvasData.padding
+        : canvasData.padding;
+  }
+
+  const items = line.items;
+  const total = items.length;
+
+  for (let k = 0; k < total; k++) {
+    //绘制
+    const item = items[k];
+
+    if (scrollType == "vertical") {
+      y -= item.offsetY; //从下往上绘制
+      if (y > canvasData.height || y < -item.offsetY) continue; //超出部分,不进行绘制提交
+      ctx.drawImage(
+        item.img,
+        0,
+        0,
+        item.w,
+        item.h,
+        Math.floor(x),
+        Math.floor(y),
+        Math.floor(canvasData.itemOffset),
+        Math.floor(item.offsetY - canvasData.padding)
+      );
+    }
+    if (scrollType == "horizontal") {
+      x -= item.offsetX;
+      if (x > canvasData.width || x < -item.offsetX) continue;
+      ctx.drawImage(
+        item.img,
+        0,
+        0,
+        item.w,
+        item.h,
+        Math.floor(x),
+        Math.floor(y),
+        Math.floor(item.offsetX - canvasData.padding),
+        Math.floor(canvasData.itemOffset)
+      );
+    }
+
+    // let text =
+    //   item.name.length > 20
+    //     ? item.name.substring(0, 19) + "..."
+    //     : item.name;
+    // ctx.fillText(text, x, Math.round(y + item.offsetY - textH * 1.2));
+  }
+}

+ 16 - 5
src/modules/list/stores.ts

@@ -1,17 +1,28 @@
 import { StateRoot } from "queenjs";
 import ListModule from ".";
-import { DialogItem, ItemObject } from "./objects/item";
+import { ColDataType, DialogItem } from "./objects/item";
 
 export const stores = ListModule.store({
   state: () => ({
     list: [],
-    items: [] as any,
+    // items: [] as any,
     dialogs: [] as DialogItem[],
-    scrollOffset: 0, //屏幕滚动值
-    scrollType: "horizontal", // 滚动方式 vertical horizontal
-    totalRow: 8, //行数或列数
     parentWidth: 0,
     parentHeight: 0,
+    animate: {
+      scrollType: "horizontal", // 滚动方式 vertical horizontal
+      totalLines: 8, //行数或列数
+      scrollSpeed: 1,
+    },
+    canvas: {
+      linesData: [] as ColDataType[],
+      linesCount: 0,
+      width: 0,
+      height: 0,
+      scale: 1,
+      padding: 12,
+      itemOffset: 0,
+    },
   }),
   getters: {},
 });

+ 92 - 0
src/pages/website/routes/backend/List.tsx

@@ -0,0 +1,92 @@
+import { css } from "@linaria/core";
+import { Button, Space, Table } from "ant-design-vue";
+import { defineComponent } from "vue";
+
+import { Image } from "@queenjs/ui";
+
+import { useList } from "@/modules/list";
+
+export default defineComponent({
+  setup() {
+    const { store, showModal } = useList();
+    const columns = [
+      {
+        title: "文物名称",
+        dataIndex: "name",
+        key: "name",
+      },
+      {
+        title: "封面图",
+        dataIndex: "thumbnail",
+        key: "thumbnail",
+        customRender: ({ text }: any) => {
+          return <Image class="thumbnail" src={text} size={120} />;
+        },
+      },
+      {
+        title: "展示形式",
+        dataIndex: "type",
+        key: "type",
+        customRender: ({ text }: any) => {
+          switch (text) {
+            case "img":
+              return "图片";
+            case "video":
+              return "视频";
+            case "3D":
+              return "模型";
+          }
+        },
+      },
+    ];
+
+    return () => (
+      <div class={ViewStyle}>
+        <div class="table_header">
+          <div class="title">文物列表</div>
+          <div>
+            <Space>
+              <Button
+                type="primary"
+                ghost
+                onClick={() => {
+                  console.log(1);
+                }}
+              >
+                导入资源
+              </Button>
+            </Space>
+          </div>
+        </div>
+        <Table
+          size="small"
+          columns={columns}
+          dataSource={store.list}
+          rowKey={(record) => record?._id}
+        ></Table>
+      </div>
+    );
+  },
+});
+
+const ViewStyle = css`
+  padding: 20px;
+  .table_header {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    margin-bottom: 20px;
+    .title {
+      font-size: 18px;
+      font-weight: bold;
+    }
+  }
+  .ant-table-thead > tr > th,
+  .ant-table-tbody > tr > td {
+    text-align: center;
+  }
+  .thumbnail {
+    width: 120px;
+    object-fit: contain;
+  }
+`;

+ 58 - 201
src/pages/website/routes/backend/index.tsx

@@ -1,201 +1,58 @@
-// import { css } from "@linaria/core";
-// import { Button, Space, Table } from "ant-design-vue";
-// import { defineComponent } from "vue";
-
-// import { Image } from "@queenjs/ui";
-// import { useCtx } from "../../context";
-// import AddModel from "./addModel";
-// import { useList } from "@/modules/list";
-
-// export default defineComponent({
-//   setup() {
-//     const { store, showModal } = useList();
-//     const columns = [
-//       {
-//         title: "文物名称",
-//         dataIndex: "name",
-//         key: "name",
-//       },
-//       {
-//         title: "封面图",
-//         dataIndex: "thumbnail",
-//         key: "thumbnail",
-//         customRender: ({ text }: any) => {
-//           return <Image class="thumbnail" src={text} size={120} />;
-//         },
-//       },
-//       {
-//         title: "展示形式",
-//         dataIndex: "type",
-//         key: "type",
-//         customRender: ({ text }: any) => {
-//           switch (text) {
-//             case "img":
-//               return "图片";
-//             case "video":
-//               return "视频";
-//             case "3D":
-//               return "模型";
-//           }
-//         },
-//       },
-//       {
-//         title: "操作",
-//         key: "action",
-//         dataIndex: "action",
-//         customRender: ({ record }) => {
-//           return (
-//             <Space>
-//               <Button type="link" onClick={() => showEdit(record)}>
-//                 编辑
-//               </Button>
-
-//               <Button
-//                 type="link"
-//                 danger
-//                 onClick={() => {
-//                   del(record);
-//                 }}
-//               >
-//                 删除
-//               </Button>
-//             </Space>
-//           );
-//         },
-//       },
-//     ];
-
-//     const showAdd = async () => {
-//       const values: any = await Modal.form({
-//         title: "添加文物",
-//         content: <AddModel />,
-//         formData: {},
-//         width: "6rem",
-//       });
-//       if (!values) return;
-//       // const uploadRes = await ctx.list.uploader.uploadBlobs(values, "museum");
-//       // if (uploadRes) {
-//       //   ctx.ui.messageError(uploadRes);
-//       //   return false;
-//       // }
-//       const res = await ctx.list.actions.addArtifacts(values);
-//     };
-//     const showEdit = async (record: any) => {
-//       const item = await ctx.list.actions.getArtifactDtl(record._id);
-
-//       if (!item) return false;
-//       const values: any = await Modal.form({
-//         title: "编辑文物",
-//         content: <AddModel />,
-//         formData: { ...item },
-//         width: "6rem",
-//       });
-//       if (!values) return;
-//       const uploadRes = await ctx.list.uploader.uploadBlobs(values, "museum");
-//       if (uploadRes) {
-//         ctx.ui.messageError(uploadRes);
-//         return false;
-//       }
-//       const res = await ctx.list.actions.updateArtifacts(values);
-//     };
-
-//     const del = (item: any) => {
-//       store.list.actions.deleteArtifact(item);
-//     };
-
-//     // const showExport = () => {
-//     //   const exportModal = Modal.show(
-//     //     <ExportModal
-//     //       onSubmit={(ids: string[]) => {
-//     //         exportArtifacts(ids);
-//     //         exportModal.close();
-//     //       }}
-//     //       onCancel={() => {
-//     //         exportModal.close();
-//     //       }}
-//     //     />,
-//     //     {
-//     //       title: "导出文物列表",
-//     //     }
-//     //   );
-//     // };
-//     const exportArtifacts = () => {
-//       ctx.list.actions.exportArtifacts();
-//     };
-
-//     return () => (
-//       <div class={ViewStyle}>
-//         <div class="table_header">
-//           <div class="title">文物列表</div>
-//           <div>
-//             <Space>
-//               <Button
-//                 type="primary"
-//                 ghost
-//                 onClick={() => {
-//                   ctx.list.actions.importArtifacts();
-//                 }}
-//               >
-//                 导入资源
-//               </Button>
-
-//               <Button
-//                 type="primary"
-//                 ghost
-//                 onClick={() => {
-//                   exportArtifacts();
-//                 }}
-//               >
-//                 导出资源
-//               </Button>
-//               <Button
-//                 type="primary"
-//                 onClick={() => {
-//                   showAdd();
-//                 }}
-//               >
-//                 添加+
-//               </Button>
-//             </Space>
-//           </div>
-//         </div>
-//         <Table
-//           size="small"
-//           columns={columns}
-//           dataSource={ctx.list.backendList.state.list}
-//           pagination={{
-//             size: "default",
-//             pageSize: ctx.list.backendList.state.size,
-//             current: ctx.list.backendList.state.page,
-//             total: ctx.list.backendList.state.total,
-//             showSizeChanger: false,
-//             onChange: (p) => ctx.list.backendList.loadPage(p),
-//           }}
-//           rowKey={(record) => record?._id}
-//         ></Table>
-//       </div>
-//     );
-//   },
-// });
-
-// const ViewStyle = css`
-//   padding: 20px;
-//   .table_header {
-//     display: flex;
-//     align-items: center;
-//     justify-content: space-between;
-//     margin-bottom: 20px;
-//     .title {
-//       font-size: 18px;
-//       font-weight: bold;
-//     }
-//   }
-//   .ant-table-thead > tr > th,
-//   .ant-table-tbody > tr > td {
-//     text-align: center;
-//   }
-//   .thumbnail {
-//     width: 120px;
-//     object-fit: contain;
-//   }
-// `;
+import { css } from "@linaria/core";
+import { defineComponent, reactive } from "vue";
+
+import { useList } from "@/modules/list";
+import { Button, Card, Form, Input, Radio, InputNumber } from "ant-design-vue";
+const layout = {
+  labelCol: { span: 6 },
+  wrapperCol: { span: 18 },
+};
+export default defineComponent({
+  setup() {
+    const { store, showModal } = useList();
+    const formState = reactive({
+      ...store.animate,
+    });
+    const submit = () => {
+      console.log(1);
+    };
+    return () => (
+      <div class={ViewStyle}>
+        <Form {...layout} class={"setting_form"} onSubmit={submit}>
+          <Form.Item label="滚动方向">
+            <Radio.Group v-model={[formState.scrollType, "value"]}>
+              <Radio.Button value="horizontal">横向</Radio.Button>
+              <Radio.Button value="vertical">纵向</Radio.Button>
+            </Radio.Group>
+          </Form.Item>
+          <Form.Item label="滚动条数">
+            <InputNumber
+              v-model={[formState.totalLines, "value"]}
+              min={1}
+              step={1}
+            />
+          </Form.Item>
+          <Form.Item label="滚动速度">
+            <InputNumber
+              v-model={[formState.scrollSpeed, "value"]}
+              min={1}
+              step={1}
+            />
+          </Form.Item>
+          <Form.Item wrapperCol={{ offset: 6, span: 18 }}>
+            <Button type="primary" htmlType="submit">
+              保存设置
+            </Button>
+          </Form.Item>
+        </Form>
+      </div>
+    );
+  },
+});
+
+const ViewStyle = css`
+  padding: 20px;
+  .setting_form {
+    width: 300px;
+  }
+`;

+ 1 - 1
src/pages/website/routes/home/index.tsx

@@ -14,7 +14,7 @@ export default defineComponent({
     const rootRef = ref<HTMLElement>();
 
     onMounted(async () => {
-      await actions.initListCanvasDatas(
+      await actions.initListCanvasData(
         rootRef.value?.clientWidth as number,
         rootRef.value?.clientHeight as number
       );

+ 22 - 21
src/pages/website/routes/index.ts

@@ -6,7 +6,8 @@ import home from "./home";
 // import list3 from "./list/list3";
 
 import BasicLayout from "./backend/components/layout/BasicLayout";
-// import Backend from "./backend";
+import Backend from "./backend";
+import BackendList from "./backend/List";
 // import Total from "./backend/total";
 
 const routes: Array<RouteRecordRaw> = [
@@ -32,26 +33,26 @@ const routes: Array<RouteRecordRaw> = [
   //   name: "list3",
   //   component: list3,
   // },
-  // {
-  //   path: "/backend",
-  //   name: "backend",
-  //   component: BasicLayout,
-  //   redirect: "/backend/upload",
-  //   children: [
-  //     {
-  //       path: "/backend/upload",
-  //       name: "upload",
-  //       component: Backend,
-  //       meta: { title: "上传管理" },
-  //     },
-  //     {
-  //       path: "/backend/total",
-  //       name: "total",
-  //       component: Total,
-  //       meta: { title: "上传统计" },
-  //     },
-  //   ],
-  // },
+  {
+    path: "/backend",
+    name: "backend",
+    component: BasicLayout,
+    redirect: "/backend/setting",
+    children: [
+      {
+        path: "/backend/setting",
+        name: "setting",
+        component: Backend,
+        meta: { title: "动画设置" },
+      },
+      {
+        path: "/backend/list",
+        name: "list",
+        component: BackendList,
+        meta: { title: "展示数据" },
+      },
+    ],
+  },
 ];
 
 const router = createRouter({

+ 1 - 0
src/pages/website/routes/list/dialog.tsx

@@ -45,6 +45,7 @@ export default defineComponent({
       state.itemData = store.list.find((e: any) => {
         return e._id == props.data.dataId;
       });
+
       setTimeout(() => {
         nextTick(() => {
           state.scale = 1.0;