canvas.ts 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. import ListModule from "..";
  2. import { ColDataType } from "./item";
  3. export function InitCanvasDragEvent(
  4. this: ListModule,
  5. canvas: HTMLCanvasElement
  6. ) {
  7. let down = false;
  8. let downIndex = -1;
  9. let downY = 0;
  10. let downX = 0;
  11. let initOffset = 0;
  12. let downTime = 0;
  13. let moving = false;
  14. const fingers: { [name: number]: any } = {};
  15. const scrollType = this.store.animate.scrollType;
  16. const canvasData = this.store.canvas;
  17. const onMouseDown = (e: MouseEvent) => {
  18. const x = e.clientX * canvasData.scale;
  19. const y = e.clientY * canvasData.scale;
  20. downY = e.clientY * canvasData.scale;
  21. downX = e.clientX * canvasData.scale;
  22. down = true;
  23. downIndex =
  24. scrollType == "vertical"
  25. ? Math.floor(x / (canvasData.itemOffset + canvasData.padding))
  26. : Math.floor(y / (canvasData.itemOffset + canvasData.padding));
  27. canvasData.linesData[downIndex].dragging = true;
  28. initOffset = canvasData.linesData[downIndex].offset;
  29. downTime = Date.now();
  30. };
  31. const onMouseMove = (e: MouseEvent) => {
  32. if (!down || downIndex < 0) return;
  33. moving = true;
  34. console.log("move");
  35. let dtaOffset = 0;
  36. if (scrollType == "vertical") {
  37. dtaOffset = e.clientY * canvasData.scale - dtaOffset;
  38. }
  39. if (scrollType == "horizontal") {
  40. dtaOffset = e.clientX * canvasData.scale - dtaOffset;
  41. }
  42. canvasData.linesData[downIndex].offset = initOffset + dtaOffset;
  43. };
  44. const onMouseUp = (e: MouseEvent) => {
  45. console.log("up");
  46. down = false;
  47. if (downIndex >= 0) {
  48. canvasData.linesData[downIndex].dragging = false;
  49. const dtaTime = Date.now() - downTime;
  50. if (dtaTime < 200 && !moving) {
  51. const line = canvasData.linesData[downIndex];
  52. let offset = line.offset;
  53. if (offset >= line.halfOffset) offset -= line.halfOffset;
  54. if (offset < 0) offset += line.halfOffset;
  55. const n = line.items.length;
  56. let z =
  57. scrollType == "vertical"
  58. ? offset + canvasData.height
  59. : offset + canvasData.width;
  60. for (let k = 0; k < n; k++) {
  61. const item = line.items[k];
  62. if (scrollType == "vertical") {
  63. z -= item.offsetY;
  64. if (downY > z && downY < z + item.offsetY) {
  65. console.log("click->", item.name);
  66. this.actions.popDialog(e, item);
  67. break;
  68. }
  69. }
  70. if (scrollType == "horizontal") {
  71. z -= item.offsetX;
  72. if (downX > z && downX < z + item.offsetX) {
  73. console.log("click->", item.name);
  74. this.actions.popDialog(e, item);
  75. break;
  76. }
  77. }
  78. }
  79. }
  80. }
  81. downIndex = -1;
  82. moving = false;
  83. };
  84. const onTouchstart = (e: TouchEvent) => {
  85. const touches = e.touches;
  86. for (let i = 0; i < touches.length; i++) {
  87. const touch = touches[i];
  88. if (fingers[touch.identifier]) {
  89. continue;
  90. }
  91. const x = touch.clientX * canvasData.scale;
  92. const y = touch.clientY * canvasData.scale;
  93. const downIndex =
  94. scrollType == "vertical"
  95. ? Math.floor(x / (canvasData.itemOffset + canvasData.padding))
  96. : Math.floor(y / (canvasData.itemOffset + canvasData.padding));
  97. canvasData.linesData[downIndex].dragging = true;
  98. const offset = canvasData.linesData[downIndex].offset;
  99. fingers[touch.identifier] = {
  100. identifier: touch.identifier,
  101. downY: y,
  102. downX: x,
  103. downIndex: downIndex,
  104. offset: offset,
  105. downTime: Date.now(),
  106. };
  107. }
  108. };
  109. const onTouchMove = (e: TouchEvent) => {
  110. const touches = e.changedTouches;
  111. for (let i = 0; i < touches.length; i++) {
  112. const touch = touches[i];
  113. const finger = fingers[touch.identifier];
  114. if (!finger) {
  115. continue;
  116. }
  117. finger.moving = true;
  118. let dtaOffset = 0;
  119. if (scrollType == "vertical") {
  120. dtaOffset = touch.clientY * canvasData.scale - finger.downY;
  121. }
  122. if (scrollType == "horizontal") {
  123. dtaOffset = touch.clientX * canvasData.scale - finger.downY;
  124. }
  125. canvasData.linesData[finger.downIndex].offset = finger.offset + dtaOffset;
  126. }
  127. };
  128. const onTouchEnd = (e: TouchEvent) => {
  129. const touches = e.changedTouches;
  130. for (let i = 0; i < touches.length; i++) {
  131. const touch = touches[i];
  132. const finger = fingers[touch.identifier];
  133. if (!finger) {
  134. continue;
  135. }
  136. canvasData.linesData[finger.downIndex].dragging = false;
  137. const dtaTime = Date.now() - finger.downTime;
  138. if (dtaTime < 200 && !finger.moving) {
  139. const line = canvasData.linesData[finger.downIndex];
  140. let offset = line.offset;
  141. if (offset >= line.halfOffset) offset -= line.halfOffset;
  142. if (offset < 0) offset += line.halfOffset;
  143. const n = line.items.length;
  144. let z =
  145. scrollType == "vertical"
  146. ? offset + canvasData.height
  147. : offset + canvasData.width;
  148. for (let k = 0; k < n; k++) {
  149. const item = line.items[k];
  150. if (scrollType == "vertical") {
  151. z -= item.offsetY;
  152. if (finger.downY > z && finger.downY < z + item.offsetY) {
  153. this.actions.popDialog(touch, item);
  154. break;
  155. }
  156. }
  157. if (scrollType == "horizontal") {
  158. z -= item.offsetX;
  159. if (finger.downX > z && finger.downX < z + item.offsetX) {
  160. this.actions.popDialog(touch, item);
  161. break;
  162. }
  163. }
  164. }
  165. }
  166. delete fingers[touch.identifier];
  167. }
  168. };
  169. canvas.addEventListener("mousedown", onMouseDown, false);
  170. canvas.addEventListener("mousemove", onMouseMove, false);
  171. document.addEventListener("mouseup", onMouseUp, false);
  172. canvas.addEventListener("touchstart", onTouchstart, false);
  173. canvas.addEventListener("touchmove", onTouchMove, false);
  174. document.addEventListener("touchend", onTouchEnd, false);
  175. }
  176. export function ListDraw(
  177. this: ListModule,
  178. line: ColDataType,
  179. row: number,
  180. ctx: any
  181. ) {
  182. const scrollType = this.store.animate.scrollType;
  183. const canvasData = this.store.canvas;
  184. let x = 0,
  185. y = 0;
  186. const offseStep = canvasData.itemOffset + canvasData.padding;
  187. if (scrollType == "vertical") {
  188. x =
  189. row > 0
  190. ? Math.floor(row * offseStep) + canvasData.padding
  191. : canvasData.padding;
  192. y = line.offset + canvasData.height;
  193. }
  194. if (scrollType == "horizontal") {
  195. x = line.offset + canvasData.width;
  196. y =
  197. row > 0
  198. ? Math.floor(row * offseStep) + canvasData.padding
  199. : canvasData.padding;
  200. }
  201. const items = line.items;
  202. const total = items.length;
  203. for (let k = 0; k < total; k++) {
  204. //绘制
  205. const item = items[k];
  206. if (scrollType == "vertical") {
  207. y -= item.offsetY; //从下往上绘制
  208. if (y > canvasData.height || y < -item.offsetY) continue; //超出部分,不进行绘制提交
  209. ctx.drawImage(
  210. item.img,
  211. 0,
  212. 0,
  213. item.w,
  214. item.h,
  215. Math.floor(x),
  216. Math.floor(y),
  217. Math.floor(canvasData.itemOffset),
  218. Math.floor(item.offsetY - canvasData.padding)
  219. );
  220. }
  221. if (scrollType == "horizontal") {
  222. x -= item.offsetX;
  223. if (x > canvasData.width || x < -item.offsetX) continue;
  224. ctx.drawImage(
  225. item.img,
  226. 0,
  227. 0,
  228. item.w,
  229. item.h,
  230. Math.floor(x),
  231. Math.floor(y),
  232. Math.floor(item.offsetX - canvasData.padding),
  233. Math.floor(canvasData.itemOffset)
  234. );
  235. }
  236. // let text =
  237. // item.name.length > 20
  238. // ? item.name.substring(0, 19) + "..."
  239. // : item.name;
  240. // ctx.fillText(text, x, Math.round(y + item.offsetY - textH * 1.2));
  241. }
  242. }