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

import { getCanvasSize } from './paperConfig.js'
/**
* 坐标转换工具类
* 处理画布坐标到ZPL打印坐标的转换
*/
export class CoordinateTransformer {
constructor(orientation = 'portrait', paperType = '60x40', customSize = null, paperId = null) {
this.orientation = orientation
this.paperType = paperType
this.customSize = customSize
this.paperId = paperId // 新增纸张ID支持
this.config = this.getConfig()
}
/**
* 获取配置参数
*/
getConfig() {
let canvasSize
this.paperId = localStorage.getItem('paperId')
// 优先使用纸张ID
if (this.paperId) {
try {
// 延迟导入避免循环依赖
const { default: dynamicPaperConfig } = require('./paperConfigDynamic.js')
const paper = dynamicPaperConfig.getPaperById(this.paperId)
if (paper) {
const pixelSize = dynamicPaperConfig.calculatePixelSize(paper, 300, this.orientation)
canvasSize = {
width: pixelSize.width,
height: pixelSize.height,
name: paper.name,
description: paper.description || ''
}
console.log(`坐标转换器 - 纸张配置:`, {
paperId: this.paperId,
paperName: paper.name,
orientation: this.orientation,
originalSize: `${paper.widthMm}×${paper.heightMm}mm`,
pixelSize: `${pixelSize.width}×${pixelSize.height}px`,
dpi: 203
})
}
} catch (error) {
console.warn('获取动态纸张配置失败,使用降级方案:', error)
}
}
// 降级方案
if (!canvasSize) {
if (this.paperType === 'custom' && this.customSize) {
// 自定义尺寸直接使用,不在这里处理方向转换
// 方向转换应该在上层组件中统一处理
canvasSize = {
width: this.customSize.width,
height: this.customSize.height,
name: '自定义',
description: `自定义尺寸 (${this.orientation === 'landscape' ? '横向' : '纵向'})`
}
console.log(`坐标转换器 - 自定义尺寸:`, canvasSize)
} else {
canvasSize = getCanvasSize(this.paperType, this.orientation)
console.log(`坐标转换器 - 降级方案:`, {
paperType: this.paperType,
orientation: this.orientation,
canvasSize
})
}
}
const configs = {
portrait: {
canvasSize,
scaleX: 1,
scaleY: 1,
offsetX: 0,
offsetY: 0
},
landscape: {
canvasSize,
scaleX: 1,
scaleY: 1,
offsetX: 0,
offsetY: 0
}
}
return configs[this.orientation] || configs.portrait
}
/**
* 更新纸张类型
*/
updatePaperType(paperType, customSize = null, paperId = null) {
this.paperType = paperType
this.customSize = customSize
this.paperId = paperId
this.config = this.getConfig()
}
/**
* 更新纸张ID(新增方法)
*/
updatePaperId(paperId) {
this.paperId = paperId
this.config = this.getConfig()
}
/**
* 将画布坐标转换为ZPL坐标
* @param {number} canvasX - 画布X坐标
* @param {number} canvasY - 画布Y坐标
* @returns {Object} ZPL坐标 {x, y}
*/
toZPL(canvasX, canvasY) {
if (this.orientation === 'portrait') {
// 纵向打印:直接映射
const result = {
x: Math.round(canvasX * this.config.scaleX),
y: Math.round(canvasY * this.config.scaleY)
};
return result;
} else {
const { width, height } = this.config.canvasSize;
const result = {
x: Math.round(canvasY * this.config.scaleX),
y: Math.round((width - canvasX-100) * this.config.scaleY)
};
return result;
}
}
/**
* 将ZPL坐标转换为画布坐标
* @param {number} zplX - ZPL X坐标
* @param {number} zplY - ZPL Y坐标
* @returns {Object} 画布坐标 {x, y}
*/
toCanvas(zplX, zplY) {
if (this.orientation === 'portrait') {
// 纵向打印:直接映射
return {
x: Math.round(zplX / this.config.scaleX),
y: Math.round(zplY / this.config.scaleY)
}
} else {
// 横向打印的逆变换
// 与修正后的 toZPL 方法对应的逆转换
const { width, height } = this.config.canvasSize
return {
x: Math.round(zplY / this.config.scaleX),
y: Math.round((height - zplX) / this.config.scaleY)
}
}
}
/**
* 获取画布尺寸
* @returns {Object} 画布尺寸 {width, height}
*/
getCanvasSize() {
return { ...this.config.canvasSize }
}
/**
* 验证坐标是否在画布范围内
* @param {number} x - X坐标
* @param {number} y - Y坐标
* @returns {boolean} 是否在范围内
*/
isInBounds(x, y) {
const { width, height } = this.config.canvasSize
return x >= 0 && x <= width && y >= 0 && y <= height
}
/**
* 将坐标限制在画布范围内
* @param {number} x - X坐标
* @param {number} y - Y坐标
* @param {number} elementWidth - 元素宽度
* @param {number} elementHeight - 元素高度
* @returns {Object} 限制后的坐标 {x, y}
*/
clampToBounds(x, y, elementWidth = 50, elementHeight = 50) {
const { width, height } = this.config.canvasSize
return {
x: Math.max(0, Math.min(x, width - elementWidth)),
y: Math.max(0, Math.min(y, height - elementHeight))
}
}
}
/**
* 创建坐标转换器实例
* @param {string} orientation - 打印方向 'portrait' | 'landscape'
* @param {string} paperType - 纸张类型(兼容性)
* @param {Object} customSize - 自定义尺寸(兼容性)
* @param {number} paperId - 纸张ID(新增)
* @returns {CoordinateTransformer} 转换器实例
*/
export function createCoordinateTransformer(orientation, paperType = null, customSize = null, paperId = null) {
return new CoordinateTransformer(orientation, paperType, customSize, paperId)
}
/**
* 根据纸张ID创建坐标转换器实例(新增方法)
* @param {number} paperId - 纸张ID
* @param {string} orientation - 打印方向
* @returns {CoordinateTransformer} 转换器实例
*/
export function createCoordinateTransformerById(paperId, orientation = 'portrait') {
return new CoordinateTransformer(orientation, null, null, paperId)
}
export default CoordinateTransformer