ImgControler.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. <template>
  2. <canvas ref="canvasRef" :style="{ cursor }" :width="size.width" :height="size.height"></canvas>
  3. </template>
  4. <script setup lang="ts">
  5. import { ref, onMounted } from "vue";
  6. import { ImgControler } from "../lmm/controler/ImgControler";
  7. import { OrbitControler } from "../lmm/controler/OrbitControler";
  8. import { Scene } from "../lmm/core/Scene";
  9. import { Vector2 } from "../lmm/math/Vector2";
  10. import { Group } from "../lmm/objects/Group";
  11. import { Img } from "../lmm/objects/Img";
  12. import { ImagePromises } from "../lmm/objects/ObjectUtils";
  13. import { Object2D } from "../lmm/objects/Object2D";
  14. // 获取父级属性
  15. defineProps({
  16. size: { type: Object, default: { width: 1000, height: 500 } },
  17. });
  18. // 鼠标样式
  19. const cursor = ref("default");
  20. // 对应canvas 画布的Ref对象
  21. const canvasRef = ref<HTMLCanvasElement>();
  22. /* 场景 */
  23. const scene = new Scene();
  24. /* 相机轨道控制器 */
  25. const orbitControler = new OrbitControler(scene.camera);
  26. /* 图案控制器 */
  27. const imgControler = new ImgControler();
  28. scene.add(imgControler);
  29. const images: HTMLImageElement[] = [];
  30. for (let i = 1; i < 5; i++) {
  31. const image = new Image();
  32. image.src = `https://yxyy-pandora.oss-cn-beijing.aliyuncs.com/stamp-images/${i}.png`;
  33. images.push(image);
  34. }
  35. /* 图案集合 */
  36. const imgGroup = new Group();
  37. scene.add(imgGroup);
  38. /* 鼠标滑上的图案 */
  39. let imgHover: Img | null;
  40. /* 测试 */
  41. function test(canvas: HTMLCanvasElement) {
  42. /* 添加图案 */
  43. imgGroup.add(
  44. ...images.map((image, i) => {
  45. const size = new Vector2(image.width, image.height).multiplyScalar(0.3);
  46. return new Img({
  47. image,
  48. position: new Vector2(0, 160 * i - canvas.height / 2 + 50),
  49. size,
  50. offset: new Vector2(-size.x / 2, 0),
  51. name: "img-" + i,
  52. style: {
  53. shadowColor: "rgba(0,0,0,0.5)",
  54. shadowBlur: 5,
  55. shadowOffsetY: 20,
  56. },
  57. });
  58. })
  59. );
  60. /* 鼠标按下*/
  61. canvas.addEventListener("pointerdown", (event: PointerEvent) => {
  62. const { button, clientX, clientY } = event;
  63. const mp = scene.clientToClip(clientX, clientY);
  64. switch (button) {
  65. case 0:
  66. imgHover = selectObj(imgGroup.children, mp);
  67. imgControler.pointerdown(imgHover, mp);
  68. updateMouseCursor();
  69. break;
  70. case 1:
  71. orbitControler.pointerdown(clientX, clientY);
  72. break;
  73. }
  74. });
  75. /* 鼠标移动 */
  76. canvas.addEventListener("pointermove", (event: PointerEvent) => {
  77. const { clientX, clientY } = event;
  78. orbitControler.pointermove(clientX, clientY);
  79. const mp = scene.clientToClip(clientX, clientY);
  80. imgHover = selectObj(imgGroup.children, mp);
  81. imgControler.pointermove(mp);
  82. updateMouseCursor();
  83. });
  84. /* 鼠标抬起 */
  85. window.addEventListener("pointerup", (event: PointerEvent) => {
  86. switch (event.button) {
  87. case 0:
  88. imgControler.pointerup();
  89. break;
  90. case 1:
  91. orbitControler.pointerup();
  92. break;
  93. }
  94. });
  95. /* 键盘按下 */
  96. window.addEventListener("keydown", ({ key, altKey, shiftKey }: KeyboardEvent) => {
  97. imgControler.keydown(key, altKey, shiftKey);
  98. updateMouseCursor();
  99. });
  100. /* 键盘抬起 */
  101. window.addEventListener("keyup", ({ altKey, shiftKey }: KeyboardEvent) => {
  102. imgControler.keyup(altKey, shiftKey);
  103. });
  104. /* 滑动滚轮缩放 */
  105. canvas.addEventListener("wheel", ({ deltaY }) => {
  106. orbitControler.doScale(deltaY);
  107. });
  108. /* 按需渲染 */
  109. orbitControler.addEventListener("change", () => {
  110. scene.render();
  111. });
  112. imgControler.addEventListener("change", () => {
  113. scene.render();
  114. });
  115. /* 渲染 */
  116. scene.render();
  117. }
  118. /* 更新鼠标样式 */
  119. function updateMouseCursor() {
  120. if (imgControler.mouseState) {
  121. cursor.value = "none";
  122. } else if (imgHover) {
  123. cursor.value = "pointer";
  124. } else {
  125. cursor.value = "default";
  126. }
  127. }
  128. /* 选择图案 */
  129. function selectObj(imgGroup: Object2D[], mp: Vector2): Img | null {
  130. for (let img of [...imgGroup].reverse()) {
  131. if (img instanceof Img && scene.isPointInObj(img, mp, img.pvmoMatrix)) {
  132. return img;
  133. }
  134. }
  135. return null;
  136. }
  137. onMounted(() => {
  138. const canvas = canvasRef.value;
  139. if (canvas) {
  140. scene.setOption({ canvas });
  141. Promise.all(ImagePromises(images)).then(() => {
  142. test(canvas);
  143. });
  144. }
  145. });
  146. </script>
  147. <style scoped></style>