Files
SoonDesign/lib/design2/ui.js
T
2025-12-12 00:10:13 +08:00

3471 lines
118 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
var _keyctrl = false,
_keyc = false,
_textEdit = false,
_inputEdit = false
$('input').focus(function () {
_inputEdit = true
})
$('input').blur(function () {
_inputEdit = false
})
$('textarea').focus(function () {
_inputEdit = true
})
$('textarea').blur(function () {
_inputEdit = false
})
$('body').keyup(function (event) {
// 兼容三端的 modifier key 检测(Windows/Linux: Ctrl, Mac: Cmd/Meta
if (event.keyCode == 17 || event.keyCode == 91 || event.keyCode == 93) { // Ctrl 键或 Meta 键(Mac Cmd)释放
_keyctrl = false
}
if (event.keyCode == 67) {
_keyc = false
}
})
$('body').keydown(function (event) {
// 统一的快捷键处理(兼容 Windows/Linux: Ctrl, Mac: Cmd/Meta
const isModifierKey = event.ctrlKey || event.metaKey; // 兼容三端
// 快捷键处理(在输入框或文本区域中时不触发,除了删除相关的)
if (!_inputEdit && !_textEdit) {
// CTRL/CMD+N - 新建
if (isModifierKey && event.keyCode == 78) {
event.preventDefault();
$('#new').click();
return;
}
// CTRL/CMD+O - 打开
if (isModifierKey && event.keyCode == 79) {
event.preventDefault();
$('#open').click();
return;
}
// CTRL/CMD+S - 保存
if (isModifierKey && !event.shiftKey && event.keyCode == 83) {
event.preventDefault();
$('#save').click();
return;
}
// CTRL/CMD+SHIFT+S - 保存副本
if (isModifierKey && event.shiftKey && event.keyCode == 83) {
event.preventDefault();
if (typeof window.output === 'function') {
window.output(null, saveAs);
}
return;
}
// CTRL/CMD+Z - 还原
if (isModifierKey && !event.shiftKey && event.keyCode == 90) {
event.preventDefault();
$('#previous').click();
return;
}
// CTRL/CMD+Y - 重做
if (isModifierKey && !event.shiftKey && event.keyCode == 89) {
event.preventDefault();
$('#next').click();
return;
}
// CTRL/CMD+C - 复制
if (isModifierKey && event.keyCode == 67 && event.target.nodeName == 'BODY') {
event.preventDefault();
window.copySelection();
return;
}
// CTRL/CMD+V - 粘贴
if (isModifierKey && event.keyCode == 86 && event.target.nodeName == 'BODY') {
event.preventDefault();
window.pasteFromClipboard();
return;
}
// CTRL/CMD+SHIFT+DEL - 清空
if (isModifierKey && event.shiftKey && event.keyCode == 46) {
event.preventDefault();
$('#clean').click();
return;
}
// CTRL/CMD+DEL - 删除
if (isModifierKey && !event.shiftKey && event.keyCode == 46) {
event.preventDefault();
$('#delete').click();
return;
}
}
// 兼容三端的 modifier key 检测(Windows/Linux: Ctrl, Mac: Cmd/Meta
if (event.keyCode == 17 || event.metaKey) { // Ctrl 键或 Meta 键(Mac Cmd
_keyctrl = true
if (_keyc && _textEdit) {
//同时按下且在编辑状态
setTimeout("clipboard.writeText( (clipboard.readText()+' ') );", 1)
//clipboard.writeText((clipboard.readText()+' '))
}
}
if (event.keyCode == 67) {
_keyc = true
if (_keyctrl & _textEdit) {
//同时按下且在编辑状态
setTimeout("clipboard.writeText( (clipboard.readText()+' ') );", 1)
//clipboard.writeText((clipboard.readText()+' '))
}
}
if (event.keyCode == 37) {
//left
let v = -1
if (_keyctrl || event.ctrlKey || event.metaKey) {
v = -5
}
if (canvas.getActiveObject()) {
let x = canvas.getActiveObject().get('left')
x += v
canvas.getActiveObject().set('left', x)
canvas.renderAll()
recordState()
updateControls()
}
}
if (event.keyCode == 38) {
//up
let v = -1
if (_keyctrl || event.ctrlKey || event.metaKey) {
v = -5
}
if (canvas.getActiveObject()) {
let y = canvas.getActiveObject().get('top')
y += v
canvas.getActiveObject().set('top', y)
canvas.renderAll()
recordState()
updateControls()
}
}
if (event.keyCode == 39) {
//right
let v = 1
if (_keyctrl || event.ctrlKey || event.metaKey) {
v = 5
}
if (canvas.getActiveObject()) {
let x = canvas.getActiveObject().get('left')
x += v
canvas.getActiveObject().set('left', x)
canvas.renderAll()
recordState()
updateControls()
}
}
if (event.keyCode == 40) {
//down
let v = +1
if (_keyctrl || event.ctrlKey || event.metaKey) {
v = 5
}
if (canvas.getActiveObject()) {
let y = canvas.getActiveObject().get('top')
y += v
canvas.getActiveObject().set('top', y)
canvas.renderAll()
recordState()
updateControls()
}
}
// 普通删除键(DEL键,没有按CTRL/CMD
if (event.keyCode == 46 && !isModifierKey && !_inputEdit && !_textEdit) {
// 使用 window.canvas 作为后备,确保在 eval() 加载 .jsc 时也能访问
const currentCanvas = window.canvas || canvas;
const currentObjs = window.objs || objs;
if (!currentCanvas) {
console.error('canvas is undefined in delete handler');
return;
}
let actObjs = currentCanvas.getActiveObjects()
let allObjs = currentCanvas.getObjects()
let flag = 0
for (let item of actObjs) {
if (item != allObjs[0]) {
let i = getIndex(item, currentCanvas) //0是背景,所以从1开始,但objs不包含背景图片,故要-1
currentObjs.splice(i - 1, 1)
currentCanvas.remove(item)
flag = 1
}
}
if (typeof window.updateList === 'function') {
window.updateList();
}
currentCanvas.discardActiveObject()
if (flag == 1) {
recordState()
canvas.renderAll()
if (typeof window.handleObjectSelected === 'function') {
window.handleObjectSelected()
}
}
}
})
// pre_add_image 已在 design2.js 中定义为全局变量
$('#addPic').click(function () {
OpenDialog()
function OpenDialog() {
dialog
.showOpenDialog({
title: language_str('selectPic'), //请选择图片
buttonLabel: language_str('comf'), //"确认"
filters: [{ name: 'Image File Type', extensions: ['png', 'jpg', 'jpeg'] }]
})
.then((result) => {
if (result.canceled) return
//console.log(result.filePaths)
fabric.Image.fromURL(result.filePaths[0], function (image) {
//image.left = pointer.x;
image.setSrc(image.toDataURL(), function (image) {
pre_add_image = image
background_image.hoverCursor = 'crosshair'
$(this).css('background-color', '#646E76')
$('#addOutPic').css('background-color', '')
$('#addText').css('background-color', '')
$("#addCircleText").css("background-color", "");
$('#addOutText').css('background-color', '')
$('#addRect').css('background-color', '')
$('#addCircle').css('background-color', '')
$('#addLine').css('background-color', '')
$('#addQrCode').css('background-color', '')
$('#addBarCode').css('background-color', '')
$('#addCounter').css('background-color', '')
addState = 1
})
//canvas.add(image);
})
})
.catch((err) => {
})
}
})
$('#addOutPic').click(function () {
background_image.hoverCursor = 'crosshair'
$(this).css('background-color', '#646E76')
$('#addPic').css('background-color', '')
$('#addText').css('background-color', '')
$("#addCircleText").css("background-color", "");
$('#addOutText').css('background-color', '')
$('#addRect').css('background-color', '')
$('#addCircle').css('background-color', '')
$('#addLine').css('background-color', '')
$('#addQrCode').css('background-color', '')
$('#addBarCode').css('background-color', '')
$('#addCounter').css('background-color', '')
addState = 2
})
$('#addText').click(function () {
background_image.hoverCursor = 'crosshair'
$(this).css('background-color', '#646E76')
$('#addPic').css('background-color', '')
$('#addOutPic').css('background-color', '')
$("#addCircleText").css("background-color", "");
$('#addOutText').css('background-color', '')
$('#addRect').css('background-color', '')
$('#addCircle').css('background-color', '')
$('#addLine').css('background-color', '')
$('#addQrCode').css('background-color', '')
$('#addBarCode').css('background-color', '')
$('#addCounter').css('background-color', '')
addState = 3
})
$("#addCircleText").click(function () {
background_image.hoverCursor = "crosshair";
$(this).css("background-color", "#646E76");
$("#addPic").css("background-color", "");
$("#addOutPic").css("background-color", "");
$("#addText").css("background-color", "");
$("#addOutText").css("background-color", "");
$("#addRect").css("background-color", "");
$("#addCircle").css("background-color", "");
$("#addLine").css("background-color", "");
$("#addQrCode").css("background-color", "");
$("#addBarCode").css("background-color", "");
$("#addCounter").css("background-color", "");
addState = 11;
});
$('#addOutText').click(function () {
background_image.hoverCursor = 'crosshair'
$(this).css('background-color', '#646E76')
$('#addPic').css('background-color', '')
$('#addOutPic').css('background-color', '')
$('#addText').css('background-color', '')
$("#addCircleText").css("background-color", "");
$('#addRect').css('background-color', '')
$('#addCircle').css('background-color', '')
$('#addLine').css('background-color', '')
$('#addQrCode').css('background-color', '')
$('#addBarCode').css('background-color', '')
$('#addCounter').css('background-color', '')
addState = 4
})
$('#addRect').click(function () {
background_image.hoverCursor = 'crosshair'
$(this).css('background-color', '#646E76')
$('#addPic').css('background-color', '')
$('#addOutPic').css('background-color', '')
$('#addText').css('background-color', '')
$("#addCircleText").css("background-color", "");
$('#addOutText').css('background-color', '')
$('#addCircle').css('background-color', '')
$('#addLine').css('background-color', '')
$('#addQrCode').css('background-color', '')
$('#addBarCode').css('background-color', '')
$('#addCounter').css('background-color', '')
addState = 5
})
$('#addCircle').click(function () {
background_image.hoverCursor = 'crosshair'
$(this).css('background-color', '#646E76')
$('#addPic').css('background-color', '')
$('#addOutPic').css('background-color', '')
$('#addText').css('background-color', '')
$("#addCircleText").css("background-color", "");
$('#addOutText').css('background-color', '')
$('#addRect').css('background-color', '')
$('#addLine').css('background-color', '')
$('#addQrCode').css('background-color', '')
$('#addBarCode').css('background-color', '')
$('#addCounter').css('background-color', '')
addState = 6
})
$('#addLine').click(function () {
background_image.hoverCursor = 'crosshair'
$(this).css('background-color', '#646E76')
$('#addPic').css('background-color', '')
$('#addOutPic').css('background-color', '')
$('#addText').css('background-color', '')
$("#addCircleText").css("background-color", "");
$('#addOutText').css('background-color', '')
$('#addRect').css('background-color', '')
$('#addCircle').css('background-color', '')
$('#addQrCode').css('background-color', '')
$('#addBarCode').css('background-color', '')
$('#addCounter').css('background-color', '')
addState = 7
})
$('#addQrCode').click(function () {
background_image.hoverCursor = 'crosshair'
$(this).css('background-color', '#646E76')
$('#addPic').css('background-color', '')
$('#addOutPic').css('background-color', '')
$('#addText').css('background-color', '')
$("#addCircleText").css("background-color", "");
$('#addOutText').css('background-color', '')
$('#addRect').css('background-color', '')
$('#addCircle').css('background-color', '')
$('#addLine').css('background-color', '')
$('#addBarCode').css('background-color', '')
$('#addCounter').css('background-color', '')
addState = 8
})
$('#addBarCode').click(function () {
background_image.hoverCursor = 'crosshair'
$(this).css('background-color', '#646E76')
$('#addPic').css('background-color', '')
$('#addOutPic').css('background-color', '')
$('#addText').css('background-color', '')
$("#addCircleText").css("background-color", "");
$('#addOutText').css('background-color', '')
$('#addRect').css('background-color', '')
$('#addCircle').css('background-color', '')
$('#addLine').css('background-color', '')
$('#addQrCode').css('background-color', '')
$('#addCounter').css('background-color', '')
addState = 9
})
$('#addCounter').click(function () {
background_image.hoverCursor = 'crosshair'
$(this).css('background-color', '#646E76')
$('#addPic').css('background-color', '')
$('#addOutPic').css('background-color', '')
$('#addText').css('background-color', '')
$("#addCircleText").css("background-color", "");
$('#addOutText').css('background-color', '')
$('#addRect').css('background-color', '')
$('#addCircle').css('background-color', '')
$('#addLine').css('background-color', '')
$('#addQrCode').css('background-color', '')
$('#addBarCode').css('background-color', '')
addState = 10
})
$('#version_change').click(function () {
if (bg_version == 1) {
bg_version = 2
} else {
bg_version = 1
}
// 类型改变
$('#source_front').attr('src', './public/images/front_bg' + bg_version + '_2.png')
canvas.renderAll()
})
$('#front_side').click(function () {
$(this).addClass('ui-button-active')
$('#back_side').removeClass('ui-button-active')
$('.canvas-container:eq(0)').show()
$('.canvas-container:eq(1)').hide()
canvas = canvas1
objs = objs1
background_image = background_image1
window.canvas = canvas;
window.objs = objs;
window.background_image = background_image;
next_objs = next_objs1
pre_objs = pre_objs1
next_json = next_json1
pre_json = pre_json1
recordObjs = recordObjs1
recordJson = recordJson1
step = step1
if (typeof window.updateList === 'function') {
window.updateList();
}
$('#line_control').hide()
$('#base_control').hide()
$('#pic_control').hide()
$("#set_bg").hide();
$('#out_pic_control').hide()
$('#text_control').hide()
$("#circle_text_control").hide();
$('#out_text_control').hide()
$('#rect_control').hide()
$('#circle_control').hide()
$('#counter_control').hide()
$('#qrcode_Controll').hide()
$('#barcode_controll').hide()
$('#component_type').text(language_str('bg')) //背景
})
$('#back_side').click(function () {
$(this).addClass('ui-button-active')
$('#front_side').removeClass('ui-button-active')
$('.canvas-container:eq(0)').hide()
$('.canvas-container:eq(1)').show()
canvas = canvas2
objs = objs2
background_image = background_image2
window.canvas = canvas;
window.objs = objs;
window.background_image = background_image;
next_objs = next_objs2
pre_objs = pre_objs2
next_json = next_json2
pre_json = pre_json2
recordObjs = recordObjs2
recordJson = recordJson2
step = step2
if (typeof window.updateList === 'function') {
window.updateList();
}
$('#line_control').hide()
$('#base_control').hide()
$('#pic_control').hide()
$("#set_bg").hide();
$('#out_pic_control').hide()
$('#text_control').hide()
$("#circle_text_control").hide();
$('#out_text_control').hide()
$('#rect_control').hide()
$('#circle_control').hide()
$('#counter_control').hide()
$('#qrcode_Controll').hide()
$('#barcode_controll').hide()
$('#component_type').text(language_str('bg')) //"背景"
})
$('#top_alignment').click(function () {
let _objs = canvas.getActiveObjects()
if (_objs.length == 1) {
//只选中了一个,对齐到背景顶部
let obj = _objs[0]
obj.setCoords()
let coords = obj.getCoords(true)
let objMinY = getCoordsMinY(coords)
let bgMinY = getCoordsMinY(background_image.getCoords(true))
let deltaY = bgMinY - objMinY
obj.set('top', obj.get('top') + deltaY)
obj.setCoords()
canvas.renderAll()
recordState()
return
}
// 多个对象对齐:找到所有对象边界框的最小Y值
let minTop = Infinity
for (let item of _objs) {
item.setCoords()
let coords = item.getCoords(true)
let itemMinY = getCoordsMinY(coords)
if (itemMinY < minTop) {
minTop = itemMinY
}
}
// 将所有对象对齐到最小Y值
groupItems = []
for (let item of _objs) {
item.setCoords()
let coords = item.getCoords(true)
let itemMinY = getCoordsMinY(coords)
let deltaY = minTop - itemMinY
item.set('top', item.get('top') + deltaY)
item.setCoords()
groupItems.push(item)
}
canvas.discardActiveObject()
let sel = new fabric.ActiveSelection(groupItems, {
canvas: canvas
})
canvas.setActiveObject(sel)
canvas.requestRenderAll()
canvas.renderAll()
recordState()
})
$('#bottom_alignment').click(function () {
let _objs = canvas.getActiveObjects()
if (_objs.length == 1) {
//只选中了一个,对齐到背景底部
let obj = _objs[0]
obj.setCoords()
let coords = obj.getCoords(true)
let objMaxY = getCoordsMaxY(coords)
let bgMaxY = getCoordsMaxY(background_image.getCoords(true))
let deltaY = bgMaxY - objMaxY
obj.set('top', obj.get('top') + deltaY)
obj.setCoords()
canvas.renderAll()
recordState()
return
}
// 多个对象对齐:找到所有对象边界框的最大Y值
let maxBottom = -Infinity
for (let item of _objs) {
item.setCoords()
let coords = item.getCoords(true)
let itemMaxY = getCoordsMaxY(coords)
if (itemMaxY > maxBottom) {
maxBottom = itemMaxY
}
}
// 将所有对象对齐到最大Y值
groupItems = []
for (let item of _objs) {
item.setCoords()
let coords = item.getCoords(true)
let itemMaxY = getCoordsMaxY(coords)
let deltaY = maxBottom - itemMaxY
item.set('top', item.get('top') + deltaY)
item.setCoords()
groupItems.push(item)
}
canvas.discardActiveObject()
let sel = new fabric.ActiveSelection(groupItems, {
canvas: canvas
})
canvas.setActiveObject(sel)
canvas.requestRenderAll()
canvas.renderAll()
recordState()
})
$('#center_y_alignment').click(function () {
let _objs = canvas.getActiveObjects()
if (_objs.length == 1) {
//只选中了一个,对齐到背景垂直中心
let obj = _objs[0]
obj.setCoords()
let coords = obj.getCoords(true)
let objMinY = getCoordsMinY(coords)
let objMaxY = getCoordsMaxY(coords)
let objCenterY = (objMinY + objMaxY) / 2
let bgCoords = background_image.getCoords(true)
let bgMinY = getCoordsMinY(bgCoords)
let bgMaxY = getCoordsMaxY(bgCoords)
let bgCenterY = (bgMinY + bgMaxY) / 2
let deltaY = bgCenterY - objCenterY
obj.set('top', obj.get('top') + deltaY)
obj.setCoords()
canvas.renderAll()
recordState()
return
}
// 多个对象对齐:找到所有对象边界框的中心Y值
let minTop = Infinity
let maxBottom = -Infinity
for (let item of _objs) {
item.setCoords()
let coords = item.getCoords(true)
let itemMinY = getCoordsMinY(coords)
let itemMaxY = getCoordsMaxY(coords)
if (itemMinY < minTop) minTop = itemMinY
if (itemMaxY > maxBottom) maxBottom = itemMaxY
}
let groupCenterY = (minTop + maxBottom) / 2
// 将所有对象对齐到中心Y值
groupItems = []
for (let item of _objs) {
item.setCoords()
let coords = item.getCoords(true)
let itemMinY = getCoordsMinY(coords)
let itemMaxY = getCoordsMaxY(coords)
let itemCenterY = (itemMinY + itemMaxY) / 2
let deltaY = groupCenterY - itemCenterY
item.set('top', item.get('top') + deltaY)
item.setCoords()
groupItems.push(item)
}
canvas.discardActiveObject()
let sel = new fabric.ActiveSelection(groupItems, {
canvas: canvas
})
canvas.setActiveObject(sel)
canvas.requestRenderAll()
canvas.renderAll()
recordState()
})
$('#left_alignment').click(function () {
let _objs = canvas.getActiveObjects()
if (_objs.length == 1) {
//只选中了一个,对齐到背景左边缘
let obj = _objs[0]
obj.setCoords()
let coords = obj.getCoords(true)
let objMinX = getCoordsMinX(coords)
let bgMinX = getCoordsMinX(background_image.getCoords(true))
let deltaX = bgMinX - objMinX
obj.set('left', obj.get('left') + deltaX)
obj.setCoords()
canvas.renderAll()
recordState()
return
}
// 多个对象对齐:找到所有对象边界框的最小X值
let minLeft = Infinity
for (let item of _objs) {
item.setCoords()
let coords = item.getCoords(true)
let itemMinX = getCoordsMinX(coords)
if (itemMinX < minLeft) {
minLeft = itemMinX
}
}
// 将所有对象对齐到最小X值
groupItems = []
for (let item of _objs) {
item.setCoords()
let coords = item.getCoords(true)
let itemMinX = getCoordsMinX(coords)
let deltaX = minLeft - itemMinX
item.set('left', item.get('left') + deltaX)
item.setCoords()
groupItems.push(item)
}
canvas.discardActiveObject()
let sel = new fabric.ActiveSelection(groupItems, {
canvas: canvas
})
canvas.setActiveObject(sel)
canvas.requestRenderAll()
canvas.renderAll()
recordState()
})
$('#right_alignment').click(function () {
let _objs = canvas.getActiveObjects()
if (_objs.length == 1) {
//只选中了一个,对齐到背景右边缘
let obj = _objs[0]
obj.setCoords()
let coords = obj.getCoords(true)
let objMaxX = getCoordsMaxX(coords)
let bgMaxX = getCoordsMaxX(background_image.getCoords(true))
let deltaX = bgMaxX - objMaxX
obj.set('left', obj.get('left') + deltaX)
obj.setCoords()
canvas.renderAll()
recordState()
return
}
// 多个对象对齐:找到所有对象边界框的最大X值
let maxRight = -Infinity
for (let item of _objs) {
item.setCoords()
let coords = item.getCoords(true)
let itemMaxX = getCoordsMaxX(coords)
if (itemMaxX > maxRight) {
maxRight = itemMaxX
}
}
// 将所有对象对齐到最大X值
let groupItems = []
for (let item of _objs) {
item.setCoords()
let coords = item.getCoords(true)
let itemMaxX = getCoordsMaxX(coords)
let deltaX = maxRight - itemMaxX
item.set('left', item.get('left') + deltaX)
item.setCoords()
groupItems.push(item)
}
canvas.discardActiveObject()
let sel = new fabric.ActiveSelection(groupItems, {
canvas: canvas
})
canvas.setActiveObject(sel)
canvas.requestRenderAll()
canvas.renderAll()
recordState()
})
$('#center_x_alignment').click(function () {
let _objs = canvas.getActiveObjects()
if (_objs.length == 1) {
//只选中了一个,对齐到背景水平中心
let obj = _objs[0]
obj.setCoords()
let coords = obj.getCoords(true)
let objMinX = getCoordsMinX(coords)
let objMaxX = getCoordsMaxX(coords)
let objCenterX = (objMinX + objMaxX) / 2
let bgCoords = background_image.getCoords(true)
let bgMinX = getCoordsMinX(bgCoords)
let bgMaxX = getCoordsMaxX(bgCoords)
let bgCenterX = (bgMinX + bgMaxX) / 2
let deltaX = bgCenterX - objCenterX
obj.set('left', obj.get('left') + deltaX)
obj.setCoords()
canvas.renderAll()
recordState()
return
}
// 多个对象对齐:找到所有对象边界框的中心X值
let minLeft = Infinity
let maxRight = -Infinity
for (let item of _objs) {
item.setCoords()
let coords = item.getCoords(true)
let itemMinX = getCoordsMinX(coords)
let itemMaxX = getCoordsMaxX(coords)
if (itemMinX < minLeft) minLeft = itemMinX
if (itemMaxX > maxRight) maxRight = itemMaxX
}
let groupCenterX = (minLeft + maxRight) / 2
// 将所有对象对齐到中心X值
groupItems = []
for (let item of _objs) {
item.setCoords()
let coords = item.getCoords(true)
let itemMinX = getCoordsMinX(coords)
let itemMaxX = getCoordsMaxX(coords)
let itemCenterX = (itemMinX + itemMaxX) / 2
let deltaX = groupCenterX - itemCenterX
item.set('left', item.get('left') + deltaX)
item.setCoords()
groupItems.push(item)
}
canvas.discardActiveObject()
let sel = new fabric.ActiveSelection(groupItems, {
canvas: canvas
})
canvas.setActiveObject(sel)
canvas.requestRenderAll()
canvas.renderAll()
recordState()
})
$('#up_obj').click(function () {
//上移,放到前面 数组中在后面
let idx = getIndex(canvas.getActiveObject())
if (idx + 1 != canvas.getObjects().length) {
canvas.bringForward(canvas.getActiveObject())
canvas.renderAll()
let temp = objs[idx - 1]
objs[idx - 1] = objs[idx]
objs[idx] = temp
//console.log(objs);
recordState()
if (typeof window.updateList === 'function') {
window.updateList();
}
if (typeof window.selectObj === 'function') {
window.selectObj(idx);
}
}
})
$('#down_obj').click(function () {
//下移,放到后面 数组中在前面
let idx = getIndex(canvas.getActiveObject())
if (idx != 1) {
canvas.sendBackwards(canvas.getActiveObject())
canvas.renderAll()
//[objs[idx-2],objs[idx-1]] = [objs[idx-1],objs[idx-2]];
let temp = objs[idx - 1]
objs[idx - 1] = objs[idx - 2]
objs[idx - 2] = temp
recordState()
if (typeof window.updateList === 'function') {
window.updateList();
}
if (typeof window.selectObj === 'function') {
window.selectObj(idx - 2);
}
}
})
$('#set_bg').click(function () {
//设置为背景
let obj = canvas.getActiveObject()
let idx = getIndex(canvas.getActiveObject())
const scaleX = 1012 / obj.width
const scaleY = 648 / obj.height
// 使用缩放后的实际尺寸计算位置,确保与初始背景图片位置一致
const scaledWidth = obj.width * scaleX;
const scaledHeight = obj.height * scaleY;
obj.set({
scaleX: scaleX,
scaleY: scaleY,
left: ($('#canvas1').width() - scaledWidth) / 2,
top: ($('#canvas1').height() - scaledHeight) / 2
})
$('#text_w').val(1012)
$('#text_h').val(648)
$('#text_x').val(0)
$('#text_y').val(0)
// 设为背景时,锁定所有编辑操作,并设置为不可选中
obj.set({
lockMovementX: true,
lockMovementY: true,
lockRotation: true,
lockScalingX: true,
lockScalingY: true,
lockSkewingX: true,
lockSkewingY: true,
selectable: false,
evented: false
});
$("#lock_img").attr("src", "public/images/lock20.png")
canvas.sendToBack(canvas.getActiveObject())
canvas.bringForward(canvas.getActiveObject())
canvas.renderAll()
let objItem = objs.splice(idx - 1, 1)[0]
objs.unshift(objItem)
// 确保背景图(索引0)的锁定属性被正确设置
setTimeout(() => {
let bgObj = canvas.getObjects()[0];
if (bgObj) {
bgObj.set({
lockMovementX: true,
lockMovementY: true,
lockRotation: true,
lockScalingX: true,
lockScalingY: true,
lockSkewingX: true,
lockSkewingY: true,
selectable: false,
evented: false
});
canvas.renderAll();
}
}, 100);
recordState()
if (typeof window.updateList === 'function') {
window.updateList();
}
if (typeof window.selectObj === 'function') {
window.selectObj(0);
}
})
$('#previous').click(function () {
//撤销一次操作
if (step.val == 0) {
return
}
step.val--
if ($('#front_side').hasClass('ui-button-active')) {
// 使用 recordJson1 和 recordObjs1
if (recordJson1 && recordJson1[step.val]) {
canvas.loadFromJSON(recordJson1[step.val])
}
if (recordObjs1 && recordObjs1[step.val]) {
objs1 = JSON.parse(recordObjs1[step.val])
objs = objs1
}
} else if ($('#back_side').hasClass('ui-button-active')) {
// 使用 recordJson2 和 recordObjs2
if (recordJson2 && recordJson2[step.val]) {
canvas.loadFromJSON(recordJson2[step.val])
}
if (recordObjs2 && recordObjs2[step.val]) {
objs2 = JSON.parse(recordObjs2[step.val])
objs = objs2
}
}
background_image = canvas.getObjects()[0]
canvas.renderAll()
//recordState();
if (typeof window.updateList === 'function') {
window.updateList();
}
selectObj(-1)
$('#base_control').hide()
$('#line_control').hide()
$('#pic_control').hide()
$("#set_bg").hide();
$('#out_pic_control').hide()
$('#text_control').hide()
$("#circle_text_control").hide();
$('#out_text_control').hide()
$('#rect_control').hide()
$('#circle_control').hide()
$('#counter_control').hide()
$('#qrcode_Controll').hide()
$('#barcode_controll').hide()
})
$('#next').click(function () {
//撤销一次撤销操作
// 根据当前是正面还是背面检查对应的 recordObjs 长度
if ($('#front_side').hasClass('ui-button-active')) {
if (step.val >= recordObjs1.length - 1) {
return
}
} else if ($('#back_side').hasClass('ui-button-active')) {
if (step.val >= recordObjs2.length - 1) {
return
}
}
++step.val
if ($('#front_side').hasClass('ui-button-active')) {
// 使用 recordJson1 和 recordObjs1
if (recordJson1 && recordJson1[step.val]) {
canvas.loadFromJSON(recordJson1[step.val])
}
if (recordObjs1 && recordObjs1[step.val]) {
objs1 = JSON.parse(recordObjs1[step.val])
objs = objs1
}
} else if ($('#back_side').hasClass('ui-button-active')) {
// 使用 recordJson2 和 recordObjs2
if (recordJson2 && recordJson2[step.val]) {
canvas.loadFromJSON(recordJson2[step.val])
}
if (recordObjs2 && recordObjs2[step.val]) {
objs2 = JSON.parse(recordObjs2[step.val])
objs = objs2
}
}
background_image = canvas.getObjects()[0]
canvas.renderAll()
selectObj(-1)
$('#base_control').hide()
$('#line_control').hide()
$('#pic_control').hide()
$("#set_bg").hide();
$('#out_pic_control').hide()
$('#text_control').hide()
$("#circle_text_control").hide();
$('#out_text_control').hide()
$('#rect_control').hide()
$('#circle_control').hide()
$('#counter_control').hide()
$('#qrcode_Controll').hide()
$('#barcode_controll').hide()
if (typeof window.updateList === 'function') {
window.updateList();
}
})
$('#clean').click(function () {
objs.splice(0, objs.length)
let allObjs = canvas.getObjects()
for (let item of allObjs) {
if (item != allObjs[0]) {
canvas.remove(item)
}
}
if (typeof window.updateList === 'function') {
window.updateList();
}
recordState()
})
$('#rotate').click(function () {
let obj = canvas.getActiveObject()
obj.rotate(Math.round((obj.get('angle') + 90) % 360))
$('#text_r').val(obj.get('angle'))
canvas.renderAll()
updateControls()
recordState()
})
$('#vertical_obj').click(function () {
let obj = canvas.getActiveObject()
obj.set('flipY', !obj.get('flipY'))
canvas.renderAll()
updateControls()
recordState()
})
$('#align_obj').click(function () {
let obj = canvas.getActiveObject()
obj.set('flipX', !obj.get('flipX'))
canvas.renderAll()
updateControls()
recordState()
})
$('#text_italics').click(function () {
if ($(this).hasClass('ui-radio-acitve')) {
//已选
canvas.getActiveObject().set('fontStyle', 'normal')
$(this).removeClass('ui-radio-acitve')
} else {
//未选
canvas.getActiveObject().set('fontStyle', 'italic')
$(this).addClass('ui-radio-acitve')
}
recordState()
canvas.renderAll()
})
$('#text_bold').click(function () {
if ($(this).hasClass('ui-radio-acitve')) {
//已选,恢复正常
canvas.getActiveObject().set('fontWeight', 'normal')
$(this).removeClass('ui-radio-acitve')
} else {
//未选
canvas.getActiveObject().set('fontWeight', 'bold')
$(this).addClass('ui-radio-acitve')
}
recordState()
canvas.renderAll()
})
$('#text_underline').click(function () {
if ($(this).hasClass('ui-radio-acitve')) {
//已选
canvas.getActiveObject().set('underline', false)
$(this).removeClass('ui-radio-acitve')
} else {
//未选
canvas.getActiveObject().set('underline', true)
$(this).addClass('ui-radio-acitve')
}
recordState()
canvas.renderAll()
})
$('#text_linethrough').click(function () {
if ($(this).hasClass('ui-radio-acitve')) {
//已选
canvas.getActiveObject().set('linethrough', false)
$(this).removeClass('ui-radio-acitve')
} else {
//未选
canvas.getActiveObject().set('linethrough', true)
$(this).addClass('ui-radio-acitve')
}
recordState()
canvas.renderAll()
})
$("#circle_text_italics").click(function () {
if ($(this).hasClass("ui-radio-acitve")) {
//已选
canvas.getActiveObject().set("fontStyle", "normal")
$(this).removeClass("ui-radio-acitve")
} else {
//未选
canvas.getActiveObject().set("fontStyle", "italic")
$(this).addClass("ui-radio-acitve")
}
recordState();
canvas.renderAll();
});
$("#circle_text_bold").click(function () {
if ($(this).hasClass("ui-radio-acitve")) {
//已选,恢复正常
canvas.getActiveObject().set("fontWeight", "normal")
$(this).removeClass("ui-radio-acitve")
} else {
//未选
canvas.getActiveObject().set("fontWeight", "bold")
$(this).addClass("ui-radio-acitve")
}
recordState();
canvas.renderAll();
});
$('#out_left_alignment').click(function () {
$('#out_left_alignment').parent().removeClass('tool1')
$('#out_right_alignment').parent().removeClass('tool1')
$('#out_center_alignment').parent().removeClass('tool1')
setTimeout(() => {
$('#out_left_alignment').parent().addClass('tool1')
});
canvas.getActiveObject().set('textAlign', 'left')
let idx = getIndex(canvas.getActiveObject())
objs[idx - 1].align = 'left'
recordState()
canvas.renderAll()
})
$('#out_right_alignment').click(function () {
$('#out_left_alignment').parent().removeClass('tool1')
$('#out_right_alignment').parent().removeClass('tool1')
$('#out_center_alignment').parent().removeClass('tool1')
setTimeout(() => {
$('#out_right_alignment').parent().addClass('tool1')
});
canvas.getActiveObject().set('textAlign', 'right')
let idx = getIndex(canvas.getActiveObject())
objs[idx - 1].align = 'right'
recordState()
canvas.renderAll()
})
$('#out_center_alignment').click(function () {
$('#out_left_alignment').parent().removeClass('tool1')
$('#out_right_alignment').parent().removeClass('tool1')
$('#out_center_alignment').parent().removeClass('tool1')
setTimeout(() => {
$('#out_center_alignment').parent().addClass('tool1')
});
canvas.getActiveObject().set('textAlign', 'center')
let idx = getIndex(canvas.getActiveObject())
objs[idx - 1].align = 'center'
recordState()
canvas.renderAll()
})
$('#out_text_italics').click(function () {
if ($(this).hasClass('ui-radio-acitve')) {
//已选
canvas.getActiveObject().set('fontStyle', 'normal')
$(this).removeClass('ui-radio-acitve')
} else {
//未选
canvas.getActiveObject().set('fontStyle', 'italic')
$(this).addClass('ui-radio-acitve')
}
recordState()
canvas.renderAll()
})
$('#out_text_bold').click(function () {
if ($(this).hasClass('ui-radio-acitve')) {
//已选,恢复正常
canvas.getActiveObject().set('fontWeight', 'normal')
$(this).removeClass('ui-radio-acitve')
} else {
//未选
canvas.getActiveObject().set('fontWeight', 'bold')
$(this).addClass('ui-radio-acitve')
}
recordState()
canvas.renderAll()
})
$('#out_text_underline').click(function () {
if ($(this).hasClass('ui-radio-acitve')) {
//已选
canvas.getActiveObject().set('underline', false)
$(this).removeClass('ui-radio-acitve')
} else {
//未选
canvas.getActiveObject().set('underline', true)
$(this).addClass('ui-radio-acitve')
}
recordState()
canvas.renderAll()
})
$('#out_text_linethrough').click(function () {
if ($(this).hasClass('ui-radio-acitve')) {
//已选
canvas.getActiveObject().set('linethrough', false)
$(this).removeClass('ui-radio-acitve')
} else {
//未选
canvas.getActiveObject().set('linethrough', true)
$(this).addClass('ui-radio-acitve')
}
recordState()
canvas.renderAll()
})
$('#lock').off('click').on('click', function (e) {
e.stopPropagation();
if (!canvas.getActiveObject()) return;
let obj = canvas.getActiveObject();
// 检查是否已锁定(通过lockMovementX判断,因为锁定时会设置所有lock属性)
let isLocked = obj.get('lockMovementX') === true;
let shouldLock = !isLocked;
// 锁定/解锁所有编辑操作,锁定后不可选中
obj.set({
lockMovementX: shouldLock,
lockMovementY: shouldLock,
lockRotation: shouldLock,
lockScalingX: shouldLock,
lockScalingY: shouldLock,
lockSkewingX: shouldLock,
lockSkewingY: shouldLock,
// 锁定时不可选中,解锁时可选中
selectable: !shouldLock,
evented: !shouldLock
});
if (shouldLock) {
$('#lock_img').attr('src', 'public/images/lock20.png') //已锁定
// 锁定后取消选中
canvas.discardActiveObject();
canvas.renderAll();
// 锁定后不需要调用 updateControls,因为已经没有选中对象了
} else {
$('#lock_img').attr('src', 'public/images/unlock20.png') //已解锁
// 解锁后更新控件
updateControls();
}
recordState()
// 更新对象列表以同步锁状态
if (typeof window.updateList === 'function') {
window.updateList();
}
if (!shouldLock) {
canvas.renderAll();
}
})
$('#text_back_transparent').click(function () {
canvas.getActiveObject().set('textBackgroundColor', '')
$('#text_back_color').val('#ffffff')
canvas.renderAll()
})
$('#circle_text_back_transparent').click(function () {
canvas.getActiveObject().set('textBackgroundColor', '')
$('#circle_text_back_color').val('#ffffff')
canvas.renderAll()
})
$('#out_text_back_transparent').click(function () {
canvas.getActiveObject().set('textBackgroundColor', '')
$('#out_text_back_color').val('#ffffff')
canvas.renderAll()
})
$('#rect_transparent').click(function () {
canvas.getActiveObject().set('fill', '')
$('#rect_color').val('#ffffff')
canvas.renderAll()
})
$('#rect_stroke_transparent').click(function () {
canvas.getActiveObject().set('stroke', '')
$('#rect_stroke').val('#ffffff')
canvas.renderAll()
})
$('#circle_transparent').click(function () {
canvas.getActiveObject().set('fill', '')
$('#circle_color').val('#ffffff')
canvas.renderAll()
})
$('#circle_stroke_transparent').click(function () {
canvas.getActiveObject().set('stroke', '')
$('#circle_stroke').val('#ffffff')
canvas.renderAll()
})
// 清理不需要的 src 字段(保留自定义图片的 src)
// cleanupSrcFields 函数已在 output.js 中定义
function saveAs(op1, callback) {
let j = canvas1.toJSON(['selectable', 'hoverable', 'hoverCursor', 'text', 'fontStyle', 'fontWeight', 'underline'])
let b = canvas2.toJSON(['selectable', 'hoverable', 'hoverCursor', 'text', 'fontStyle', 'fontWeight', 'underline'])
// 清理不需要的 src 字段(使用 window.cleanupSrcFields,在 output.js 中定义)
if (typeof window.cleanupSrcFields === 'function') {
window.cleanupSrcFields(j.objects, objs1);
window.cleanupSrcFields(b.objects, objs2);
}
let o = { f: j, b: b, fo: objs1, bo: objs2 }
let con_o = Object.assign(o, op1)
dialog
.showSaveDialog({
title: language_str('saveFile'), //'保存文件'
filters: [{ name: 'Soon File Type', extensions: ['soon'] }]
})
.then((result) => {
if (result.filePath == '') {
return
}
if (result.filePath.substring(result.filePath.length - 5).indexOf('.') == -1) {
result.filePath += '.soon'
}
let fs = require('fs')
con_o.soonType = 2
fs.writeFileSync(result.filePath, JSON.stringify(con_o), 'utf8')
openAs.name = result.filePath
layer.msg(language_str('saveSucc') + openAs.name) //'保存成功至'
if (typeof window.saveHistory === 'function') {
window.saveHistory();
}
if (callback && typeof callback === 'function') {
callback()
}
})
.catch((err) => {
})
}
// save 函数已在 output.js 中定义
// 复制
$("#copy").click(function () {
window.copySelection();
})
// 粘贴
$("#paste").click(function () {
window.pasteFromClipboard();
})
// 保存按钮事件绑定
$('#save').click(function () {
if (typeof window.output === 'function') {
window.output(); // 调用 output 函数
}
return;
})
function getDate() {
let date = new Date()
return date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate()
}
function getAbsoluteXY(_obj) {
let coord = _obj.get('lineCoords')
//let xs = [], ys = [];
return [_obj.get('left'), _obj.get('top')]
}
// fullPath, saveHistory 和 open 函数已在 output.js 中定义
$('#open').click(function () {
if (step.val == 0) {
OpenDialog();
return;
}
layer.confirm(
'<font style="color:black">' + language_str('whetherSave') + '</font>',
function (index) {
if (typeof window.output === 'function') {
window.output(OpenDialog);
}
layer.close(index);
},
function (index) {
OpenDialog();
}
)
function OpenDialog() {
dialog
.showOpenDialog({
title: '请选择文件',
buttonLabel: language_str('comf'),
filters: [{ name: 'Soon File Type', extensions: ['soon'] }]
})
.then((result) => {
if (result.canceled) return;
let filePath = result.filePaths[0];
let fs = require('fs');
let fsData = fs.readFileSync(filePath);
let j = JSON.parse(fsData.toString());
let type = j.soonType ? j.soonType : j.backBlackPic ? 2 : 1;
if (type == 1) {
ipcRenderer.send('open-design-page', filePath, type);
return;
}
// 调用 output.js 中的 openFile 函数
if (typeof window.openFile === 'function') {
window.openFile(filePath);
} else {
console.error('openFile 函数未定义!');
}
})
.catch((err) => {
console.log(err);
})
}
})
$('#new').click(function () {
if (step.val == 0) {
ipcRenderer.send('open-first-page');
return;
}
layer.confirm(
'<font style="color:black">' + language_str('whetherSave') + '</font>',
function (index) {
if (typeof window.output === 'function') {
window.output(() => ipcRenderer.send('open-first-page'));
}
layer.close(index);
},
function (index) {
ipcRenderer.send('open-first-page');
}
)
})
function chagneTitle() { }
function addBackground() {
// 类型改变
fabric.Image.fromURL('./public/images/bg_front_2.png', function (image) {
//image.set("scaleX",$("#canvas-div").width() / 1200 < 1 ? $("#canvas-div").width() / 1200 : 1)
image.left = ($('#canvas1').width() - image.width * image.get('scaleX')) / 2
image.top = ($('#canvas1').height() - image.height * image.get('scaleY')) / 2
image.selectable = false
image.hoverable = false
image.hoverCursor = 'default'
image.setSrc(image.toDataURL(), function (image) {
background_image1 = image
background_image = background_image1
canvas.add(image)
canvas.renderAll()
//pre_objs1.push(JSON.stringify(objs1));
recordObjs1.push(JSON.stringify(objs1))
recordJson1.push(canvas1.toJSON(['selectable', 'hoverable', 'hoverCursor', 'text', 'fontStyle', 'fontWeight', 'underline']))
})
// 类型改变
fabric.Image.fromURL('./public/images/bg_back_2.png', function (image) {
image.left = ($('#canvas2').width() - image.width) / 2
image.top = ($('#canvas2').height() - image.height) / 2
image.selectable = false
image.hoverable = false
image.hoverCursor = 'default'
image.setSrc(image.toDataURL(), function (image) {
background_image2 = image
canvas2.add(image)
canvas2.renderAll()
//pre_objs2.push(JSON.stringify(objs2));
recordObjs2.push(JSON.stringify(objs2))
recordJson2.push(canvas2.toJSON(['selectable', 'hoverable', 'hoverCursor', 'text', 'fontStyle', 'fontWeight', 'underline']))
let file = GetFile().get('file')
if (file && file != 'empty') {
if (typeof window.openFile === 'function') {
window.openFile(file);
} else {
console.error('openFile 函数未定义!');
}
}
})
})
is_bgi_add = true
})
}
function selectObject(target, index) {
updateControls()
$('#base_control').show()
//$("#text_x").val((target.left - background_image.left).toFixed(1));
}
function updateControls() {
// 检查是否有选中对象,如果没有则直接返回
if (!canvas || !canvas.getActiveObject()) return;
const activeObj = canvas.getActiveObject();
$('#text_r').val(activeObj.get('angle').toFixed(0))
$('#text_x').val((activeObj.get('left') - background_image.left).toFixed(0))
$('#text_y').val((activeObj.get('top') - background_image.top).toFixed(0))
$('#text_h').val((activeObj.get('scaleY') * activeObj.get('height')).toFixed(0))
$('#text_w').val((activeObj.get('scaleX') * activeObj.get('width')).toFixed(0))
// 根据锁定状态显示图标(使用lockMovementX判断,因为锁定时会设置所有lock属性)
if (activeObj.get('lockMovementX')) {
$('#lock_img').attr('src', 'public/images/lock20.png') //已锁定
} else {
$('#lock_img').attr('src', 'public/images/unlock20.png') //未锁定
}
}
function checkName(name) {
//检查字段名是否重复了
for (let item of objs1) {
if (item.name == name) {
return false
}
}
for (let item of objs2) {
if (item.name == name) {
return false
}
}
return true
}
function resName(pre_name) {
//返回的是不重复的字段名
let num = objs1.length + objs2.length - 1
do {
num++
} while (!checkName(pre_name + num)) //重复了就再加1
return pre_name + num
}
function addPic(pointer) {
pre_add_image.left = pointer.x
pre_add_image.top = pointer.y
canvas.add(pre_add_image)
objs.push({ type: 1, black: false })
canvas.renderAll()
if (typeof window.updateList === 'function') {
window.updateList();
}
recordState()
//OpenDialog();
}
function selectPic(target, index) {
// 检查是否有选中对象,如果没有则直接返回
if (!canvas || !canvas.getActiveObject()) return;
let activeObj = canvas.getActiveObject();
// 检查对象是否被锁定或设为背景(索引0且已锁定)
let idx = getIndex(activeObj, canvas);
if (idx === 0) {
// 如果是背景图且已锁定,不应该显示图片控件
if (activeObj.get('lockMovementX') === true || activeObj.get('selectable') === false) {
canvas.discardActiveObject();
canvas.renderAll();
return;
}
}
//透明度
$('#pic_control').show()
$("#set_bg").show();
// 检查 pic_op 是否存在且有 setValue 方法
if (typeof pic_op !== 'undefined' && pic_op && typeof pic_op.setValue === 'function') {
pic_op.setValue(100 - activeObj.get('opacity') * 100);
} else {
$("#pic_op").next().children(".layui-slider-bar").css("width", (1 - activeObj.get("opacity")) * 100 + "%");
$("#pic_op").next().children(".layui-slider-handle").css("left", (1 - activeObj.get("opacity")) * 100 + "%");
}
// $("#pic_black").prop("checked", objs[idx-1].black ? 'checked' : '');
$('#out_pic_control').hide()
$('#text_control').hide()
$("#circle_text_control").hide();
$('#out_text_control').hide()
$('#rect_control').hide()
$('#circle_control').hide()
$('#line_control').hide()
$('#counter_control').hide()
$('#qrcode_Controll').hide()
$('#barcode_controll').hide()
}
function addOutPic(pointer) {
fabric.Image.fromURL('./public/images/outpic_extra.png', function (image) {
let width = canvas.getWidth()
let height = canvas.getHeight()
image.left = pointer.x
image.top = pointer.y
image.opacity = 1
//image.on("selected",function(){//test well
image.setSrc(image.toDataURL(), function (image) {
canvas.add(image)
objs.push({ type: 2, name: resName('OUT_PIC_'), black: false })
canvas.renderAll()
if (typeof window.updateList === 'function') {
window.updateList();
}
recordState()
})
})
}
function selectOutPic(target, index) {
//字段名
$('#out_pic_control').show()
out_pic_op.setValue(100 - canvas.getActiveObject().get('opacity') * 100)
let idx = getIndex(canvas.getActiveObject())
$('#out_pic_field_name').val(objs[idx - 1].name)
// $("#out_pic_black").prop("checked", objs[idx-1].black ? 'checked' : '');
$('#pic_control').hide()
$("#set_bg").hide();
$('#text_control').hide()
$("#circle_text_control").hide();
$('#out_text_control').hide()
$('#rect_control').hide()
$('#circle_control').hide()
$('#line_control').hide()
$('#counter_control').hide()
$('#qrcode_Controll').hide()
$('#barcode_controll').hide()
}
function addText(pointer) {
let text = new fabric.IText('TEXT', {
//源:文本
left: pointer.x,
top: pointer.y,
fill: '#000000',
textBackgroundColor: '',
fontStyle: 'normal',
fontWeight: 'normal',
underline: false,
linethrough: false,
fontFamily: 'Arial'
})
text.setControlVisible('ml', false)
text.setControlVisible('mt', false)
text.setControlVisible('mr', false)
text.setControlVisible('mb', false)
canvas.add(text)
objs.push({ type: 3, black: false })
canvas.renderAll()
if (typeof window.updateList === 'function') {
window.updateList();
}
recordState()
}
function selectText() {
//console.log(canvas.getActiveObject().get("fontFamily"));
$('#text_control').show()
$('#text_color').val(canvas.getActiveObject().get('fill'))
$('#text_back_color').val(canvas.getActiveObject().get('textBackgroundColor') == '' ? '#ffffff' : canvas.getActiveObject().get('textBackgroundColor'))
let val = parseFloat(canvas.getActiveObject().get("fontSize")) * 72 / dpi
if (val % 0.5 !== 0) val = Math.round(val * 2) / 2
$("#text_size").val(val);
$('#text_text').val(canvas.getActiveObject().get('text'))
$('#text_font_family').val(canvas.getActiveObject().get('fontFamily'))
if (canvas.getActiveObject().get('underline') == true) {
$('#text_underline').addClass('ui-radio-acitve')
} else {
$('#text_underline').removeClass('ui-radio-acitve')
}
if (canvas.getActiveObject().get('fontWeight') == 'bold') {
$('#text_bold').addClass('ui-radio-acitve')
} else {
$('#text_bold').removeClass('ui-radio-acitve')
}
if (canvas.getActiveObject().get('fontStyle') == 'italic') {
$('#text_italics').addClass('ui-radio-acitve')
} else {
$('#text_italics').removeClass('ui-radio-acitve')
}
if (canvas.getActiveObject().get('linethrough') == true) {
$('#text_linethrough').addClass('ui-radio-acitve')
} else {
$('#text_linethrough').removeClass('ui-radio-acitve')
}
$('#pic_control').hide()
$("#set_bg").hide();
$('#out_pic_control').hide()
$("#circle_text_control").hide();
$('#out_text_control').hide()
$('#rect_control').hide()
$('#circle_control').hide()
$('#line_control').hide()
$('#counter_control').hide()
$('#qrcode_Controll').hide()
$('#barcode_controll').hide()
}
function getDisdance(x1, y1, x2, y2) {
var dx = Math.abs(x2 - x1); // 计算x轴上的距离差,并取绝对值
var dy = Math.abs(y2 - y1); // 计算y轴上的距离差,并取绝对值
var distance = Math.sqrt(dx * dx + dy * dy); // 应用勾股定理计算距离
return distance;
}
function getDeg(pointer) {
// 计算点击位置与画布中心的坐标差
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var mouseX = pointer.x;
var mouseY = pointer.y;
var dx = mouseX - centerX;
var dy = mouseY - centerY;
// 计算旋转角度(弧度)
var angleRad = Math.atan2(dy, dx);
// 将角度转换为度数
var angleDeg = angleRad * (180 / Math.PI);
if (angleDeg < 0) {
angleDeg += 360;
}
angleDeg += 90
return angleDeg
}
function addCircleText(pointer) {
let distance = getDisdance(pointer.x, pointer.y, canvas.width / 2, canvas.height / 2)
let angleDeg = getDeg(pointer)
let text = new fabric.CurvedText('Circle TEXT', {//源:圆形文本
left: pointer.x,
top: pointer.y,
fill: "#000000",
textBackgroundColor: "",
fontStyle: "normal",
fontWeight: "normal",
diameter: distance * 2,
fontSize: 30,
underline: false,
linethrough: false,
lockScalingX: true,
lockScalingY: true,
fontFamily: 'Arial',
originX: 'center',
originY: 'center',
angle: angleDeg,
flipped: pointer.y > canvas.height / 2 ? true : false
});
// distance = getDisdance(pointer.x+text.width/2, pointer.y, canvas.width/2,canvas.height/2)
text.setControlVisible("ml", false);
text.setControlVisible("mt", false);
text.setControlVisible("mr", false);
text.setControlVisible("mb", false);
canvas.add(text);
objs.push({ type: 11, black: false, circleCenter: 0 });
canvas.renderAll();
if (typeof window.updateList === 'function') {
window.updateList();
};
recordState();
}
function selectCircleText() {
let idx = getIndex(canvas.getActiveObject());
$("#circle_text_control").show();
$("#circle_text_color").val(canvas.getActiveObject().get("fill"));
$("#circle_text_back_color").val(canvas.getActiveObject().get("textBackgroundColor") == "" ? '#ffffff' : canvas.getActiveObject().get("textBackgroundColor"));
if (typeof circle_text_size_updating !== 'undefined') {
circle_text_size_updating = true;
}
circle_text_size.setValue(canvas.getActiveObject().get("fontSize"));
if (typeof circle_text_size_updating !== 'undefined') {
circle_text_size_updating = false;
}
circle_text_diameter.setValue(canvas.getActiveObject().get("diameter"));
$("#circle_text_center").prop("checked", objs[idx - 1].circleCenter ? 'checked' : '');
$("#circle_text_text").val(canvas.getActiveObject().get("text"));
$("#circle_text_font_family").val(canvas.getActiveObject().get("fontFamily"));
if (canvas.getActiveObject().get("underline") == true) {
$("#circle_text_underline").addClass("ui-radio-acitve")
} else {
$("#circle_text_underline").removeClass("ui-radio-acitve")
}
if (canvas.getActiveObject().get("fontWeight") == "bold") {
$("#circle_text_bold").addClass("ui-radio-acitve")
} else {
$("#circle_text_bold").removeClass("ui-radio-acitve")
}
if (canvas.getActiveObject().get("fontStyle") == "italic") {
$("#circle_text_italics").addClass("ui-radio-acitve")
} else {
$("#circle_text_italics").removeClass("ui-radio-acitve")
}
if (canvas.getActiveObject().get("linethrough") == true) {
$("#circle_text_linethrough").addClass("ui-radio-acitve")
} else {
$("#circle_text_linethrough").removeClass("ui-radio-acitve")
}
$("#pic_control").hide();
$("#set_bg").hide();
$("#rotate").hide();
$("#out_pic_control").hide();
$("#text_control").hide();
$("#out_text_control").hide();
$("#rect_control").hide();
$("#circle_control").hide();
$("#line_control").hide();
$("#counter_control").hide();
$("#qrcode_Controll").hide();
$("#barcode_controll").hide();
}
function addOutText(pointer) {
//MERGE_TEXT_1
let text = new fabric.Text('MERGE TEXT', {
//源:合成文本
left: pointer.x,
top: pointer.y,
fill: '#000000',
fontStyle: 'normal',
fontWeight: 'normal',
textBackgroundColor: '',
underline: false,
linethrough: false,
fontFamily: 'Arial',
textAlign: 'center'
})
//text.on({
text.setControlVisible('ml', false)
text.setControlVisible('mt', false)
text.setControlVisible('mr', false)
text.setControlVisible('mb', false)
canvas.add(text)
objs.push({ type: 4, name: resName('OUT_TEXT_'), exceed: false, autoWrap: false, fixSize: false, black: false, align: 'center' })
canvas.renderAll()
if (typeof window.updateList === 'function') {
window.updateList();
}
recordState()
}
function selectOutText() {
//color
const align = canvas.getActiveObject().get('textAlign')
if (align === 'left') {
$('#out_left_alignment').parent().addClass('tool1')
} else if (align === 'right') {
$('#out_right_alignment').parent().addClass('tool1')
} else {
$('#out_center_alignment').parent().addClass('tool1')
}
$('#out_text_control').show()
$('#out_text_color').val(canvas.getActiveObject().get('fill'))
$('#out_text_text').val(canvas.getActiveObject().get('text'))
let val = parseFloat(canvas.getActiveObject().get("fontSize")) * 72 / dpi
if (val % 0.5 !== 0) val = Math.round(val * 2) / 2
$("#out_text_size").val(val);
$('#out_text_back_color').val(canvas.getActiveObject().get('textBackgroundColor') == '' ? '#ffffff' : canvas.getActiveObject().get('textBackgroundColor'))
let idx = getIndex(canvas.getActiveObject())
$('#out_text_field_name').val(objs[idx - 1].name)
$('#out_text_font_family').val(canvas.getActiveObject().get('fontFamily'))
$('#exceed').prop('checked', objs[idx - 1].exceed ? 'checked' : '')
$('#autoWrap').prop('checked', objs[idx - 1].autoWrap ? 'checked' : '')
$('#fixSize').prop('checked', objs[idx - 1].fixSize ? 'checked' : '')
if (canvas.getActiveObject().get('underline') == true) {
$('#out_text_underline').addClass('ui-radio-acitve')
} else {
$('#out_text_underline').removeClass('ui-radio-acitve')
}
if (canvas.getActiveObject().get('fontWeight') == 'bold') {
$('#out_text_bold').addClass('ui-radio-acitve')
} else {
$('#out_text_bold').removeClass('ui-radio-acitve')
}
if (canvas.getActiveObject().get('fontStyle') == 'italic') {
$('#out_text_italics').addClass('ui-radio-acitve')
} else {
$('#out_text_italics').removeClass('ui-radio-acitve')
}
if (canvas.getActiveObject().get('linethrough') == true) {
$('#out_text_linethrough').addClass('ui-radio-acitve')
} else {
$('#out_text_linethrough').removeClass('ui-radio-acitve')
}
$('#pic_control').hide()
$("#set_bg").hide();
$('#out_pic_control').hide()
$('#text_control').hide()
$("#circle_text_control").hide();
$('#rect_control').hide()
$('#circle_control').hide()
$('#line_control').hide()
$('#counter_control').hide()
$('#qrcode_Controll').hide()
$('#barcode_controll').hide()
}
function addRect(pointer) {
let rect = new fabric.Rect({
left: pointer.x,
top: pointer.y,
fill: '',
stroke: "#ff0000",
strokeWidth: 3,
width: 100,
height: 100
})
canvas.add(rect)
objs.push({ type: 5, black: false })
canvas.renderAll()
if (typeof window.updateList === 'function') {
window.updateList();
}
recordState()
}
function selectRect() {
//color
$('#rect_control').show()
$('#rect_color').val(canvas.getActiveObject().get('fill') == '' ? '#ffffff' : canvas.getActiveObject().get('fill'))
$('#rect_stroke').val(canvas.getActiveObject().get('stroke') == '' ? '#ffffff' : canvas.getActiveObject().get('stroke'))
$('#rect_stroke_width').val(canvas.getActiveObject().get('strokeWidth'))
$('#rect_radius').val(canvas.getActiveObject().get('rx'))
rect_op.setValue(100 - canvas.getActiveObject().get('opacity') * 100)
let a = canvas.getActiveObject().getCoords()
$('#pic_control').hide()
$("#set_bg").hide();
$('#out_pic_control').hide()
$('#text_control').hide()
$("#circle_text_control").hide();
$('#out_text_control').hide()
$('#circle_control').hide()
$('#line_control').hide()
$('#counter_control').hide()
$('#qrcode_Controll').hide()
$('#barcode_controll').hide()
}
function addCircle(pointer) {
let circle = new fabric.Circle({
left: pointer.x,
top: pointer.y,
fill: '',
stroke: '#ff0000',
strokeWidth: 3,
radius: 100,
strokeUniform: true
})
canvas.add(circle)
objs.push({ type: 6, black: false })
canvas.renderAll()
if (typeof window.updateList === 'function') {
window.updateList();
}
recordState()
}
function selectCircle() {
//border-color
$('#circle_control').show()
$('#circle_color').val(canvas.getActiveObject().get('fill') == '' ? '#ffffff' : canvas.getActiveObject().get('fill'))
$('#circle_stroke').val(canvas.getActiveObject().get('stroke') == '' ? '#ffffff' : canvas.getActiveObject().get('stroke'))
$('#circle_stroke_width').val(canvas.getActiveObject().get('strokeWidth'))
circle_op.setValue(100 - canvas.getActiveObject().get('opacity') * 100)
$('#pic_control').hide()
$("#set_bg").hide();
$('#out_pic_control').hide()
$('#text_control').hide()
$("#circle_text_control").hide();
$('#out_text_control').hide()
$('#rect_control').hide()
$('#line_control').hide()
$('#counter_control').hide()
$('#qrcode_Controll').hide()
$('#barcode_controll').hide()
}
function addLine(pointer) {
let line = new fabric.Line([50, 100, 200, 100], {
left: pointer.x,
top: pointer.y,
stroke: '#ff0000',
strokeWidth: 3,
strokeDashArray: [0, 0],
})
line.setControlVisible('tl', false)
line.setControlVisible('tr', false)
line.setControlVisible('br', false)
line.setControlVisible('bl', false)
line.setControlVisible('mt', false)
line.setControlVisible('mb', false)
canvas.add(line)
objs.push({ type: 7, black: false })
canvas.renderAll()
if (typeof window.updateList === 'function') {
window.updateList();
}
recordState()
}
function selectLine() {
//color
$('#line_control').show()
let idx = getIndex(canvas.getActiveObject())
$('#line_color').val(canvas.getActiveObject().get('stroke'))
$('#line_dist').val(canvas.getActiveObject().get('strokeDashArray')[0])
$('#text_h').val(canvas.getActiveObject().get('strokeWidth'))
$('#pic_control').hide()
$("#set_bg").hide();
$('#out_pic_control').hide()
$('#text_control').hide()
$("#circle_text_control").hide();
$('#out_text_control').hide()
$('#rect_control').hide()
$('#circle_control').hide()
$('#counter_control').hide()
$('#qrcode_Controll').hide()
$('#barcode_controll').hide()
}
function addQrCode(pointer) {
let qr = jrQrcode.getQrBase64('https://www.cardsoon.com', { padding: 0 })
fabric.Image.fromURL(qr, function (image) {
image.left = pointer.x
image.top = pointer.y
canvas.add(image)
objs.push({ type: 8, name: resName('QR_CODE_'), color: '#000000', val: 'http://www.cardsoon.com', black: false })
canvas.renderAll()
if (typeof window.updateList === 'function') {
window.updateList();
}
recordState()
})
}
function selectQrCode() {
//字段名
$('#qrcode_Controll').show()
let idx = getIndex(canvas.getActiveObject())
$('#qrcode_field_name').val(objs[idx - 1].name)
$('#qrcode_color').val(objs[idx - 1].color)
$('#qrcode_val').val(objs[idx - 1].val)
$('#line_control').hide()
$('#pic_control').hide()
$('#out_pic_control').hide()
$('#text_control').hide()
$("#circle_text_control").hide();
$('#out_text_control').hide()
$('#rect_control').hide()
$('#circle_control').hide()
$('#counter_control').hide()
$('#barcode_controll').hide()
}
function addBarCode(pointer) {
JsBarcode('#barcode', '123456789', { margin: 0, lineColor: '#000000', fontSize: 18, font: 'Arial' })
let barcode = document.getElementById('barcode')
let bar = barcode.toDataURL('image/png')
fabric.Image.fromURL(bar, function (image) {
image.left = pointer.x
image.top = pointer.y
canvas.add(image)
objs.push({ type: 9, name: resName('BAR_CODE_'), val: '123456789', color: '#000000', fontSize: 18, font: 'Arial', show: false, black: false }) //show是取消文字显示
canvas.renderAll()
if (typeof window.updateList === 'function') {
window.updateList();
}
recordState()
})
}
function selectBarCode() {
//字段名
$('#barcode_controll').show()
let idx = getIndex(canvas.getActiveObject())
$('#barcode_field_name').val(objs[idx - 1].name)
$('#barcode_font_family').val(objs[idx - 1].font)
let val = parseFloat(objs[idx - 1].fontSize) * 72 / dpi
if (val % 0.5 !== 0) val = Math.round(val * 2) / 2
$("#barcode_size").val(val);
$('#barcode_val').val(objs[idx - 1].val)
$('#barcode_show').prop('checked', objs[idx - 1].show ? 'checked' : '')
$('#line_control').hide()
$('#pic_control').hide()
$('#out_pic_control').hide()
$('#text_control').hide()
$("#circle_text_control").hide();
$('#out_text_control').hide()
$('#rect_control').hide()
$('#circle_control').hide()
$('#counter_control').hide()
$('#qrcode_Controll').hide()
}
function addCounter(pointer) {
let text = new fabric.Text('0', {
left: pointer.x,
top: pointer.y,
fill: '#000000'
})
canvas.add(text)
objs.push({ type: 10, name: resName('COUNTER_'), start: 0, add: 1, black: false })
canvas.renderAll()
if (typeof window.updateList === 'function') {
window.updateList();
}
recordState()
}
function selectCounter() {
//起始
$('#counter_control').show()
let idx = getIndex(canvas.getActiveObject())
$('#counter_start').val(objs[idx - 1].start)
$('#counter_add').val(objs[idx - 1].add)
$('#counter_color').val(canvas.getActiveObject().get('fill'))
$('#count_font_family').val(canvas.getActiveObject().get('fontFamily'))
let val = parseFloat(canvas.getActiveObject().get("fontSize")) * 72 / dpi
if (val % 0.5 !== 0) val = Math.round(val * 2) / 2
$("#count_size").val(val);
$('#line_control').hide()
$('#pic_control').hide()
$('#out_pic_control').hide()
$('#text_control').hide()
$("#circle_text_control").hide();
$('#out_text_control').hide()
$('#rect_control').hide()
$('#circle_control').hide()
$('#qrcode_Controll').hide()
$('#barcode_controll').hide()
}
function getIndex(target, _canvas = null) {
let temp_objs
if (_canvas == null) {
temp_objs = canvas.getObjects()
} else {
temp_objs = _canvas.getObjects()
}
let i = 0
for (let res of temp_objs) {
if (target == res) {
return i
}
i++
}
return 0
}
function getType(target) {
let temp_objs = canvas.getObjects()
let i = 0
for (let res of temp_objs) {
if (target == res) {
return objs[i].type
}
i++
}
}
// updateList 和 selectObj 函数在 core.js 中定义并附加到 window 对象
function recordState() {
//pre_objs.push(JSON.stringify(objs));
++step.val
for (let i = step.val; i < recordObjs.length; i++) {
recordObjs.pop()
recordJson.pop()
}
//recordObjs.splice(step.val, 1, JSON.stringify(objs))
recordObjs.push(JSON.stringify(objs))
j = canvas.toJSON(['selectable', 'hoverable', 'hoverCursor', 'text', 'fontStyle', 'fontWeight', 'underline'])
j.objects[0].hoverCursor = 'default'
recordJson.push(j)
}
function getCoordsMinX(acoords) {
x = acoords[0].x
for (let item of acoords) {
if (item.x < x) {
x = item.x
}
}
return x
}
function getCoordsMaxX(acoords) {
x = acoords[0].x
for (let item of acoords) {
if (item.x > x) {
x = item.x
}
}
return x
}
function getCoordsMinY(acoords) {
y = acoords[0].y
for (let item of acoords) {
if (item.y < y) {
y = item.y
}
}
return y
}
function getCoordsMaxY(acoords) {
y = acoords[0].y
for (let item of acoords) {
if (item.y > y) {
y = item.y
}
}
return y
}
$('#text_y').bind('input propertychange', function () {
if ($('#text_y').val() == '') {
$('#text_y').val(0)
}
let val = background_image.top
if ($('#text_y').val() != '') {
val = background_image.top + parseInt($('#text_y').val())
}
canvas.getActiveObject().set('top', val)
canvas.renderAll()
recordState()
})
$('#text_x').bind('input propertychange', function () {
if ($('#text_x').val() == '') {
$('#text_x').val(0)
}
let val = background_image.left
if ($('#text_x').val() != '') {
val = background_image.left + parseInt($('#text_x').val())
}
canvas.getActiveObject().set('left', val)
canvas.renderAll()
recordState()
})
$('#text_w').bind('input propertychange', function () {
let val = '0'
if ($('#text_w').val() != '') {
val = $('#text_w').val()
}
let type = objs[getIndex(canvas.getActiveObject()) - 1].type
if (type == 3 || type == 4) {
canvas.getActiveObject().set('width', parseInt(val))
} else {
canvas.getActiveObject().set('scaleX', parseInt(val) / canvas.getActiveObject().get('width'))
}
canvas.renderAll()
recordState()
})
$('#text_h').bind('input propertychange', function () {
let idx = getIndex(canvas.getActiveObject())
if (objs[idx - 1].type == 7) {
if ($('#text_h').val() == '') {
$('#text_h').val(canvas.getActiveObject().get('strokeWidth'))
}
canvas.getActiveObject().set('strokeWidth', parseInt($('#text_h').val()))
canvas.renderAll()
return
}
let val = '0'
if ($('#text_h').val() != '') {
val = $('#text_h').val()
}
let type = objs[getIndex(canvas.getActiveObject()) - 1].type
if (type == 3 || type == 4) {
canvas.getActiveObject().set('height', parseInt(val))
} else {
canvas.getActiveObject().set('scaleY', parseInt(val) / canvas.getActiveObject().get('height'))
}
canvas.renderAll()
recordState()
})
$('#text_r').bind('input propertychange', function () {
if ($('#text_r').val() == '') {
$('#text_r').val('0')
}
$('#text_r').val(parseInt($('#text_r').val()) % 360)
//canvas.getActiveObject().set("rotate", val)
canvas.getActiveObject().rotate(parseInt($('#text_r').val()))
canvas.renderAll()
recordState()
})
$('#out_pic_field_name').bind('input propertychange', function () {
let idx = getIndex(canvas.getActiveObject())
objs[idx - 1].name = $('#out_pic_field_name').val()
if (typeof window.updateList === 'function') {
window.updateList();
}
recordState()
})
$('#text_black').click(function () {
let idx = getIndex(canvas.getActiveObject())
if ($(this).prop('checked')) {
objs[idx - 1].black = true
} else {
objs[idx - 1].black = false
}
recordState()
})
// $("#out_pic_black").click(function () {
$('#out_text_field_name').bind('input propertychange', function () {
let idx = getIndex(canvas.getActiveObject())
objs[idx - 1].name = $('#out_text_field_name').val()
if (typeof window.updateList === 'function') {
window.updateList();
}
recordState()
})
$('#qrcode_field_name').bind('input propertychange', function () {
let idx = getIndex(canvas.getActiveObject())
objs[idx - 1].name = $('#qrcode_field_name').val()
if (typeof window.updateList === 'function') {
window.updateList();
}
recordState()
})
$('#qrcode_color').bind('input propertychange', function () {
let item = canvas.getActiveObject()
let qr = jrQrcode.getQrBase64('https://www.cardsoon.com', { padding: 0, foreground: $(this).val() })
let idx = getIndex(item)
objs[idx - 1].color = $(this).val()
item.setSrc(qr, function (img) {
canvas.renderAll()
recordState()
})
})
$("#qrcode_val").bind('change', function () {
let val = $(this).val() ? $(this).val() : 'https://www.cardsoon.com'
let item = canvas.getActiveObject();
let qr = jrQrcode.getQrBase64(val, { padding: 0, foreground: $("#qrcode_color").val() });
let idx = getIndex(item);
objs[idx - 1].val = val;
item.setSrc(qr, function (img) {
canvas.renderAll();
recordState();
});
});
$('#barcode_color').bind('input propertychange', function () {
let item = canvas.getActiveObject()
let idx = getIndex(item)
objs[idx - 1].color = $(this).val()
JsBarcode('#barcode', objs[idx - 1].val, { margin: 0, lineColor: objs[idx - 1].color, fontSize: objs[idx - 1].fontSize, font: objs[idx - 1].font })
let barcode = document.getElementById('barcode')
let bar = barcode.toDataURL('image/png')
item.setSrc(bar, function (img) {
canvas.renderAll()
recordState()
})
})
$('#barcode_field_name').bind('input propertychange', function () {
let idx = getIndex(canvas.getActiveObject())
objs[idx - 1].name = $('#barcode_field_name').val()
if (typeof window.updateList === 'function') {
window.updateList();
}
recordState()
})
$('#text_color').bind('input propertychange', function () {
canvas.getActiveObject().set('fill', $('#text_color').val())
canvas.renderAll()
recordState()
})
$('#text_back_color').bind('input propertychange', function () {
canvas.getActiveObject().set('textBackgroundColor', $('#text_back_color').val())
canvas.renderAll()
recordState()
})
$('#out_text_back_color').bind('input propertychange', function () {
canvas.getActiveObject().set('textBackgroundColor', $('#out_text_back_color').val())
canvas.renderAll()
recordState()
})
$("#text_size").bind('input propertychange', function () {
let val = 1
if (parseFloat($("#text_size").val())) {
val = parseFloat($("#text_size").val())
if (val < 1) {
val = 1
} else if (val > dpi) {
val = dpi
} else if (val % 0.5 !== 0) {
val = Math.round(val * 2) / 2
}
}
$("#text_size").val(val)
canvas.getActiveObject().set("fontSize", val * dpi / 72);
$("#text_h").val((canvas.getActiveObject().get("height")).toFixed(0));
$("#text_w").val((canvas.getActiveObject().get("width")).toFixed(0));
canvas.renderAll();
recordState();
})
$("#circle_text_color").bind('input propertychange', function () {
canvas.getActiveObject().set("fill", $("#circle_text_color").val());
canvas.renderAll();
recordState();
})
$("#circle_text_back_color").bind('input propertychange', function () {
canvas.getActiveObject().set("textBackgroundColor", $("#circle_text_back_color").val());
canvas.renderAll();
recordState();
})
$("#circle_text_text").bind('input propertychange', function () {
let val = $("#circle_text_text").val().trim()
canvas.getActiveObject().set("text", ` ${val} `);
canvas.renderAll();
if (typeof window.updateList === 'function') {
window.updateList();
};
recordState();
})
$("#circle_text_center").click(function () {
let idx = getIndex(canvas.getActiveObject());
if ($(this).prop("checked")) {
objs[idx - 1].circleCenter = 1;
} else {
objs[idx - 1].circleCenter = 0;
}
recordState();
});
$('#out_text_color').bind('input propertychange', function () {
canvas.getActiveObject().set('fill', $('#out_text_color').val())
canvas.renderAll()
recordState()
})
$("#out_text_size").bind('input propertychange', function () {
let val = 1
if (parseFloat($("#out_text_size").val())) {
val = parseFloat($("#out_text_size").val())
if (val < 1) {
val = 1
} else if (val > dpi) {
val = dpi
} else if (val % 0.5 !== 0) {
val = Math.round(val * 2) / 2
}
}
$("#out_text_size").val(val)
canvas.getActiveObject().set("fontSize", val * dpi / 72);
$("#text_h").val((canvas.getActiveObject().get("height")).toFixed(0));
$("#text_w").val((canvas.getActiveObject().get("width")).toFixed(0));
canvas.renderAll();
recordState();
})
$('#out_text_text').bind('input propertychange', function () {
let val = $("#out_text_text").val().trim()
canvas.getActiveObject().set("text", ` ${val} `);
canvas.renderAll()
if (typeof window.updateList === 'function') {
window.updateList();
}
recordState()
})
$('#rect_color').bind('input propertychange', function () {
canvas.getActiveObject().set('fill', $('#rect_color').val())
canvas.renderAll()
recordState()
})
$('#rect_stroke').bind('input propertychange', function () {
canvas.getActiveObject().set('stroke', $('#rect_stroke').val())
canvas.renderAll()
recordState()
})
$('#rect_stroke_width').bind('input propertychange', function () {
if ($('#rect_stroke_width').val() == '') {
$('#rect_stroke_width').val('0')
} else {
$('#rect_stroke_width').val(parseInt($('#rect_stroke_width').val()))
}
canvas.getActiveObject().set('strokeWidth', parseInt($('#rect_stroke_width').val()))
canvas.renderAll()
recordState()
})
$('#rect_radius').bind('input propertychange', function () {
if ($('#rect_radius').val() == '') {
$('#rect_radius').val('0')
} else {
$('#rect_radius').val(parseInt($('#rect_radius').val()))
}
canvas.getActiveObject().set('rx', parseInt($('#rect_radius').val()))
canvas.getActiveObject().set('ry', parseInt($('#rect_radius').val()))
canvas.renderAll()
recordState()
})
$('#circle_color').bind('input propertychange', function () {
canvas.getActiveObject().set('fill', $('#circle_color').val())
canvas.renderAll()
recordState()
})
$('#circle_stroke').bind('input propertychange', function () {
canvas.getActiveObject().set('stroke', $('#circle_stroke').val())
canvas.renderAll()
recordState()
})
$('#circle_stroke_width').bind('input propertychange', function () {
if ($('#circle_stroke_width').val() == '') {
$('#circle_stroke_width').val('0')
} else {
$(this).val(parseInt($(this).val()))
}
canvas.getActiveObject().set('strokeWidth', parseInt($('#circle_stroke_width').val()))
canvas.renderAll()
recordState()
})
$('#counter_start').bind('input propertychange', function () {
canvas.getActiveObject().set('text', $('#counter_start').val())
let item = canvas.getActiveObject()
let idx = getIndex(item)
objs[idx - 1].start = $(this).val()
canvas.renderAll()
recordState()
})
$('#counter_add').bind('input propertychange', function () {
let item = canvas.getActiveObject()
let idx = getIndex(item)
objs[idx - 1].add = $(this).val()
canvas.renderAll()
recordState()
})
$('#counter_color').bind('input propertychange', function () {
canvas.getActiveObject().set('fill', $('#counter_color').val())
canvas.renderAll()
recordState()
})
$("#count_size").bind('input propertychange', function () {
let val = 1
if (parseFloat($("#count_size").val())) {
val = parseFloat($("#count_size").val())
if (val < 1) {
val = 1
} else if (val > dpi) {
val = dpi
} else if (val % 0.5 !== 0) {
val = Math.round(val * 2) / 2
}
}
$("#count_size").val(val)
canvas.getActiveObject().set("fontSize", val * dpi / 72);
$("#text_h").val((canvas.getActiveObject().get("height")).toFixed(0));
$("#text_w").val((canvas.getActiveObject().get("width")).toFixed(0));
canvas.renderAll();
recordState();
})
$('#line_color').bind('input propertychange', function () {
canvas.getActiveObject().set('stroke', $('#line_color').val())
canvas.renderAll()
recordState()
})
$('#line_dist').bind('input propertychange', function () {
if ($('#line_dist').val() == '') {
$('#line_dist').val(0)
}
canvas.getActiveObject().set('strokeDashArray', [parseInt($('#line_dist').val()), parseInt($('#line_dist').val())])
canvas.renderAll()
recordState()
})
$('#text_text').bind('input propertychange', function () {
let val = $("#text_text").val().trim()
canvas.getActiveObject().set("text", ` ${val} `);
canvas.renderAll()
if (typeof window.updateList === 'function') {
window.updateList();
}
recordState()
})
$('#barcode_val').bind('input propertychange', function () {
let item = canvas.getActiveObject()
let idx = getIndex(item)
objs[idx - 1].val = $(this).val()
JsBarcode('#barcode', objs[idx - 1].val, { margin: 0, lineColor: objs[idx - 1].color, fontSize: objs[idx - 1].fontSize, font: objs[idx - 1].font })
let barcode = document.getElementById('barcode')
let bar = barcode.toDataURL('image/png')
item.setSrc(bar, function (img) {
canvas.renderAll()
recordState()
})
})
$("#barcode_show").click(function () {
let item = canvas.getActiveObject();
let idx = getIndex(canvas.getActiveObject());
let val = $("#barcode_size").val()
if ($(this).prop("checked")) {
objs[idx - 1].show = true;
val = 0
} else {
objs[idx - 1].show = false;
}
JsBarcode("#barcode", objs[idx - 1].val, { margin: 0, lineColor: objs[idx - 1].color, fontSize: val * dpi / 72, font: objs[idx - 1].font });
let barcode = document.getElementById('barcode');
let bar = barcode.toDataURL("image/png");
item.setSrc(bar, function (img) {
canvas.renderAll();
recordState();
});
});
$("#barcode_size").bind('input propertychange', function () {
let item = canvas.getActiveObject();
let idx = getIndex(item);
let val = 1
if (parseFloat($(this).val())) {
val = parseFloat($(this).val())
if (val < 1) {
val = 1
} else if (val > dpi) {
val = dpi
} else if (val % 0.5 !== 0) {
val = Math.round(val * 2) / 2
}
}
$("#barcode_size").val(val)
objs[idx - 1].fontSize = val * dpi / 72;
JsBarcode("#barcode", objs[idx - 1].val, { margin: 0, lineColor: objs[idx - 1].color, fontSize: objs[idx - 1].fontSize, font: objs[idx - 1].font });
let barcode = document.getElementById('barcode');
let bar = barcode.toDataURL("image/png");
item.setSrc(bar, function (img) {
canvas.renderAll();
recordState();
});
})
$('#count_font_family').on('change', function () {
canvas.getActiveObject().set('fontFamily', $(this).find('option:selected').text())
canvas.renderAll()
recordState()
})
$('#text_font_family').on('change', function () {
canvas.getActiveObject().set('fontFamily', $(this).find('option:selected').text())
canvas.renderAll()
recordState()
})
$('#circle_text_font_family').on('change', function () {
canvas.getActiveObject().set("fontFamily", $(this).find('option:selected').text())
canvas.renderAll()
recordState();
});
$('#language_select').on('change', function () {
//语言选择
langua_ge($(this).find('option:selected').val())
s_lan = $(this).find('option:selected').val()
localStorage.setItem('lang', s_lan)
})
$('#barcode_font_family').on('change', function () {
let item = canvas.getActiveObject()
let idx = getIndex(item)
objs[idx - 1].font = $(this).find('option:selected').text()
JsBarcode('#barcode', objs[idx - 1].val, { margin: 0, lineColor: objs[idx - 1].color, fontSize: objs[idx - 1].fontSize, font: objs[idx - 1].font })
let barcode = document.getElementById('barcode')
let bar = barcode.toDataURL('image/png')
item.setSrc(bar, function (img) {
canvas.renderAll()
recordState()
})
//recordState();
})
$('#out_text_font_family').on('change', function () {
canvas.getActiveObject().set('fontFamily', $(this).find('option:selected').text())
canvas.renderAll()
recordState()
})
$('.obj_list').on('click', 'div', function () {
let idx = objs.length - 1 - $(this).index()
selectObj(idx)
})
$('#exceed').click(function () {
let idx = getIndex(canvas.getActiveObject())
if ($(this).prop('checked')) {
objs[idx - 1].exceed = true
} else {
objs[idx - 1].exceed = false
}
recordState()
})
$('#autoWrap').click(function () {
let idx = getIndex(canvas.getActiveObject())
if ($(this).prop('checked')) {
objs[idx - 1].autoWrap = true
} else {
objs[idx - 1].autoWrap = false
}
recordState()
})
$('#fixSize').click(function () {
let idx = getIndex(canvas.getActiveObject())
if ($(this).prop('checked')) {
objs[idx - 1].fixSize = true
} else {
objs[idx - 1].fixSize = false
}
recordState()
})
$('#delete').click(function () {
let actObjs = canvas.getActiveObjects()
let allObjs = canvas.getObjects()
let flag = 0
for (let item of actObjs) {
if (item != allObjs[0]) {
let i = getIndex(item) //0是背景,所以从1开始,但objs不包含背景图片,故要-1
objs.splice(i - 1, 1)
canvas.remove(item)
flag = 1
}
}
if (typeof window.updateList === 'function') {
window.updateList();
}
canvas.discardActiveObject()
if (flag == 1) {
recordState()
canvas.renderAll()
}
// let actObjs = canvas.getActiveObjects();
})
//在关于我们获取版本号。
$("#about").click(async function () {
// 1. 先异步获取版本号
let version = "0.0.0"; // 默认值,防止获取失败
try {
if (window.sysAPI && window.sysAPI.getAppVersion) {
const v = await window.sysAPI.getAppVersion();
version = "v" + v; // 拼接一个 v,变成 v2.3.017
}
} catch (e) {
console.error("获取版本号失败", e);
}
// 2. 获取成功后再弹出窗口
layer.open({
type: 1
, title: language_str("about")
, area: '450px;'
, id: 'LAY_layuipro'
, moveType: 1
, content: '<div style="padding-top:20px;padding-bottom:30px;background-color: #32363A; color: #fff; font-weight: 300;text-align:center;">' +
'<div style="width: 120px;margin: 0 auto;"><img style="width: 120px;" src="./public/images/IconA.png"></div>' +
'<div style="font-size:24px;">Soon Design</div>' +
// 【修改点】这里使用了刚才获取到的 version 变量
'<div style="font-size:14px;">' + language_str("vers") + ' ' + version + '</div>' +
'<div style="font-size:14px;">' + language_str("copyright") + '</div>' +
'</div>'
});
})
$("#help").click(() => {
ipcRenderer.send('open-help-file');
});
// ===========================================================
$('#display').off('click').on('click', function () {
// 类型改变
fabric.Image.fromURL('./public/images/front_bg' + bg_version + '_2.png', function (i1) {
i1.left = background_image.left
i1.top = background_image.top
let img1 = i1
fabric.Image.fromURL('./public/images/back_bg_2.png', function (i2) {
i2.left = background_image.left
i2.top = background_image.top
let img2 = i2
fabric.Image.fromURL('./public/images/op_2.png', function (i3) {
i2.left = background_image.left
i2.top = background_image.top
let img3 = i3
if (typeof window.display_func === 'function') {
window.display_func(img1, img2, img3);
}
})
})
})
});
$("#output").click(function () {
// 另存为:传递 saveAs 函数作为第二个参数
if (typeof window.output === 'function') {
window.output(null, saveAs); // 调用output函数,使用saveAs进行另存为
}
});
function handleObjectSelected() {
let select_obj = canvas.getActiveObject()
if (!select_obj) {
$('#base_control').hide()
$('#line_control').hide()
$('#pic_control').hide()
$('#out_pic_control').hide()
$('#text_control').hide()
$("#circle_text_control").hide();
$('#out_text_control').hide()
$('#rect_control').hide()
$('#circle_control').hide()
$('#counter_control').hide()
$('#qrcode_Controll').hide()
$('#barcode_controll').hide()
$('#component_type').text(language_str('bg')) //comfirm
return
}
// 如果是辅助线,直接返回,不处理
if (select_obj.isGuideLine) {
return
}
let i = getIndex(select_obj)
if (i != 0) {
//不是背景
--i
// 安全检查:确保 objs[i] 存在且有 type 属性
if (!objs[i] || typeof objs[i].type === 'undefined') {
return
}
switch (objs[i].type) {
case 1:
//console.log("图片");
$('#component_type').text(language_str('img')) //"图片"
selectObject(select_obj, i)
selectPic(select_obj, i)
break
case 2:
//console.log("预留图片");
$('#component_type').text(language_str('simg')) //"合成图片"
selectObject(select_obj, i)
selectOutPic(select_obj, i)
break
case 3:
$('#component_type').text(language_str('text')) //"文字"
//console.log("文字");
selectObject(select_obj, i)
selectText(select_obj, i)
break
case 4:
//console.log("标签");
$('#component_type').text(language_str('stext')) //"合成文字"
selectObject(select_obj, i)
selectOutText(select_obj, i)
break
case 5:
//console.log("矩形");
$('#component_type').text(language_str('rect')) //"矩形"
selectObject(select_obj, i)
selectRect(select_obj, i)
break
case 6:
//console.log("圆形");
$('#component_type').text(language_str('circ')) //"圆形"
selectObject(select_obj, i)
selectCircle(select_obj, i)
break
case 7:
//console.log("直线");
$('#component_type').text(language_str('line')) //"直线"
selectObject(select_obj, i)
selectLine(select_obj, i)
break
case 8:
//console.log("二维码");
$('#component_type').text(language_str('qrc')) //"二维码"
selectObject(select_obj, i)
selectQrCode(select_obj, i)
break
case 9:
//console.log("条形码");
$('#component_type').text(language_str('barc')) //"条形码"
selectObject(select_obj, i)
selectBarCode(select_obj, i)
break
case 10:
//console.log("计数器");
$('#component_type').text(language_str('counter')) //"计数器"
selectObject(select_obj, i)
selectCounter(select_obj, i)
break
case 11:
$("#component_type").text(language_str("ctext"));//"圆形文字"
//console.log("圆形文字");
selectObject(select_obj, i);
selectCircleText(select_obj, i);
break;
}
} else {
//背景,收起对象属性
$('#base_control').hide()
$('#line_control').hide()
$('#pic_control').hide()
$('#out_pic_control').hide()
$('#text_control').hide()
$("#circle_text_control").hide();
$('#out_text_control').hide()
$('#rect_control').hide()
$('#circle_control').hide()
$('#counter_control').hide()
$('#qrcode_Controll').hide()
$('#barcode_controll').hide()
$('#component_type').text(language_str('bg'))
}
}
// 防止重复初始化事件监听器
if (typeof window._design2CanvasEventsInitialized === 'undefined') {
window._design2CanvasEventsInitialized = true;
canvas1.on('mouse:move', (e) => {
if (!e.pointer || typeof background_image === 'undefined' || !background_image) return;
let width = canvas.getWidth()
let height = canvas.getHeight()
$('#posText').text(
'X: ' + (e.pointer.x - (width / 2 - (width / 2 - background_image.left) * zoom)).toFixed(0) + ' Y: ' + (e.pointer.y - (height / 2 - (height / 2 - background_image.top) * zoom)).toFixed(0)
)
})
canvas1.on("object:moving", function (e) {
let obj = canvas1.getActiveObject()
let idx = getIndex(e.target, canvas1);
// 添加边界检查,避免访问 undefined
if (idx > 0 && idx <= objs1.length && objs1[idx - 1] && objs1[idx - 1].type && objs1[idx - 1].type === 11 && $("#circle_text_center").prop("checked")) {
let pointer = {
x: obj.left,
y: obj.top
}
let distance = getDisdance(pointer.x, pointer.y, canvas1.width / 2, canvas1.height / 2)
let angleDeg = getDeg(pointer)
let flipped = pointer.y > canvas1.height / 2 ? true : false
if (typeof circle_text_diameter !== 'undefined' && circle_text_diameter.setValue) {
circle_text_diameter.setValue(distance * 2 - 50);
}
obj.set("diameter", distance * 2);
obj.set("angle", angleDeg);
obj.set("flipped", flipped);
}
updateControls();
});
canvas1.on('object:scaling', function (event) {
updateControls();
})
canvas1.on('object:rotating', function (e) {
updateControls()
})
canvas1.on('object:rotated', function (e) {
recordState()
})
canvas1.on('object:added', function (e) {
//recordState();
})
canvas1.on('mouse:down', (e) => {
//单选
canvas = canvas1;
objs = objs1;
let select_obj = canvas.getActiveObject()
// 如果是辅助线,直接返回,不处理
if (select_obj && select_obj.isGuideLine) {
return
}
let i = getIndex(select_obj, canvas)
if (i != 0) {
//不是背景
--i
// 安全检查:确保 objs[i] 存在且有 type 属性
if (!objs[i] || typeof objs[i].type === 'undefined') {
return
}
switch (objs[i].type) {
case 1:
$('#component_type').text(language_str('img'))
selectObject(select_obj, i)
selectPic(select_obj, i)
break
case 2:
$('#component_type').text(language_str('simg'))
selectObject(select_obj, i)
selectOutPic(select_obj, i)
break
case 3:
$('#component_type').text(language_str('text'))
selectObject(select_obj, i)
selectText(select_obj, i)
break
case 4:
$('#component_type').text(language_str('stext'))
selectObject(select_obj, i)
selectOutText(select_obj, i)
break
case 5:
$('#component_type').text(language_str('rect'))
selectObject(select_obj, i)
selectRect(select_obj, i)
break
case 6:
$('#component_type').text(language_str('circ'))
selectObject(select_obj, i)
selectCircle(select_obj, i)
break
case 7:
$('#component_type').text(language_str('line'))
selectObject(select_obj, i)
selectLine(select_obj, i)
break
case 8:
$('#component_type').text(language_str('qrc'))
selectObject(select_obj, i)
selectQrCode(select_obj, i)
break
case 9:
$('#component_type').text(language_str('barc'))
selectObject(select_obj, i)
selectBarCode(select_obj, i)
break
case 10:
$('#component_type').text(language_str('counter'))
selectObject(select_obj, i)
selectCounter(select_obj, i)
break
case 11:
$("#component_type").text(language_str("ctext"));
selectObject(select_obj, i);
selectCircleText(select_obj, i);
break;
}
selectObj(i, true)
} else {
//背景,收起对象属性
$('#base_control').hide()
$('#line_control').hide()
$('#pic_control').hide()
$('#out_pic_control').hide()
$('#text_control').hide()
$("#circle_text_control").hide();
$('#out_text_control').hide()
$('#rect_control').hide()
$('#circle_control').hide()
$('#qrcode_Controll').hide()
$('#barcode_controll').hide()
$('#counter_control').hide()
selectObj(-1)
$('#component_type').text(language_str('bg'))
}
})
canvas1.on('text:editing:entered', function () {
_textEdit = true
})
canvas1.on('text:editing:exited', function () {
_textEdit = false
})
canvas1.on('object:modified', function (event) {
if (canvas1.getActiveObjects().length > 1) {
return
}
// 跳过辅助线
if (event.target.isGuideLine) {
return
}
let idx = getIndex(event.target, canvas1);
if (idx <= 0) return;
// 安全检查:确保 objs[idx - 1] 存在且有 type 属性
if (!objs[idx - 1] || typeof objs[idx - 1].type === 'undefined') {
return
}
if (objs[idx - 1].type == 3) {
event.target.fontSize *= event.target.scaleX
event.target.fontSize = event.target.fontSize.toFixed(0)
event.target.scaleX = 1
event.target.scaleY = 1
event.target._clearCache()
canvas1.renderAll()
updateControls()
} else if (objs[idx - 1].type == 4) {
event.target.fontSize *= event.target.scaleX
event.target.fontSize = event.target.fontSize.toFixed(0)
event.target.scaleX = 1
event.target.scaleY = 1
event.target._clearCache()
canvas1.renderAll()
} else if (objs[idx - 1].type == 10) {
event.target.fontSize *= event.target.scaleX
event.target.fontSize = event.target.fontSize.toFixed(0)
event.target.scaleX = 1
event.target.scaleY = 1
event.target._clearCache()
canvas1.renderAll()
} else if (objs[idx - 1].type == 5) {
canvas1.getActiveObject().set('width', canvas1.getActiveObject().get('width') * canvas1.getActiveObject().get('scaleX'))
canvas1.getActiveObject().set('height', canvas1.getActiveObject().get('height') * canvas1.getActiveObject().get('scaleY'))
canvas1.getActiveObject().set('scaleX', 1)
canvas1.getActiveObject().set('scaleY', 1)
updateControls()
}
recordState()
})
canvas1.on('mouse:up', (e) => {
canvas = canvas1;
objs = objs1;
switch (addState) {
case 1:
addPic(e.pointer)
addState = 0
background_image.hoverCursor = 'default'
canvas1.renderAll()
$('#addPic').css('background-color', '')
break
case 2:
addOutPic(e.pointer)
addState = 0
background_image.hoverCursor = 'default'
canvas1.renderAll()
$('#addOutPic').css('background-color', '')
break
case 3:
addText(e.pointer)
addState = 0
background_image.hoverCursor = 'default'
canvas1.renderAll()
$('#addText').css('background-color', '')
break
case 4:
addOutText(e.pointer)
addState = 0
background_image.hoverCursor = 'default'
canvas1.renderAll()
$('#addOutText').css('background-color', '')
break
case 5:
addRect(e.pointer)
addState = 0
background_image.hoverCursor = 'default'
canvas1.renderAll()
$('#addRect').css('background-color', '')
break
case 6:
addCircle(e.pointer)
addState = 0
background_image.hoverCursor = 'default'
canvas1.renderAll()
$('#addCircle').css('background-color', '')
break
case 7:
addLine(e.pointer)
addState = 0
background_image.hoverCursor = 'default'
canvas1.renderAll()
$('#addLine').css('background-color', '')
break
case 8:
addQrCode(e.pointer)
addState = 0
background_image.hoverCursor = 'default'
canvas1.renderAll()
$('#addQrCode').css('background-color', '')
break
case 9:
addBarCode(e.pointer)
addState = 0
background_image.hoverCursor = 'default'
canvas1.renderAll()
$('#addBarCode').css('background-color', '')
break
case 10:
addCounter(e.pointer)
addState = 0
background_image.hoverCursor = 'default'
$('#addCounter').css('background-color', '')
break
case 11:
addCircleText(e.pointer);
addState = 0;
background_image.hoverCursor = "default";
canvas1.renderAll();
$("#addCircleText").css("background-color", "");
break;
}
})
canvas1.on('text:changed', (e) => {
$('#text_text').val(e.target.get('text'))
})
canvas1.on('after:render', function () {
if (is_bgi_add) {
var image = document.getElementById('source_front')
ctx1.drawImage(image, (canvas.width - $('#source_front').width()) / 2, (canvas.height - $('#source_front').height()) / 2, $('#source_front').width(), $('#source_front').height())
}
})
canvas2.on('text:editing:entered', function () {
_textEdit = true
})
canvas2.on('text:editing:exited', function () {
_textEdit = false
})
canvas2.on('after:render', function () {
if (is_bgi_add) {
var image = document.getElementById('source_back')
ctx2.drawImage(image, (canvas.width - $('#source_back').width()) / 2, (canvas1.height - $('#source_back').height()) / 2, $('#source_back').width(), $('#source_back').height())
}
})
canvas2.on('mouse:move', (e) => {
if (!e.pointer || typeof background_image === 'undefined' || !background_image) return;
canvas = canvas2;
objs = objs2;
$('#posText').text('X: ' + (e.pointer.x - background_image.left).toFixed(0) + ' Y: ' + (e.pointer.y - background_image.top).toFixed(0))
})
canvas2.on("object:moving", function (e) {
canvas = canvas2;
objs = objs2;
let obj = canvas2.getActiveObject()
let idx = getIndex(e.target, canvas2);
// 添加边界检查,避免访问 undefined
if (idx > 0 && idx <= objs2.length && objs2[idx - 1] && objs2[idx - 1].type && objs2[idx - 1].type === 11 && $("#circle_text_center").prop("checked")) {
let pointer = {
x: obj.left,
y: obj.top
}
let distance = getDisdance(pointer.x, pointer.y, canvas2.width / 2, canvas2.height / 2)
// 计算角度时需要使用 canvas2
let centerX = canvas2.width / 2;
let centerY = canvas2.height / 2;
let mouseX = pointer.x;
let mouseY = pointer.y;
let dx = mouseX - centerX;
let dy = mouseY - centerY;
let angleRad = Math.atan2(dy, dx);
let angleDeg = angleRad * (180 / Math.PI);
if (angleDeg < 0) {
angleDeg += 360;
}
angleDeg += 90;
let flipped = pointer.y > canvas2.height / 2 ? true : false
if (typeof circle_text_diameter !== 'undefined' && circle_text_diameter.setValue) {
circle_text_diameter.setValue(distance * 2 - 50);
}
obj.set("diameter", distance * 2);
obj.set("angle", angleDeg);
obj.set("flipped", flipped);
}
updateControls();
});
canvas2.on('object:scaling', function (e) {
canvas = canvas2;
objs = objs2;
updateControls()
})
canvas2.on('object:rotating', function (e) {
canvas = canvas2;
objs = objs2;
updateControls()
})
canvas2.on('object:rotated', function (e) {
canvas = canvas2;
objs = objs2;
recordState()
})
canvas2.on('object:added', function (e) {
//recordState();
})
canvas2.on('mouse:down', (e) => {
//单选
canvas = canvas2;
objs = objs2;
let select_obj = canvas.getActiveObject()
// 如果是辅助线,直接返回,不处理
if (select_obj && select_obj.isGuideLine) {
return
}
let i = getIndex(select_obj, canvas)
if (i != 0) {
//不是背景
--i
// 安全检查:确保 objs[i] 存在且有 type 属性
if (!objs[i] || typeof objs[i].type === 'undefined') {
return
}
switch (objs[i].type) {
case 1:
$('#component_type').text(language_str('img'))
selectObject(select_obj, i)
selectPic(select_obj, i)
break
case 2:
$('#component_type').text(language_str('simg'))
selectObject(select_obj, i)
selectOutPic(select_obj, i)
break
case 3:
$('#component_type').text(language_str('text'))
selectObject(select_obj, i)
selectText(select_obj, i)
break
case 4:
$('#component_type').text(language_str('stext'))
selectObject(select_obj, i)
selectOutText(select_obj, i)
break
case 5:
$('#component_type').text(language_str('rect'))
selectObject(select_obj, i)
selectRect(select_obj, i)
break
case 6:
$('#component_type').text(language_str('circ'))
selectObject(select_obj, i)
selectCircle(select_obj, i)
break
case 7:
$('#component_type').text(language_str('line'))
selectObject(select_obj, i)
selectLine(select_obj, i)
break
case 8:
$('#component_type').text(language_str('qrc'))
selectObject(select_obj, i)
selectQrCode(select_obj, i)
break
case 9:
$('#component_type').text(language_str('barc'))
selectObject(select_obj, i)
selectBarCode(select_obj, i)
break
case 10:
$('#component_type').text(language_str('counter'))
selectObject(select_obj, i)
selectCounter(select_obj, i)
break
case 11:
$("#component_type").text(language_str("ctext"));
selectObject(select_obj, i);
selectCircleText(select_obj, i);
break;
}
selectObj(i, true)
} else {
//背景,收起对象属性
$('#base_control').hide()
$('#line_control').hide()
$('#pic_control').hide()
$('#out_pic_control').hide()
$('#text_control').hide()
$("#circle_text_control").hide();
$('#out_text_control').hide()
$('#rect_control').hide()
$('#circle_control').hide()
$('#qrcode_Controll').hide()
$('#barcode_controll').hide()
$('#counter_control').hide()
selectObj(-1)
$('#component_type').text(language_str('bg'))
}
})
canvas2.on('object:modified', function (event) {
canvas = canvas2;
objs = objs2;
if (canvas.getActiveObjects().length > 1) {
return
}
// 跳过辅助线
if (event.target.isGuideLine) {
return
}
let idx = getIndex(event.target, canvas2);
if (idx <= 0) return;
// 安全检查:确保 objs[idx - 1] 存在且有 type 属性
if (!objs[idx - 1] || typeof objs[idx - 1].type === 'undefined') {
return
}
if (objs[idx - 1].type == 3) {
event.target.fontSize *= event.target.scaleX
event.target.fontSize = event.target.fontSize.toFixed(0)
event.target.scaleX = 1
event.target.scaleY = 1
event.target._clearCache()
canvas2.renderAll()
} else if (objs[idx - 1].type == 4) {
event.target.fontSize *= event.target.scaleX
event.target.fontSize = event.target.fontSize.toFixed(0)
event.target.scaleX = 1
event.target.scaleY = 1
event.target._clearCache()
canvas2.renderAll()
} else if (objs[idx - 1].type == 10) {
event.target.fontSize *= event.target.scaleX
event.target.fontSize = event.target.fontSize.toFixed(0)
event.target.scaleX = 1
event.target.scaleY = 1
event.target._clearCache()
canvas2.renderAll()
} else if (objs[idx - 1].type == 5) {
canvas2.getActiveObject().set('width', canvas2.getActiveObject().get('width') * canvas2.getActiveObject().get('scaleX'))
canvas2.getActiveObject().set('height', canvas2.getActiveObject().get('height') * canvas2.getActiveObject().get('scaleY'))
canvas2.getActiveObject().set('scaleX', 1)
canvas2.getActiveObject().set('scaleY', 1)
updateControls()
}
recordState()
})
canvas2.on('mouse:up', (e) => {
canvas = canvas2;
objs = objs2;
switch (addState) {
case 1:
addPic(e.pointer)
addState = 0
background_image.hoverCursor = 'default'
canvas2.renderAll()
$('#addPic').css('background-color', '')
break
case 2:
addOutPic(e.pointer)
addState = 0
background_image.hoverCursor = 'default'
canvas2.renderAll()
$('#addOutPic').css('background-color', '')
break
case 3:
addText(e.pointer)
addState = 0
background_image.hoverCursor = 'default'
canvas2.renderAll()
$('#addText').css('background-color', '')
break
case 4:
addOutText(e.pointer)
addState = 0
background_image.hoverCursor = 'default'
canvas2.renderAll()
$('#addOutText').css('background-color', '')
break
case 5:
addRect(e.pointer)
addState = 0
background_image.hoverCursor = 'default'
canvas2.renderAll()
$('#addRect').css('background-color', '')
break
case 6:
addCircle(e.pointer)
addState = 0
background_image.hoverCursor = 'default'
canvas2.renderAll()
$('#addCircle').css('background-color', '')
break
case 7:
addLine(e.pointer)
addState = 0
background_image.hoverCursor = 'default'
canvas2.renderAll()
$('#addLine').css('background-color', '')
break
case 8:
addQrCode(e.pointer)
addState = 0
background_image.hoverCursor = 'default'
canvas2.renderAll()
$('#addQrCode').css('background-color', '')
break
case 9:
addBarCode(e.pointer)
addState = 0
background_image.hoverCursor = 'default'
canvas2.renderAll()
$('#addBarCode').css('background-color', '')
break
case 10:
addCounter(e.pointer)
addState = 0
background_image.hoverCursor = 'default'
$('#addCounter').css('background-color', '')
break
case 11:
addCircleText(e.pointer);
addState = 0;
background_image.hoverCursor = "default";
canvas2.renderAll();
$("#addCircleText").css("background-color", "");
break;
}
})
}