Grid.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import Canvas from './Canvas'
  2. // 网格
  3. export default class Grid {
  4. constructor(app) {
  5. this.app = app
  6. this.canvas = null
  7. this.ctx = null
  8. this.init()
  9. this.app.on('zoomChange', this.renderGrid, this)
  10. this.app.on('scrollChange', this.renderGrid, this)
  11. }
  12. // 初始化
  13. init() {
  14. if (this.canvas) {
  15. this.app.container.removeChild(this.canvas.el)
  16. }
  17. let { width, height } = this.app
  18. this.canvas = new Canvas(width, height, {
  19. className: 'grid'
  20. })
  21. this.ctx = this.canvas.ctx
  22. this.app.container.insertBefore(
  23. this.canvas.el,
  24. this.app.container.children[0]
  25. )
  26. }
  27. // 绘制水平线
  28. drawHorizontalLine(i) {
  29. let { coordinate, width, state } = this.app
  30. let _i = coordinate.subScrollY(i)
  31. this.ctx.beginPath()
  32. this.ctx.moveTo(-width / state.scale / 2, _i)
  33. this.ctx.lineTo(width / state.scale / 2, _i)
  34. this.ctx.stroke()
  35. }
  36. // 渲染水平线
  37. renderHorizontalLines() {
  38. let { coordinate, height, state } = this.app
  39. let { gridConfig, scale } = state
  40. let maxBottom = 0
  41. for (let i = -height / 2; i < height / 2; i += gridConfig.size) {
  42. this.drawHorizontalLine(i)
  43. maxBottom = i
  44. }
  45. // 向下滚时绘制上方超出的线
  46. for (
  47. let i = -height / 2 - gridConfig.size;
  48. i > -coordinate.subScrollY(height / scale / 2);
  49. i -= gridConfig.size
  50. ) {
  51. this.drawHorizontalLine(i)
  52. }
  53. // 向上滚时绘制下方超出的线
  54. for (
  55. let i = maxBottom + gridConfig.size;
  56. i < coordinate.addScrollY(height / scale / 2);
  57. i += gridConfig.size
  58. ) {
  59. this.drawHorizontalLine(i)
  60. }
  61. }
  62. // 绘制重置线
  63. drawVerticalLine(i) {
  64. let { coordinate, height, state } = this.app
  65. let _i = coordinate.subScrollX(i)
  66. this.ctx.beginPath()
  67. this.ctx.moveTo(_i, -height / state.scale / 2)
  68. this.ctx.lineTo(_i, height / state.scale / 2)
  69. this.ctx.stroke()
  70. }
  71. // 渲染垂直线
  72. renderVerticalLines() {
  73. let { coordinate, width, state } = this.app
  74. let { gridConfig, scale } = state
  75. let maxRight = 0
  76. for (let i = -width / 2; i < width / 2; i += gridConfig.size) {
  77. this.drawVerticalLine(i)
  78. maxRight = i
  79. }
  80. // 向右滚时绘制左方超出的线
  81. for (
  82. let i = -width / 2 - gridConfig.size;
  83. i > -coordinate.subScrollX(width / scale / 2);
  84. i -= gridConfig.size
  85. ) {
  86. this.drawVerticalLine(i)
  87. }
  88. // 向左滚时绘制右方超出的线
  89. for (
  90. let i = maxRight + gridConfig.size;
  91. i < coordinate.addScrollX(width / scale / 2);
  92. i += gridConfig.size
  93. ) {
  94. this.drawVerticalLine(i)
  95. }
  96. }
  97. // 渲染网格
  98. renderGrid() {
  99. this.canvas.clearCanvas()
  100. let { gridConfig, scale, showGrid } = this.app.state
  101. if (!showGrid) {
  102. return
  103. }
  104. this.ctx.save()
  105. this.ctx.scale(scale, scale)
  106. this.ctx.strokeStyle = gridConfig.strokeStyle
  107. this.ctx.lineWidth = gridConfig.lineWidth
  108. // 水平
  109. this.renderHorizontalLines()
  110. // 垂直
  111. this.renderVerticalLines()
  112. this.ctx.restore()
  113. }
  114. // 显示网格
  115. showGrid() {
  116. this.app.updateState({
  117. showGrid: true
  118. })
  119. this.renderGrid()
  120. }
  121. // 隐藏网格
  122. hideGrid() {
  123. this.app.updateState({
  124. showGrid: false
  125. })
  126. this.canvas.clearCanvas()
  127. }
  128. // 更新网格配置
  129. updateGrid(config = {}) {
  130. this.app.updateState({
  131. gridConfig: {
  132. ...this.app.state.gridConfig,
  133. ...config
  134. }
  135. })
  136. if (this.app.state.showGrid) {
  137. this.hideGrid()
  138. this.showGrid()
  139. }
  140. }
  141. }