You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

217 lines
6.3 KiB

11 months ago
11 months ago
11 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
11 months ago
10 months ago
11 months ago
11 months ago
11 months ago
10 months ago
11 months ago
10 months ago
11 months ago
10 months ago
11 months ago
10 months ago
11 months ago
10 months ago
11 months ago
10 months ago
11 months ago
11 months ago
11 months ago
  1. import { getCanvasSize } from './paperConfig.js'
  2. /**
  3. * 坐标转换工具类
  4. * 处理画布坐标到ZPL打印坐标的转换
  5. */
  6. export class CoordinateTransformer {
  7. constructor(orientation = 'portrait', paperType = '60x40', customSize = null, paperId = null) {
  8. this.orientation = orientation
  9. this.paperType = paperType
  10. this.customSize = customSize
  11. this.paperId = paperId // 新增纸张ID支持
  12. this.config = this.getConfig()
  13. }
  14. /**
  15. * 获取配置参数
  16. */
  17. getConfig() {
  18. let canvasSize
  19. this.paperId = localStorage.getItem('paperId')
  20. // 优先使用纸张ID
  21. if (this.paperId) {
  22. try {
  23. // 延迟导入避免循环依赖
  24. const { default: dynamicPaperConfig } = require('./paperConfigDynamic.js')
  25. const paper = dynamicPaperConfig.getPaperById(this.paperId)
  26. if (paper) {
  27. const pixelSize = dynamicPaperConfig.calculatePixelSize(paper, 300, this.orientation)
  28. canvasSize = {
  29. width: pixelSize.width,
  30. height: pixelSize.height,
  31. name: paper.name,
  32. description: paper.description || ''
  33. }
  34. console.log(`坐标转换器 - 纸张配置:`, {
  35. paperId: this.paperId,
  36. paperName: paper.name,
  37. orientation: this.orientation,
  38. originalSize: `${paper.widthMm}×${paper.heightMm}mm`,
  39. pixelSize: `${pixelSize.width}×${pixelSize.height}px`,
  40. dpi: 203
  41. })
  42. }
  43. } catch (error) {
  44. console.warn('获取动态纸张配置失败,使用降级方案:', error)
  45. }
  46. }
  47. // 降级方案
  48. if (!canvasSize) {
  49. if (this.paperType === 'custom' && this.customSize) {
  50. // 自定义尺寸直接使用,不在这里处理方向转换
  51. // 方向转换应该在上层组件中统一处理
  52. canvasSize = {
  53. width: this.customSize.width,
  54. height: this.customSize.height,
  55. name: '自定义',
  56. description: `自定义尺寸 (${this.orientation === 'landscape' ? '横向' : '纵向'})`
  57. }
  58. console.log(`坐标转换器 - 自定义尺寸:`, canvasSize)
  59. } else {
  60. canvasSize = getCanvasSize(this.paperType, this.orientation)
  61. console.log(`坐标转换器 - 降级方案:`, {
  62. paperType: this.paperType,
  63. orientation: this.orientation,
  64. canvasSize
  65. })
  66. }
  67. }
  68. const configs = {
  69. portrait: {
  70. canvasSize,
  71. scaleX: 1,
  72. scaleY: 1,
  73. offsetX: 0,
  74. offsetY: 0
  75. },
  76. landscape: {
  77. canvasSize,
  78. scaleX: 1,
  79. scaleY: 1,
  80. offsetX: 0,
  81. offsetY: 0
  82. }
  83. }
  84. return configs[this.orientation] || configs.portrait
  85. }
  86. /**
  87. * 更新纸张类型
  88. */
  89. updatePaperType(paperType, customSize = null, paperId = null) {
  90. this.paperType = paperType
  91. this.customSize = customSize
  92. this.paperId = paperId
  93. this.config = this.getConfig()
  94. }
  95. /**
  96. * 更新纸张ID新增方法
  97. */
  98. updatePaperId(paperId) {
  99. this.paperId = paperId
  100. this.config = this.getConfig()
  101. }
  102. /**
  103. * 将画布坐标转换为ZPL坐标
  104. * @param {number} canvasX - 画布X坐标
  105. * @param {number} canvasY - 画布Y坐标
  106. * @returns {Object} ZPL坐标 {x, y}
  107. */
  108. toZPL(canvasX, canvasY) {
  109. if (this.orientation === 'portrait') {
  110. // 纵向打印:直接映射
  111. const result = {
  112. x: Math.round(canvasX * this.config.scaleX),
  113. y: Math.round(canvasY * this.config.scaleY)
  114. };
  115. return result;
  116. } else {
  117. const { width, height } = this.config.canvasSize;
  118. const result = {
  119. x: Math.round(canvasY * this.config.scaleX),
  120. y: Math.round((width - canvasX-100) * this.config.scaleY)
  121. };
  122. return result;
  123. }
  124. }
  125. /**
  126. * 将ZPL坐标转换为画布坐标
  127. * @param {number} zplX - ZPL X坐标
  128. * @param {number} zplY - ZPL Y坐标
  129. * @returns {Object} 画布坐标 {x, y}
  130. */
  131. toCanvas(zplX, zplY) {
  132. if (this.orientation === 'portrait') {
  133. // 纵向打印:直接映射
  134. return {
  135. x: Math.round(zplX / this.config.scaleX),
  136. y: Math.round(zplY / this.config.scaleY)
  137. }
  138. } else {
  139. // 横向打印的逆变换
  140. // 与修正后的 toZPL 方法对应的逆转换
  141. const { width, height } = this.config.canvasSize
  142. return {
  143. x: Math.round(zplY / this.config.scaleX),
  144. y: Math.round((height - zplX) / this.config.scaleY)
  145. }
  146. }
  147. }
  148. /**
  149. * 获取画布尺寸
  150. * @returns {Object} 画布尺寸 {width, height}
  151. */
  152. getCanvasSize() {
  153. return { ...this.config.canvasSize }
  154. }
  155. /**
  156. * 验证坐标是否在画布范围内
  157. * @param {number} x - X坐标
  158. * @param {number} y - Y坐标
  159. * @returns {boolean} 是否在范围内
  160. */
  161. isInBounds(x, y) {
  162. const { width, height } = this.config.canvasSize
  163. return x >= 0 && x <= width && y >= 0 && y <= height
  164. }
  165. /**
  166. * 将坐标限制在画布范围内
  167. * @param {number} x - X坐标
  168. * @param {number} y - Y坐标
  169. * @param {number} elementWidth - 元素宽度
  170. * @param {number} elementHeight - 元素高度
  171. * @returns {Object} 限制后的坐标 {x, y}
  172. */
  173. clampToBounds(x, y, elementWidth = 50, elementHeight = 50) {
  174. const { width, height } = this.config.canvasSize
  175. return {
  176. x: Math.max(0, Math.min(x, width - elementWidth)),
  177. y: Math.max(0, Math.min(y, height - elementHeight))
  178. }
  179. }
  180. }
  181. /**
  182. * 创建坐标转换器实例
  183. * @param {string} orientation - 打印方向 'portrait' | 'landscape'
  184. * @param {string} paperType - 纸张类型兼容性
  185. * @param {Object} customSize - 自定义尺寸兼容性
  186. * @param {number} paperId - 纸张ID新增
  187. * @returns {CoordinateTransformer} 转换器实例
  188. */
  189. export function createCoordinateTransformer(orientation, paperType = null, customSize = null, paperId = null) {
  190. return new CoordinateTransformer(orientation, paperType, customSize, paperId)
  191. }
  192. /**
  193. * 根据纸张ID创建坐标转换器实例新增方法
  194. * @param {number} paperId - 纸张ID
  195. * @param {string} orientation - 打印方向
  196. * @returns {CoordinateTransformer} 转换器实例
  197. */
  198. export function createCoordinateTransformerById(paperId, orientation = 'portrait') {
  199. return new CoordinateTransformer(orientation, null, null, paperId)
  200. }
  201. export default CoordinateTransformer