Scene.vue 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. <script setup lang="ts">
  2. import { ref, onMounted } from 'vue'
  3. import { Scene } from '../lmm/core/Scene'
  4. import { Vector2 } from '../lmm/math/Vector2'
  5. import { Img2D } from '../lmm/objects/Img2D'
  6. // 获取父级属性
  7. const props = defineProps({
  8. size: { type: Object, default: { width: 1000, height: 500 } },
  9. })
  10. // 对应canvas 画布的Ref对象
  11. const canvasRef = ref<HTMLCanvasElement>()
  12. /* 场景 */
  13. const scene = new Scene()
  14. /* 图案 */
  15. const image = new Image()
  16. image.src =
  17. 'https://yxyy-pandora.oss-cn-beijing.aliyuncs.com/stamp-images/1.png'
  18. const pattern = new Img2D({ image })
  19. scene.add(pattern)
  20. /* 鼠标的裁剪坐标位 */
  21. const mouseClipPos = new Vector2(Infinity)
  22. /* 测试 */
  23. function test(canvas: HTMLCanvasElement) {
  24. const imgSize = new Vector2(image.width, image.height).multiplyScalar(0.6)
  25. pattern.setOption({
  26. /* 模型矩阵 */
  27. rotate: 0.4,
  28. position: new Vector2(0, -50),
  29. scale: new Vector2(0.5),
  30. /* Img属性 */
  31. size: imgSize.clone(),
  32. offset: imgSize.clone().multiplyScalar(-0.5),
  33. /* 样式 */
  34. style: {
  35. globalAlpha: 0.8,
  36. shadowColor: 'rgba(0,0,0,0.5)',
  37. shadowBlur: 0,
  38. },
  39. })
  40. /* 相机位移测试 */
  41. scene.camera.position.set(0, 100)
  42. /* 记录鼠标的裁剪坐标位 */
  43. canvas.addEventListener('mousemove', ({ clientX, clientY }) => {
  44. mouseClipPos.copy(scene.clientToClip(clientX, clientY))
  45. })
  46. /* 动画 */
  47. ani()
  48. }
  49. function ani(time = 0) {
  50. /* 相机缩放测试 */
  51. const inter = (Math.sin(time * 0.002) + 1) / 2
  52. scene.camera.zoom = inter + 0.5
  53. /* 投影 */
  54. pattern.style.shadowOffsetY = 80 * (1 - inter)
  55. pattern.style.shadowBlur = 10 * (1 - inter)
  56. /* 选择测试 */
  57. if (scene.isPointInObj(pattern, mouseClipPos, pattern.pvmoMatrix)) {
  58. pattern.rotate += 0.02
  59. }
  60. /* 渲染 */
  61. scene.render()
  62. requestAnimationFrame(ani)
  63. }
  64. onMounted(() => {
  65. const canvas = canvasRef.value
  66. if (canvas) {
  67. scene.setOption({ canvas })
  68. image.onload = function () {
  69. test(canvas)
  70. }
  71. }
  72. })
  73. </script>
  74. <template>
  75. <canvas ref="canvasRef" :width="size.width" :height="size.height"></canvas>
  76. </template>
  77. <style scoped></style>