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
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
|