MatrixOfCanvas.vue 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. <script setup lang="ts">
  2. import { onMounted, ref } from 'vue'
  3. import { Vector2 } from '../lmm/math/Vector2'
  4. import { Matrix3 } from '../lmm/math/Matrix3'
  5. defineProps({
  6. size: {
  7. type: Object,
  8. default: {
  9. width: 1000,
  10. height: 500,
  11. },
  12. },
  13. })
  14. const canvasRef = ref<HTMLCanvasElement>()
  15. /* 矩形的初始顶点 */
  16. const vertices = [
  17. //1
  18. 0, 0,
  19. //2
  20. 100, 0,
  21. //3
  22. 100, 50,
  23. //4
  24. 0, 50,
  25. ]
  26. /* 矩形的模型矩阵数据 */
  27. const position = new Vector2(300, 200)
  28. const rotate = 0.4
  29. const scale = new Vector2(1, 2)
  30. /* 矩阵 */
  31. /* const [pm, rm, sm] = [
  32. new Matrix3().makeTranslation(position.x, position.y),
  33. new Matrix3().makeRotation(rotate),
  34. new Matrix3().makeScale(scale.x, scale.y),
  35. ]
  36. const matrix = pm.multiply(rm).multiply(sm) */
  37. const matrix = new Matrix3()
  38. .scale(scale.x, scale.y)
  39. .rotate(rotate)
  40. .translate(position.x, position.y)
  41. /* 绘制矩形 */
  42. function drawRect(
  43. ctx: CanvasRenderingContext2D,
  44. vertices: number[],
  45. color: string = 'black',
  46. lineWidth: number = 0
  47. ) {
  48. ctx.fillStyle = color
  49. ctx.strokeStyle = color
  50. ctx.lineWidth = lineWidth
  51. ctx.beginPath()
  52. ctx.moveTo(vertices[0], vertices[1])
  53. for (let i = 2, len = vertices.length; i < len; i += 2) {
  54. ctx.lineTo(vertices[i], vertices[i + 1])
  55. }
  56. ctx.closePath()
  57. ctx.stroke()
  58. ctx.fill()
  59. }
  60. /* 矩阵测试 */
  61. function matrixTest(ctx: CanvasRenderingContext2D) {
  62. /* translate(),rotate(),scale()测试 */
  63. ctx.save()
  64. ctx.translate(position.x, position.y)
  65. /* 先缩放,后旋转 > 矩形 */
  66. ctx.rotate(rotate)
  67. ctx.scale(scale.x, scale.y)
  68. /* 先旋转,后缩放 > 平行四边形 */
  69. /* ctx.scale(scale.x, scale.y)
  70. ctx.rotate(rotate) */
  71. drawRect(ctx, vertices, 'black', 40)
  72. ctx.restore()
  73. /* 矩阵测试 */
  74. const { elements: e } = matrix
  75. console.log(e)
  76. ctx.save()
  77. ctx.transform(e[0], e[1], e[3], e[4], e[6], e[7])
  78. drawRect(ctx, vertices, '#00acec', 20)
  79. ctx.restore()
  80. /* 顶点变换 */
  81. ctx.save()
  82. drawRect(ctx, tranformVertices(vertices, matrix), '#acec00', 0)
  83. ctx.restore()
  84. }
  85. /* 顶点变换 */
  86. function tranformVertices(vertices: number[], matrix: Matrix3) {
  87. const worldVertives: number[] = []
  88. for (let i = 0, len = vertices.length; i < len; i += 2) {
  89. const { x, y } = new Vector2(vertices[i], vertices[i + 1]).applyMatrix3(
  90. matrix
  91. )
  92. worldVertives.push(x, y)
  93. }
  94. return worldVertives
  95. }
  96. onMounted(() => {
  97. const canvas = canvasRef.value
  98. const ctx = canvas?.getContext('2d')
  99. ctx && matrixTest(ctx)
  100. })
  101. </script>
  102. <template>
  103. <canvas ref="canvasRef" :width="size.width" :height="size.height"></canvas>
  104. </template>
  105. <style scoped></style>