|
@@ -1,72 +1,100 @@
|
|
|
// import item from "@/pages/website/routes/list/item";
|
|
|
-import list from "queenjs/ui/list";
|
|
|
import ListModule from "..";
|
|
|
-import { Dialog, ShowItem } from "../state";
|
|
|
-import { isPc } from "queenjs/framework/utils";
|
|
|
+import { ShowItem } from "../state";
|
|
|
type ColDataType = {
|
|
|
offset: number;
|
|
|
items: any[];
|
|
|
- halfHeight: number;
|
|
|
+ halfOffset: number;
|
|
|
dragging: boolean;
|
|
|
speed: number;
|
|
|
};
|
|
|
|
|
|
export default (listModule: ListModule) => {
|
|
|
- const cols: ColDataType[] = []; //{offset, items:[], halfHeight: 0, dragging: false}
|
|
|
-
|
|
|
- let totalColCount = 0; //每列的数量
|
|
|
+ const cols: ColDataType[] = []; //{offset, items:[], halfOffset: 0, dragging: false}
|
|
|
+ const totalRow = listModule.state.totalRow || 8;
|
|
|
let CanvasWidth = 0;
|
|
|
let CanvasHeight = 0;
|
|
|
let textH = 0;
|
|
|
- let paddingW = 0;
|
|
|
- let itemW = 0;
|
|
|
+ let paddingOffset = 0;
|
|
|
+ let totalSizeCount = 0; //每行或每列的数量
|
|
|
+ let itemOffset = 0;
|
|
|
|
|
|
let ctx: CanvasRenderingContext2D;
|
|
|
let scale = 1;
|
|
|
|
|
|
return {
|
|
|
async initListCanvasDatas(wWidth: number, wHeight: number) {
|
|
|
- const totalRow = listModule.state.totalRow || 8;
|
|
|
- const actions = listModule.actions;
|
|
|
+ const scrollType = listModule.state.scrollType;
|
|
|
const items = await listModule.actions.loadData(wWidth, wHeight);
|
|
|
- const itemsLen = items.length;
|
|
|
scale = Math.max(devicePixelRatio, 2);
|
|
|
|
|
|
- textH = 24 * scale;
|
|
|
+ // textH = 24 * scale;
|
|
|
CanvasWidth = wWidth * scale;
|
|
|
CanvasHeight = wHeight * scale;
|
|
|
- paddingW = 12 * scale;
|
|
|
- itemW = (CanvasWidth - paddingW * (totalRow + 1)) / totalRow;
|
|
|
+ paddingOffset = 12 * scale;
|
|
|
+ totalSizeCount = Math.ceil(items.length / totalRow) * 2;
|
|
|
|
|
|
- totalColCount = Math.ceil(items.length / totalRow) * 2;
|
|
|
+ if (scrollType == "vertical") {
|
|
|
+ listModule.actions.initVerticalList(items);
|
|
|
+ }
|
|
|
+ if (scrollType == "horizontal") {
|
|
|
+ listModule.actions.initHorizontalList(items);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ initVerticalList(items) {
|
|
|
+ itemOffset = (CanvasWidth - paddingOffset * (totalRow + 1)) / totalRow;
|
|
|
+ for (let i = 0; i < totalRow; i++) {
|
|
|
+ let off = i * totalSizeCount;
|
|
|
+ let arr: ShowItem[] = [];
|
|
|
+ for (let k = 0; k < totalSizeCount; k++) {
|
|
|
+ arr.push(items[(off + k) % items.length]);
|
|
|
+ }
|
|
|
+ listModule.actions.shuffleSelf(arr, totalSizeCount);
|
|
|
+ //计算总高度
|
|
|
+ let halfOffset = 0;
|
|
|
+ arr.forEach((item) => {
|
|
|
+ let h = ((item.h * 1.0) / item.w) * itemOffset;
|
|
|
+ item.offsetY = h + textH + paddingOffset; //y step;
|
|
|
+ halfOffset += item.offsetY;
|
|
|
+ });
|
|
|
|
|
|
+ const colData = {
|
|
|
+ items: [...arr, ...arr],
|
|
|
+ offset: 0,
|
|
|
+ halfOffset: halfOffset,
|
|
|
+ dragging: false,
|
|
|
+ speed: i % 2 == 0 ? 1 : 2,
|
|
|
+ };
|
|
|
+ cols.push(colData);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ initHorizontalList(items) {
|
|
|
+ itemOffset = (CanvasHeight - paddingOffset * (totalRow + 1)) / totalRow;
|
|
|
for (let i = 0; i < totalRow; i++) {
|
|
|
- let off = i * totalColCount;
|
|
|
+ let off = i * totalSizeCount;
|
|
|
let arr: ShowItem[] = [];
|
|
|
- for (let k = 0; k < totalColCount; k++) {
|
|
|
- arr.push(items[(off + k) % itemsLen]);
|
|
|
+ for (let k = 0; k < totalSizeCount; k++) {
|
|
|
+ arr.push(items[(off + k) % items.length]);
|
|
|
}
|
|
|
- actions.shuffleSelf(arr, totalColCount);
|
|
|
+ listModule.actions.shuffleSelf(arr, totalSizeCount);
|
|
|
|
|
|
//计算总高度
|
|
|
- let halfHeight = 0;
|
|
|
+ let halfOffset = 0;
|
|
|
arr.forEach((item) => {
|
|
|
- let h = ((item.h * 1.0) / item.w) * itemW;
|
|
|
- item.offsetY = h + textH + paddingW; //y step;
|
|
|
- halfHeight += item.offsetY;
|
|
|
+ let w = ((item.w * 1.0) / item.h) * itemOffset;
|
|
|
+ item.offsetX = w + textH + paddingOffset; //y step;
|
|
|
+ halfOffset += item.offsetX;
|
|
|
});
|
|
|
|
|
|
const colData = {
|
|
|
items: [...arr, ...arr],
|
|
|
offset: 0,
|
|
|
- halfHeight: halfHeight,
|
|
|
+ halfOffset: halfOffset,
|
|
|
dragging: false,
|
|
|
speed: i % 2 == 0 ? 1 : 2,
|
|
|
};
|
|
|
- // colData.speed = 0;
|
|
|
cols.push(colData);
|
|
|
}
|
|
|
- console.log(cols);
|
|
|
},
|
|
|
|
|
|
startListRunning(canvas: HTMLCanvasElement) {
|
|
@@ -84,45 +112,6 @@ export default (listModule: ListModule) => {
|
|
|
cacheCtx.textBaseline = "top";
|
|
|
|
|
|
let loopId = 0;
|
|
|
- let x = 0,
|
|
|
- y = 0,
|
|
|
- xStep = itemW + paddingW;
|
|
|
-
|
|
|
- function draw(col: ColDataType, row: number) {
|
|
|
- x = row > 0 ? Math.floor(row * xStep) + paddingW : paddingW;
|
|
|
- const items = col.items;
|
|
|
- let total = items.length;
|
|
|
-
|
|
|
- y = col.offset + CanvasHeight;
|
|
|
-
|
|
|
- for (let k = 0; k < total; k++) {
|
|
|
- //绘制
|
|
|
- let item = items[k];
|
|
|
- y -= item.offsetY; //从下往上绘制
|
|
|
- if (y > CanvasHeight || y < -item.offsetY) continue; //超出部分,不进行绘制提交
|
|
|
-
|
|
|
- cacheCtx.drawImage(
|
|
|
- item.img,
|
|
|
- 0,
|
|
|
- 0,
|
|
|
- item.w,
|
|
|
- item.h,
|
|
|
- x,
|
|
|
- Math.floor(y),
|
|
|
- Math.floor(itemW),
|
|
|
- Math.floor(item.offsetY - textH - paddingW)
|
|
|
- );
|
|
|
- let text =
|
|
|
- item.name.length > 20
|
|
|
- ? item.name.substring(0, 19) + "..."
|
|
|
- : item.name;
|
|
|
- cacheCtx.fillText(
|
|
|
- text,
|
|
|
- x,
|
|
|
- Math.round(y + item.offsetY - textH * 1.2)
|
|
|
- );
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
let n = cols.length;
|
|
|
let i = 0;
|
|
@@ -139,13 +128,13 @@ export default (listModule: ListModule) => {
|
|
|
item.offset = Math.floor(item.offset + item.speed);
|
|
|
}
|
|
|
// console.log(item.offset);
|
|
|
- if (item.offset >= item.halfHeight) item.offset -= item.halfHeight;
|
|
|
- if (item.offset < 0) item.offset += item.halfHeight;
|
|
|
+ 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;
|
|
|
for (i = 0; i < n; i++) {
|
|
|
- draw(cols[i], i);
|
|
|
+ listModule.actions.listDraw(cols[i], i, cacheCtx);
|
|
|
}
|
|
|
ctx.clearRect(0, 0, CanvasWidth, CanvasHeight);
|
|
|
ctx.drawImage(cache, 0, 0);
|
|
@@ -153,29 +142,155 @@ export default (listModule: ListModule) => {
|
|
|
}
|
|
|
loop();
|
|
|
},
|
|
|
+ listDraw(col: ColDataType, row: number, ctx: any) {
|
|
|
+ const scrollType = listModule.state.scrollType;
|
|
|
+ let x = 0,
|
|
|
+ y = 0,
|
|
|
+ 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;
|
|
|
+ let total = items.length;
|
|
|
+
|
|
|
+ for (let k = 0; k < total; k++) {
|
|
|
+ //绘制
|
|
|
+ let 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));
|
|
|
+ }
|
|
|
+ },
|
|
|
|
|
|
endListRuning() {},
|
|
|
|
|
|
initDragEvents(canvas: HTMLCanvasElement) {
|
|
|
let down = false;
|
|
|
- let downCol = -1;
|
|
|
+ let downIndex = -1;
|
|
|
let downY = 0;
|
|
|
+ let downX = 0;
|
|
|
|
|
|
let initOffset = 0;
|
|
|
let downTime = 0;
|
|
|
let moving = false;
|
|
|
let fingers = {};
|
|
|
+ const scrollType = listModule.state.scrollType;
|
|
|
|
|
|
function onMouseDown(e: MouseEvent) {
|
|
|
let x = e.clientX * scale;
|
|
|
+ let y = e.clientY * scale;
|
|
|
downY = e.clientY * scale;
|
|
|
+ downX = e.clientX * scale;
|
|
|
down = true;
|
|
|
- downCol = Math.floor(x / (itemW + paddingW));
|
|
|
- console.log(downCol);
|
|
|
- cols[downCol].dragging = true;
|
|
|
- initOffset = cols[downCol].offset;
|
|
|
+ downIndex =
|
|
|
+ scrollType == "vertical"
|
|
|
+ ? Math.floor(x / (itemOffset + paddingOffset))
|
|
|
+ : Math.floor(y / (itemOffset + paddingOffset));
|
|
|
+
|
|
|
+ cols[downIndex].dragging = true;
|
|
|
+ initOffset = cols[downIndex].offset;
|
|
|
downTime = Date.now();
|
|
|
}
|
|
|
+
|
|
|
+ function onMouseMove(e) {
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ function onMouseUp(e) {
|
|
|
+ console.log("up");
|
|
|
+ down = false;
|
|
|
+ if (downIndex >= 0) {
|
|
|
+ cols[downIndex].dragging = false;
|
|
|
+ let 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;
|
|
|
+
|
|
|
+ let 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);
|
|
|
+ listModule.actions.popDialog(e, item);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (scrollType == "horizontal") {
|
|
|
+ z -= item.offsetX;
|
|
|
+ if (downX > z && downX < z + item.offsetX) {
|
|
|
+ console.log("click->", item.name);
|
|
|
+ listModule.actions.popDialog(e, item);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ downIndex = -1;
|
|
|
+ moving = false;
|
|
|
+ }
|
|
|
function onTouchstart(e: TouchEvent) {
|
|
|
let touches = e.touches;
|
|
|
for (let i = 0; i < touches.length; i++) {
|
|
@@ -185,27 +300,22 @@ export default (listModule: ListModule) => {
|
|
|
}
|
|
|
let x = touch.clientX * scale;
|
|
|
let y = touch.clientY * scale;
|
|
|
- let downCol = Math.floor(x / (itemW + paddingW));
|
|
|
- cols[downCol].dragging = true;
|
|
|
- let offset = cols[downCol].offset;
|
|
|
+ let downIndex =
|
|
|
+ scrollType == "vertical"
|
|
|
+ ? Math.floor(x / (itemOffset + paddingOffset))
|
|
|
+ : Math.floor(y / (itemOffset + paddingOffset));
|
|
|
+ cols[downIndex].dragging = true;
|
|
|
+ let offset = cols[downIndex].offset;
|
|
|
fingers[touch.identifier] = {
|
|
|
identifier: touch.identifier,
|
|
|
downY: y,
|
|
|
- downCol: downCol,
|
|
|
+ downX: x,
|
|
|
+ downIndex: downIndex,
|
|
|
offset: offset,
|
|
|
downTime: Date.now(),
|
|
|
};
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- function onMouseMove(e) {
|
|
|
- if (!down || downCol < 0) return;
|
|
|
- moving = true;
|
|
|
-
|
|
|
- console.log("move");
|
|
|
- let dtaY = e.clientY * scale - downY;
|
|
|
- cols[downCol].offset = initOffset + dtaY;
|
|
|
- }
|
|
|
function onTouchMove(e: TouchEvent) {
|
|
|
let touches = e.changedTouches;
|
|
|
for (let i = 0; i < touches.length; i++) {
|
|
@@ -215,40 +325,17 @@ export default (listModule: ListModule) => {
|
|
|
continue;
|
|
|
}
|
|
|
finger.moving = true;
|
|
|
- let dtaY = touch.clientY * scale - finger.downY;
|
|
|
- cols[finger.downCol].offset = finger.offset + dtaY;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- function onMouseUp(e) {
|
|
|
- console.log("up");
|
|
|
- down = false;
|
|
|
- if (downCol >= 0) {
|
|
|
- cols[downCol].dragging = false;
|
|
|
- let dtaTime = Date.now() - downTime;
|
|
|
- if (dtaTime < 200 && !moving) {
|
|
|
- // alert("click")
|
|
|
- const col = cols[downCol];
|
|
|
- let offset = col.offset;
|
|
|
- if (offset >= col.halfHeight) offset -= col.halfHeight;
|
|
|
- if (offset < 0) offset += col.halfHeight;
|
|
|
-
|
|
|
- let n = col.items.length;
|
|
|
- let z = offset + CanvasHeight;
|
|
|
- for (let k = 0; k < n; k++) {
|
|
|
- const item = col.items[k];
|
|
|
- z -= item.offsetY; //从下往上绘制
|
|
|
- if (downY > z && downY < z + item.offsetY) {
|
|
|
- console.log("click->", item.name);
|
|
|
- listModule.actions.popDialog(e, item);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
+ 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;
|
|
|
}
|
|
|
- downCol = -1;
|
|
|
- moving = false;
|
|
|
}
|
|
|
+
|
|
|
function onTouchEnd(e: TouchEvent) {
|
|
|
let touches = e.changedTouches;
|
|
|
for (let i = 0; i < touches.length; i++) {
|
|
@@ -259,21 +346,34 @@ export default (listModule: ListModule) => {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
- cols[finger.downCol].dragging = false;
|
|
|
+ cols[finger.downIndex].dragging = false;
|
|
|
let dtaTime = Date.now() - finger.downTime;
|
|
|
if (dtaTime < 200 && !finger.moving) {
|
|
|
- const col = cols[finger.downCol];
|
|
|
+ const col = cols[finger.downIndex];
|
|
|
let offset = col.offset;
|
|
|
- if (offset >= col.halfHeight) offset -= col.halfHeight;
|
|
|
- if (offset < 0) offset += col.halfHeight;
|
|
|
+ if (offset >= col.halfOffset) offset -= col.halfOffset;
|
|
|
+ if (offset < 0) offset += col.halfOffset;
|
|
|
let n = col.items.length;
|
|
|
- let z = offset + CanvasHeight;
|
|
|
+ let z =
|
|
|
+ scrollType == "vertical"
|
|
|
+ ? offset + CanvasHeight
|
|
|
+ : offset + CanvasWidth;
|
|
|
for (let k = 0; k < n; k++) {
|
|
|
const item = col.items[k];
|
|
|
- z -= item.offsetY;
|
|
|
- if (finger.downY > z && finger.downY < z + item.offsetY) {
|
|
|
- listModule.actions.popDialog(touch, item);
|
|
|
- break;
|
|
|
+
|
|
|
+ if (scrollType == "vertical") {
|
|
|
+ z -= item.offsetY;
|
|
|
+ if (finger.downY > z && finger.downY < z + item.offsetY) {
|
|
|
+ listModule.actions.popDialog(touch, item);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (scrollType == "horizontal") {
|
|
|
+ z -= item.offsetX;
|
|
|
+ if (finger.downX > z && finger.downX < z + item.offsetX) {
|
|
|
+ listModule.actions.popDialog(touch, item);
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|