2750 lines
113 KiB
JavaScript
2750 lines
113 KiB
JavaScript
// design2核心功能模块
|
||
// 注意:此代码在layui.use回调函数内部执行
|
||
// 全局变量已在主入口文件中定义,这里只需要初始化
|
||
|
||
$('#canvas1').attr('height', document.body.clientHeight - 100)
|
||
$('#canvas2').attr('height', document.body.clientHeight - 100)
|
||
$('#object_attribute').css('height', '470px')
|
||
$('#obj_list').css('height', document.body.clientHeight - 520)
|
||
$('.obj_list').css('height', $('#obj_list').height() - 32)
|
||
|
||
$('.main').show()
|
||
$('#canvas1').attr('width', $('#canvas-div').width())
|
||
$('#canvas2').attr('width', $('#canvas-div').width())
|
||
|
||
// 初始化Canvas对象
|
||
// 优化性能:在创建 Fabric Canvas 之前,先设置 canvas context 的 willReadFrequently
|
||
try {
|
||
const canvas1El = document.getElementById('canvas1');
|
||
const canvas2El = document.getElementById('canvas2');
|
||
if (canvas1El) {
|
||
canvas1El.getContext('2d', { willReadFrequently: true });
|
||
}
|
||
if (canvas2El) {
|
||
canvas2El.getContext('2d', { willReadFrequently: true });
|
||
}
|
||
} catch (e) {
|
||
// 如果浏览器不支持 willReadFrequently,忽略错误
|
||
}
|
||
|
||
canvas1 = new fabric.Canvas('canvas1')
|
||
canvas2 = new fabric.Canvas('canvas2')
|
||
fabric.Object.prototype.objectCaching = false
|
||
ctx1 = canvas1.getSelectionContext()
|
||
ctx2 = canvas2.getSelectionContext()
|
||
is_bgi_add = false
|
||
canvas1.zoomToPoint(new fabric.Point(canvas1.width / 2, canvas1.height / 2), $('#canvas-div').width() / 1200 > 1 ? 1 : $('#canvas-div').width() / 1200)
|
||
//console.log(canvas1.width / 2, canvas1.height / 2);
|
||
//console.log($("#canvas-div").width() / 1200 > 1 ? 1 : $("#canvas-div").width() / 1200);
|
||
canvas2.zoomToPoint(new fabric.Point(canvas2.width / 2, canvas2.height / 2), $('#canvas-div').width() / 1200 > 1 ? 1 : $('#canvas-div').width() / 1200)
|
||
zoom = $('#canvas-div').width() / 1200 > 1 ? 1 : $('#canvas-div').width() / 1200
|
||
|
||
// 初始化标尺
|
||
function initRulers() {
|
||
// dpi已在主入口文件中定义为全局变量
|
||
const mmToPx = dpi / 25.4; // 1mm = 11.811px (300 DPI)
|
||
const rulerHeight = 20;
|
||
const rulerWidth = 20;
|
||
|
||
// 获取实际画布的像素尺寸(px)
|
||
// design2.html 的实际画布尺寸是 1012px x 648px
|
||
const actualCanvasWidth = canvas1.width || 1012; // 实际画布宽度(px)
|
||
const actualCanvasHeight = canvas1.height || 648; // 实际画布高度(px)
|
||
|
||
// 获取显示区域的尺寸(包括 margin)
|
||
const canvasDiv = $('#canvas-div');
|
||
const canvasWrapper = $('.canvas-wrapper');
|
||
// 使用 canvas-wrapper 的宽度,如果没有则使用 canvas_div 的宽度
|
||
let canvasWidth = canvasWrapper.width();
|
||
let canvasHeight = canvasWrapper.height();
|
||
if (!canvasWidth || canvasWidth === 0) {
|
||
const canvas1Width = $('#canvas1').width() || canvasDiv.width() - 20;
|
||
canvasWidth = canvas1Width + 20; // 加上 margin-left: 20px
|
||
}
|
||
if (!canvasHeight || canvasHeight === 0) {
|
||
const canvas1Height = $('#canvas1').height() || canvasDiv.height() - 20;
|
||
canvasHeight = canvas1Height + 20; // 加上 margin-top: 20px
|
||
}
|
||
|
||
// 设置标尺尺寸(使用显示区域的尺寸)
|
||
$('#ruler-h').attr('width', canvasWidth).attr('height', rulerHeight);
|
||
$('#ruler-v').attr('width', rulerWidth).attr('height', canvasHeight);
|
||
$('.ruler-horizontal').css('width', canvasWidth + 'px');
|
||
$('.ruler-vertical').css('height', canvasHeight + 'px');
|
||
|
||
// 绘制水平标尺
|
||
function drawHorizontalRuler() {
|
||
const ctx = document.getElementById('ruler-h').getContext('2d', { willReadFrequently: true });
|
||
ctx.clearRect(0, 0, canvasWidth, rulerHeight);
|
||
|
||
// 背景
|
||
ctx.fillStyle = '#2C2C2C';
|
||
ctx.fillRect(0, 0, canvasWidth, rulerHeight);
|
||
|
||
// 边框
|
||
ctx.strokeStyle = '#1E1E1E';
|
||
ctx.lineWidth = 1;
|
||
ctx.strokeRect(0, 0, canvasWidth, rulerHeight);
|
||
ctx.beginPath();
|
||
ctx.moveTo(0, rulerHeight - 1);
|
||
ctx.lineTo(canvasWidth, rulerHeight - 1);
|
||
ctx.stroke();
|
||
|
||
// 刻度线
|
||
ctx.strokeStyle = '#888888';
|
||
ctx.fillStyle = '#CCCCCC';
|
||
ctx.font = '10px Arial';
|
||
ctx.textAlign = 'left';
|
||
ctx.textBaseline = 'top';
|
||
|
||
// 计算:实际画布尺寸(px)对应的物理尺寸(mm),然后根据显示区域的缩放比例计算
|
||
// 实际画布物理宽度 = actualCanvasWidth / dpi * 25.4 (mm)
|
||
// 显示区域宽度 = actualCanvasWidth * zoom (px)
|
||
// 所以:1mm 在显示区域中 = (actualCanvasWidth * zoom) / (actualCanvasWidth / dpi * 25.4) = zoom * dpi / 25.4
|
||
const pxPerMm = zoom * mmToPx; // 在显示区域中,1mm对应的像素数
|
||
const marginOffset = 20; // canvas 的 margin-left: 20px
|
||
// 标尺0点应该在background_image的左上角位置
|
||
// background_image在画布坐标系中的left值,需要转换到标尺坐标系
|
||
// 画布从标尺的marginOffset位置开始,所以:标尺0点 = marginOffset + background_image.left (如果存在)
|
||
let originX = marginOffset;
|
||
if (typeof background_image !== 'undefined' && background_image) {
|
||
originX = marginOffset + background_image.left;
|
||
}
|
||
const startX = 0;
|
||
const endX = canvasWidth;
|
||
|
||
// 绘制主要刻度(每10mm)
|
||
// 从0点向左绘制负值刻度
|
||
for (let mm = -10; originX + mm * pxPerMm >= startX; mm -= 10) {
|
||
const x = originX + mm * pxPerMm;
|
||
if (x < startX) break;
|
||
|
||
ctx.beginPath();
|
||
ctx.moveTo(x, 0);
|
||
ctx.lineTo(x, rulerHeight);
|
||
ctx.stroke();
|
||
|
||
// 数字(负值)
|
||
ctx.fillText(mm + 'mm', x + 2, 2);
|
||
}
|
||
// 从0点向右绘制正值刻度
|
||
for (let mm = 0; originX + mm * pxPerMm <= endX; mm += 10) {
|
||
const x = originX + mm * pxPerMm;
|
||
if (x > endX) break;
|
||
|
||
ctx.beginPath();
|
||
ctx.moveTo(x, 0);
|
||
ctx.lineTo(x, rulerHeight);
|
||
ctx.stroke();
|
||
|
||
// 数字
|
||
ctx.fillText(mm + 'mm', x + 2, 2);
|
||
}
|
||
|
||
// 绘制次要刻度(每1mm)
|
||
// 从0点向左绘制负值刻度
|
||
for (let mm = -1; originX + mm * pxPerMm >= startX; mm -= 1) {
|
||
const x = originX + mm * pxPerMm;
|
||
if (x < startX) break;
|
||
if (mm % 10 === 0) continue; // 跳过主要刻度
|
||
|
||
ctx.beginPath();
|
||
ctx.moveTo(x, rulerHeight - 8);
|
||
ctx.lineTo(x, rulerHeight);
|
||
ctx.stroke();
|
||
}
|
||
// 从0点向右绘制正值刻度
|
||
for (let mm = 0; originX + mm * pxPerMm <= endX; mm += 1) {
|
||
const x = originX + mm * pxPerMm;
|
||
if (x > endX) break;
|
||
if (mm % 10 === 0) continue; // 跳过主要刻度
|
||
|
||
ctx.beginPath();
|
||
ctx.moveTo(x, rulerHeight - 8);
|
||
ctx.lineTo(x, rulerHeight);
|
||
ctx.stroke();
|
||
}
|
||
}
|
||
|
||
// 绘制垂直标尺
|
||
function drawVerticalRuler() {
|
||
const ctx = document.getElementById('ruler-v').getContext('2d', { willReadFrequently: true });
|
||
ctx.clearRect(0, 0, rulerWidth, canvasHeight);
|
||
|
||
// 背景
|
||
ctx.fillStyle = '#2C2C2C';
|
||
ctx.fillRect(0, 0, rulerWidth, canvasHeight);
|
||
|
||
// 边框
|
||
ctx.strokeStyle = '#1E1E1E';
|
||
ctx.lineWidth = 1;
|
||
ctx.strokeRect(0, 0, rulerWidth, canvasHeight);
|
||
ctx.beginPath();
|
||
ctx.moveTo(rulerWidth - 1, 0);
|
||
ctx.lineTo(rulerWidth - 1, canvasHeight);
|
||
ctx.stroke();
|
||
|
||
// 刻度线
|
||
ctx.strokeStyle = '#888888';
|
||
ctx.fillStyle = '#CCCCCC';
|
||
ctx.font = '10px Arial';
|
||
ctx.textAlign = 'left';
|
||
ctx.textBaseline = 'top';
|
||
|
||
// 计算:实际画布尺寸(px)对应的物理尺寸(mm),然后根据显示区域的缩放比例计算
|
||
const pxPerMm = zoom * mmToPx; // 在显示区域中,1mm对应的像素数
|
||
const marginOffset = 20; // canvas 的 margin-top: 20px (但还要加上ruler的高度)
|
||
const rulerHeightOffset = 20; // ruler 的高度
|
||
// 标尺0点应该在background_image的左上角位置
|
||
// background_image在画布坐标系中的top值,需要转换到标尺坐标系
|
||
// 画布从标尺的marginOffset + rulerHeightOffset位置开始,所以:标尺0点 = marginOffset + rulerHeightOffset + background_image.top (如果存在)
|
||
let originY = marginOffset + rulerHeightOffset;
|
||
if (typeof background_image !== 'undefined' && background_image) {
|
||
originY = marginOffset + rulerHeightOffset + background_image.top;
|
||
}
|
||
const startY = 0;
|
||
const endY = canvasHeight;
|
||
|
||
// 绘制主要刻度(每10mm)
|
||
// 从0点向上绘制负值刻度
|
||
for (let mm = -10; originY + mm * pxPerMm >= startY; mm -= 10) {
|
||
const y = originY + mm * pxPerMm;
|
||
if (y < startY) break;
|
||
|
||
ctx.beginPath();
|
||
ctx.moveTo(0, y);
|
||
ctx.lineTo(rulerWidth, y);
|
||
ctx.stroke();
|
||
|
||
// 数字(旋转90度,负值)
|
||
ctx.save();
|
||
ctx.translate(2, y + 8);
|
||
ctx.rotate(-Math.PI / 2);
|
||
ctx.fillText(mm + 'mm', 0, 0);
|
||
ctx.restore();
|
||
}
|
||
// 从0点向下绘制正值刻度
|
||
for (let mm = 0; originY + mm * pxPerMm <= endY; mm += 10) {
|
||
const y = originY + mm * pxPerMm;
|
||
if (y > endY) break;
|
||
|
||
ctx.beginPath();
|
||
ctx.moveTo(0, y);
|
||
ctx.lineTo(rulerWidth, y);
|
||
ctx.stroke();
|
||
|
||
// 数字(旋转90度)
|
||
ctx.save();
|
||
ctx.translate(2, y + 8);
|
||
ctx.rotate(-Math.PI / 2);
|
||
ctx.fillText(mm + 'mm', 0, 0);
|
||
ctx.restore();
|
||
}
|
||
|
||
// 绘制次要刻度(每1mm)
|
||
// 从0点向上绘制负值刻度
|
||
for (let mm = -1; originY + mm * pxPerMm >= startY; mm -= 1) {
|
||
const y = originY + mm * pxPerMm;
|
||
if (y < startY) break;
|
||
if (mm % 10 === 0) continue; // 跳过主要刻度
|
||
|
||
ctx.beginPath();
|
||
ctx.moveTo(rulerWidth - 8, y);
|
||
ctx.lineTo(rulerWidth, y);
|
||
ctx.stroke();
|
||
}
|
||
// 从0点向下绘制正值刻度
|
||
for (let mm = 0; originY + mm * pxPerMm <= endY; mm += 1) {
|
||
const y = originY + mm * pxPerMm;
|
||
if (y > endY) break;
|
||
if (mm % 10 === 0) continue; // 跳过主要刻度
|
||
|
||
ctx.beginPath();
|
||
ctx.moveTo(rulerWidth - 8, y);
|
||
ctx.lineTo(rulerWidth, y);
|
||
ctx.stroke();
|
||
}
|
||
}
|
||
|
||
// 初始绘制
|
||
drawHorizontalRuler();
|
||
drawVerticalRuler();
|
||
|
||
// 监听窗口大小变化
|
||
$(window).on('resize', function () {
|
||
setTimeout(function () {
|
||
const canvasWrapper = $('.canvas-wrapper');
|
||
let newWidth = canvasWrapper.width();
|
||
let newHeight = canvasWrapper.height();
|
||
if (!newWidth || newWidth === 0) {
|
||
const canvas1Width = $('#canvas1').width() || $('#canvas-div').width() - 20;
|
||
newWidth = canvas1Width + 20; // 加上 margin-left: 20px
|
||
}
|
||
if (!newHeight || newHeight === 0) {
|
||
const canvas1Height = $('#canvas1').height() || $('#canvas-div').height() - 20;
|
||
newHeight = canvas1Height + 20; // 加上 margin-top: 20px
|
||
}
|
||
if (newWidth !== canvasWidth || newHeight !== canvasHeight) {
|
||
canvasWidth = newWidth;
|
||
canvasHeight = newHeight;
|
||
$('#ruler-h').attr('width', newWidth);
|
||
$('#ruler-v').attr('height', newHeight);
|
||
$('.ruler-horizontal').css('width', newWidth + 'px');
|
||
$('.ruler-vertical').css('height', newHeight + 'px');
|
||
drawHorizontalRuler();
|
||
drawVerticalRuler();
|
||
}
|
||
}, 100);
|
||
});
|
||
|
||
// 监听画布缩放变化
|
||
canvas1.on('after:render', function () {
|
||
drawHorizontalRuler();
|
||
drawVerticalRuler();
|
||
});
|
||
canvas2.on('after:render', function () {
|
||
drawHorizontalRuler();
|
||
drawVerticalRuler();
|
||
});
|
||
}
|
||
initRulers();
|
||
$('#source_front').width(zoom * $('#source_front').width())
|
||
$('#source_back').width(zoom * $('#source_back').width())
|
||
$('.canvas-container:eq(1)').hide()
|
||
canvas = canvas1
|
||
fabric.Object.prototype.set({
|
||
borderColor: '#9013FE',
|
||
cornerColor: '#9013FE', //激活状态角落图标的填充颜色
|
||
cornerStrokeColor: '#9013FE', //激活状态角落图标的边框颜色
|
||
borderOpacityWhenMoving: 1,
|
||
borderScaleFactor: 1,
|
||
cornerSize: 6,
|
||
cornerStyle: 'circle', //rect,circle
|
||
centeredScaling: false, //角落放大缩小是否是以图形中心为放大原点
|
||
centeredRotation: true, //旋转按钮旋转是否是左上角为圆心旋转
|
||
transparentCorners: false, //激活状态角落的图标是否透明
|
||
rotatingPointOffset: 20, //旋转距旋转体的距离
|
||
padding: 0
|
||
})
|
||
canvas1.preserveObjectStacking = true
|
||
canvas2.preserveObjectStacking = true
|
||
|
||
// ==========================================
|
||
// 对象选择和属性更新函数
|
||
// ==========================================
|
||
function updateControls() {
|
||
if (!canvas.getActiveObject()) return;
|
||
$("#text_r").val(canvas.getActiveObject().get("angle").toFixed(0));
|
||
$("#text_x").val((canvas.getActiveObject().get("left") - background_image.left).toFixed(0));
|
||
$("#text_y").val((canvas.getActiveObject().get("top") - background_image.top).toFixed(0));
|
||
$("#text_h").val((canvas.getActiveObject().get("scaleY") * canvas.getActiveObject().get("height")).toFixed(0));
|
||
$("#text_w").val((canvas.getActiveObject().get("scaleX") * canvas.getActiveObject().get("width")).toFixed(0));
|
||
if (canvas.getActiveObject().get("selectable")) {
|
||
$("#lock_img").attr("src", "public/images/unlock20.png")//已经上锁,需要解锁
|
||
} else {
|
||
$("#lock_img").attr("src", "public/images/lock20.png")//没上锁,可以上锁
|
||
}
|
||
}
|
||
function selectObject(target, index) {
|
||
updateControls();
|
||
$("#base_control").show();
|
||
}
|
||
|
||
function selectPic(target, index) {
|
||
$("#pic_control").show();
|
||
$("#set_bg").show();
|
||
let activeObj = canvas.getActiveObject();
|
||
if (typeof pic_op !== 'undefined' && pic_op.setValue) {
|
||
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 + "%");
|
||
}
|
||
$("#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 selectOutPic(target, index) {
|
||
$("#out_pic_control").show();
|
||
if (typeof out_pic_op !== 'undefined' && out_pic_op.setValue) {
|
||
out_pic_op.setValue(100 - (canvas.getActiveObject().get("opacity") * 100));
|
||
} else {
|
||
$("#out_pic_op").next().children(".layui-slider-bar").css("width", (1 - canvas.getActiveObject().get("opacity")) * 100 + "%");
|
||
$("#out_pic_op").next().children(".layui-slider-handle").css("left", (1 - canvas.getActiveObject().get("opacity")) * 100 + "%");
|
||
}
|
||
let idx = getIndex(canvas.getActiveObject(), canvas);
|
||
$("#out_pic_field_name").val(objs[idx - 1].name);
|
||
$("#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 selectText(target, index) {
|
||
$("#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")
|
||
}
|
||
$("#circle_text_control").hide();
|
||
$("#pic_control").hide();
|
||
$("#set_bg").hide();
|
||
$("#out_pic_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 selectCircleText(target, index) {
|
||
let idx = getIndex(canvas.getActiveObject(), canvas);
|
||
$("#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 !== 'undefined' && circle_text_size.setValue) {
|
||
circle_text_size_updating = true; // 设置标志位
|
||
circle_text_size.setValue(canvas.getActiveObject().get("fontSize"));
|
||
circle_text_size_updating = false; // 清除标志位
|
||
} else {
|
||
$("#circle_text_size").next().children(".layui-slider-bar").css("width", ((canvas.getActiveObject().get("fontSize") - 10) / (120 - 10)) * 100 + "%");
|
||
$("#circle_text_size").next().children(".layui-slider-handle").css("left", ((canvas.getActiveObject().get("fontSize") - 10) / (120 - 10)) * 100 + "%");
|
||
}
|
||
if (typeof circle_text_diameter !== 'undefined' && circle_text_diameter.setValue) {
|
||
circle_text_diameter.setValue(canvas.getActiveObject().get("diameter"));
|
||
} else {
|
||
$("#circle_text_diameter").next().children(".layui-slider-bar").css("width", ((canvas.getActiveObject().get("diameter") - 50) / (1100 - 50)) * 100 + "%");
|
||
$("#circle_text_diameter").next().children(".layui-slider-handle").css("left", ((canvas.getActiveObject().get("diameter") - 50) / (1100 - 50)) * 100 + "%");
|
||
}
|
||
$("#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 selectOutText(target, index) {
|
||
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(), canvas);
|
||
$("#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 selectRect(target, index) {
|
||
$("#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"));
|
||
if (typeof rect_op !== 'undefined' && rect_op.setValue) {
|
||
rect_op.setValue(100 - (canvas.getActiveObject().get("opacity") * 100));
|
||
} else {
|
||
$("#rect_op").next().children(".layui-slider-bar").css("width", (1 - canvas.getActiveObject().get("opacity")) * 100 + "%");
|
||
$("#rect_op").next().children(".layui-slider-handle").css("left", (1 - 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();
|
||
$("#circle_control").hide();
|
||
$("#line_control").hide();
|
||
$("#counter_control").hide();
|
||
$("#qrcode_Controll").hide();
|
||
$("#barcode_controll").hide();
|
||
}
|
||
|
||
function selectCircle(target, index) {
|
||
$("#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"));
|
||
if (typeof circle_op !== 'undefined' && circle_op.setValue) {
|
||
circle_op.setValue(100 - (canvas.getActiveObject().get("opacity") * 100));
|
||
} else {
|
||
$("#circle_op").next().children(".layui-slider-bar").css("width", (1 - canvas.getActiveObject().get("opacity")) * 100 + "%");
|
||
$("#circle_op").next().children(".layui-slider-handle").css("left", (1 - 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 selectLine(target, index) {
|
||
$("#line_control").show();
|
||
let idx = getIndex(canvas.getActiveObject(), canvas);
|
||
$("#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 selectQrCode(target, index) {
|
||
$("#qrcode_Controll").show();
|
||
let idx = getIndex(canvas.getActiveObject(), canvas);
|
||
$("#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();
|
||
$("#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();
|
||
$("#barcode_controll").hide();
|
||
}
|
||
|
||
function selectBarCode(target, index) {
|
||
$("#barcode_controll").show();
|
||
let idx = getIndex(canvas.getActiveObject(), canvas);
|
||
$("#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();
|
||
$("#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();
|
||
}
|
||
|
||
function selectCounter(target, index) {
|
||
$("#counter_control").show();
|
||
let idx = getIndex(canvas.getActiveObject(), canvas);
|
||
$("#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();
|
||
$("#set_bg").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 handleObjectSelected(e) {
|
||
// 确定当前活动的 canvas(从事件参数或全局变量)
|
||
let currentCanvas = (e && e.target && (e.target.canvas === canvas1 || e.target.canvas === canvas2))
|
||
? (e.target.canvas === canvas1 ? canvas1 : canvas2)
|
||
: canvas;
|
||
|
||
// 如果事件来自 canvas,更新全局 canvas 变量
|
||
if (currentCanvas === canvas1 || currentCanvas === canvas2) {
|
||
canvas = currentCanvas;
|
||
objs = (currentCanvas === canvas1) ? objs1 : objs2;
|
||
}
|
||
|
||
let select_obj = canvas.getActiveObject();
|
||
|
||
// 1. 未选中任何对象
|
||
if (!select_obj) {
|
||
$("#base_control, #line_control, #pic_control, #out_pic_control, #text_control, #circle_text_control, #out_text_control, #rect_control, #circle_control, #counter_control, #qrcode_Controll, #barcode_controll").hide();
|
||
$("#component_type").text(language_str("bg"));
|
||
selectObj(-1, true); // 传 true,只更新UI
|
||
return;
|
||
}
|
||
|
||
// 2. 获取索引
|
||
let i = getIndex(select_obj, canvas);
|
||
|
||
if (i != 0) {
|
||
// --- 选中了普通对象 ---
|
||
--i; // 转换为 objs 数组下标
|
||
|
||
if (objs[i]) {
|
||
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;
|
||
}
|
||
}
|
||
|
||
// 【关键】这里传入 true!
|
||
// 意思是:因为我已经是在画布上选中它了,selectObj 函数只负责把左边的条目变灰,不要再回头去 setActiveObject 了
|
||
selectObj(i, true);
|
||
|
||
} else {
|
||
// --- 选中了背景 ---
|
||
$("#base_control, #line_control, #pic_control, #out_pic_control, #text_control, #circle_text_control, #out_text_control, #rect_control, #circle_control, #counter_control, #qrcode_Controll, #barcode_controll").hide();
|
||
selectObj(-1, true);
|
||
$("#component_type").text(language_str("bg"));
|
||
}
|
||
}
|
||
|
||
function handleObjectMoving(e) {
|
||
let obj = e.target;
|
||
let idx = getIndex(obj, canvas);
|
||
// 圆形文本特殊处理
|
||
if (idx > 0 && idx <= objs.length && objs[idx - 1] && objs[idx - 1].type === 11 && $("#circle_text_center").prop("checked")) {
|
||
let pointer = { x: obj.left, y: obj.top };
|
||
let distance = getDisdance(pointer.x, pointer.y, canvas.width / 2, canvas.height / 2);
|
||
let angleDeg = getDeg(pointer);
|
||
let flipped = pointer.y > canvas.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();
|
||
}
|
||
|
||
function initCanvasEvents() {
|
||
[canvas1, canvas2].forEach(currentCanvas => {
|
||
|
||
// 1. 鼠标移动
|
||
currentCanvas.on("mouse:move", (e) => {
|
||
let offsetX = 0, offsetY = 0;
|
||
if (currentCanvas === canvas2 && typeof background_image !== 'undefined') {
|
||
offsetX = background_image.left;
|
||
offsetY = background_image.top;
|
||
}
|
||
if (e.pointer) {
|
||
$("#posText").text("X: " + (e.pointer.x - offsetX).toFixed(0) + " Y: " + (e.pointer.y - offsetY).toFixed(0));
|
||
}
|
||
});
|
||
|
||
// 2. 鼠标移出
|
||
currentCanvas.on("mouse:out", () => {
|
||
// 可以在这里隐藏标尺辅助线
|
||
});
|
||
|
||
// 3. 鼠标松开 (添加对象)
|
||
currentCanvas.on("mouse:up", (e) => {
|
||
if (addState === 0) return;
|
||
const ptr = e.pointer;
|
||
switch (addState) {
|
||
case 1: addPic(ptr); break;
|
||
case 2: addOutPic(ptr); break;
|
||
case 3: addText(ptr); break;
|
||
case 4: addOutText(ptr); break;
|
||
case 5: addRect(ptr); break;
|
||
case 6: addCircle(ptr); break;
|
||
case 7: addLine(ptr); break;
|
||
case 8: addQrCode(ptr); break;
|
||
case 9: addBarCode(ptr); break;
|
||
case 10: addCounter(ptr); break;
|
||
case 11: addCircleText(ptr); break;
|
||
}
|
||
addState = 0;
|
||
if (typeof background_image !== 'undefined') background_image.hoverCursor = "default";
|
||
currentCanvas.renderAll();
|
||
$("#addPic, #addOutPic, #addText, #addOutText, #addRect, #addCircle, #addLine, #addQrCode, #addBarCode, #addCounter, #addCircleText").css("background-color", "");
|
||
});
|
||
|
||
// 4. 选中处理
|
||
currentCanvas.on('mouse:down', (e) => {
|
||
// 更新全局 canvas 变量
|
||
canvas = currentCanvas;
|
||
objs = (currentCanvas === canvas1) ? objs1 : objs2;
|
||
handleObjectSelected(e);
|
||
});
|
||
// 添加 selection 事件以确保对象选中时正确显示属性面板
|
||
currentCanvas.on('selection:created', (e) => {
|
||
canvas = currentCanvas;
|
||
objs = (currentCanvas === canvas1) ? objs1 : objs2;
|
||
handleObjectSelected(e);
|
||
});
|
||
currentCanvas.on('selection:updated', (e) => {
|
||
canvas = currentCanvas;
|
||
objs = (currentCanvas === canvas1) ? objs1 : objs2;
|
||
handleObjectSelected(e);
|
||
});
|
||
currentCanvas.on('object:selected', (e) => {
|
||
canvas = currentCanvas;
|
||
objs = (currentCanvas === canvas1) ? objs1 : objs2;
|
||
handleObjectSelected(e);
|
||
});
|
||
|
||
// 5. 对象移动
|
||
currentCanvas.on("object:moving", (e) => {
|
||
handleObjectMoving(e);
|
||
});
|
||
|
||
// 6. 变换事件
|
||
currentCanvas.on("object:rotating", updateControls);
|
||
currentCanvas.on("object:scaling", updateControls);
|
||
currentCanvas.on("object:rotated", () => { recordState(); });
|
||
currentCanvas.on('text:editing:entered', () => { _textEdit = true; });
|
||
currentCanvas.on('text:editing:exited', () => { _textEdit = false; });
|
||
currentCanvas.on("text:changed", (e) => { $("#text_text").val(e.target.get("text")); });
|
||
|
||
// 7. 对象修改后
|
||
currentCanvas.on('object:modified', function (event) {
|
||
if (currentCanvas.getActiveObjects().length > 1) return;
|
||
let idx = getIndex(event.target, currentCanvas);
|
||
if (idx <= 0) return;
|
||
let objData = objs[idx - 1];
|
||
let target = event.target;
|
||
|
||
if ([3, 4, 10].includes(objData.type)) {
|
||
target.fontSize = (target.fontSize * target.scaleX).toFixed(0);
|
||
target.scaleX = 1; target.scaleY = 1;
|
||
target._clearCache();
|
||
if (objData.type == 3) $("#text_size").val(target.fontSize);
|
||
if (objData.type == 4) $("#out_text_size").val(target.fontSize);
|
||
if (objData.type == 10) $("#count_size").val(target.fontSize);
|
||
currentCanvas.renderAll();
|
||
updateControls();
|
||
} else if (objData.type == 5) {
|
||
target.width *= target.scaleX; target.height *= target.scaleY;
|
||
target.scaleX = 1; target.scaleY = 1;
|
||
updateControls();
|
||
}
|
||
recordState();
|
||
});
|
||
});
|
||
}
|
||
|
||
function updateList() {
|
||
let str = "";
|
||
let i = 0;
|
||
|
||
// 定义行样式:Flex布局,两端对齐,相对定位防止溢出
|
||
const rowStyle = "display:flex; justify-content:space-between; align-items:center; height:32px; padding:0 5px; cursor:pointer; border-bottom:1px solid #444; color:#ccc; font-size:12px; position:relative;";
|
||
// 定义左侧内容样式
|
||
const leftStyle = "display:flex; align-items:center; overflow:hidden; white-space:nowrap; max-width:180px;";
|
||
// 定义序号样式:靠右,有左边框
|
||
const indexStyle = "min-width:24px; text-align:center; padding-left:5px; color:#666; border-left:1px solid #555;";
|
||
|
||
for (let item of objs) {
|
||
let displayIndex = i + 1; // 序号底层为1
|
||
|
||
// 图标逻辑
|
||
let iconName = "rect.svg";
|
||
switch (item.type) {
|
||
case 1: iconName = "images.svg"; break;
|
||
case 2: iconName = "images_add.svg"; break;
|
||
case 3: iconName = "text.svg"; break;
|
||
case 4: iconName = "text2.svg"; break;
|
||
case 5: iconName = "rect.svg"; break;
|
||
case 6: iconName = "round.svg"; break;
|
||
case 7: iconName = "line.svg"; break;
|
||
case 8: iconName = "qrcode.svg"; break;
|
||
case 9: iconName = "barcode.svg"; break;
|
||
case 10: iconName = "counter.svg"; break;
|
||
case 11: iconName = "text3.svg"; break;
|
||
}
|
||
|
||
// 名称逻辑
|
||
let nameText = item.name ? item.name :
|
||
(item.type === 3 ? "TEXT_" + displayIndex :
|
||
(item.type === 1 ? "IMG_" + displayIndex : "OBJ_" + displayIndex));
|
||
|
||
// 组装 HTML
|
||
str = `<div style="${rowStyle}">
|
||
<div style="${leftStyle}">
|
||
<img src="public/images/${iconName}" id="obj${i}" style="width:16px; margin-right:5px;">
|
||
<span title="${nameText}">${nameText}</span>
|
||
</div>
|
||
<span style="${indexStyle}">${displayIndex}</span>
|
||
</div>` + str;
|
||
i++;
|
||
}
|
||
$(".obj_list").html(str);
|
||
|
||
// 重新绑定点击事件(防止 updateList 后点击失效)
|
||
$(".obj_list > div").on("click", function () {
|
||
let imgId = $(this).find("img").attr("id");
|
||
if (imgId) {
|
||
let idx = parseInt(imgId.replace("obj", ""));
|
||
selectObj(idx);
|
||
}
|
||
});
|
||
}
|
||
|
||
function selectObj(objIndices, isFromCanvas = false) {
|
||
let indicesArray = (Array.isArray(objIndices)) ? objIndices : ((typeof objIndices === 'number' && objIndices >= 0) ? [objIndices] : []);
|
||
|
||
// 清除所有高亮
|
||
$('.obj_list > div').css("background-color", "transparent");
|
||
|
||
// 遍历列表查找并高亮
|
||
$('.obj_list > div').each(function () {
|
||
let $img = $(this).find("img");
|
||
if ($img.length === 0) return;
|
||
|
||
let idIndex = parseInt($img.attr("id").replace("obj", ""));
|
||
|
||
if (indicesArray.includes(idIndex)) {
|
||
$(this).css("background-color", "#6F7A84");
|
||
|
||
// 自动滚动到可视区域
|
||
if (isFromCanvas && indicesArray[0] === idIndex) {
|
||
this.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
||
}
|
||
}
|
||
});
|
||
|
||
// 如果是点击列表,触发画布选中
|
||
if (!isFromCanvas && indicesArray.length === 1) {
|
||
let target = canvas.getObjects()[indicesArray[0] + 1];
|
||
if (target) {
|
||
canvas.setActiveObject(target);
|
||
canvas.requestRenderAll();
|
||
handleObjectSelected();
|
||
}
|
||
}
|
||
}
|
||
|
||
function recordState() {
|
||
++step.val;
|
||
for (let i = step.val; i < recordObjs.length; i++) {
|
||
recordObjs.pop();
|
||
recordJson.pop();
|
||
}
|
||
recordObjs.push(JSON.stringify(objs))
|
||
j = canvas.toJSON(["selectable", "hoverable", "hoverCursor", "text", "fontStyle", "fontWeight", "underline"]);
|
||
j.objects[0].hoverCursor = "default";
|
||
recordJson.push(j);
|
||
}
|
||
|
||
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++;
|
||
}
|
||
}
|
||
|
||
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 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 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;
|
||
}
|
||
|
||
function addBackground() {
|
||
// 类型改变
|
||
fabric.Image.fromURL('./public/images/bg_front_2.png', function (image) {
|
||
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
|
||
canvas1.add(image)
|
||
canvas1.renderAll()
|
||
|
||
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()
|
||
|
||
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') {
|
||
open(file)
|
||
}
|
||
})
|
||
})
|
||
is_bgi_add = true
|
||
})
|
||
}
|
||
|
||
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()
|
||
updateList()
|
||
recordState()
|
||
}
|
||
|
||
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.setSrc(image.toDataURL(), function (image) {
|
||
canvas.add(image)
|
||
objs.push({ type: 2, name: resName('OUT_PIC_'), black: false })
|
||
canvas.renderAll()
|
||
updateList()
|
||
recordState()
|
||
})
|
||
})
|
||
}
|
||
|
||
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()
|
||
updateList()
|
||
recordState()
|
||
}
|
||
|
||
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
|
||
});
|
||
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();
|
||
updateList();
|
||
recordState();
|
||
}
|
||
|
||
function addOutText(pointer) {
|
||
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.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()
|
||
updateList()
|
||
recordState()
|
||
}
|
||
|
||
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()
|
||
updateList()
|
||
recordState()
|
||
}
|
||
|
||
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()
|
||
updateList()
|
||
recordState()
|
||
}
|
||
|
||
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()
|
||
updateList()
|
||
recordState()
|
||
}
|
||
|
||
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()
|
||
updateList()
|
||
recordState()
|
||
})
|
||
}
|
||
|
||
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 })
|
||
canvas.renderAll()
|
||
updateList()
|
||
recordState()
|
||
})
|
||
}
|
||
|
||
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()
|
||
updateList()
|
||
recordState()
|
||
}
|
||
|
||
var front_list = []
|
||
ipcRenderer.on('font-list', (event, data) => {
|
||
const newFontList = []
|
||
data.map((item) => {
|
||
if (item.indexOf('"') === 0) {
|
||
newFontList.push(item.replace(/^"|"$/g, ''))
|
||
} else {
|
||
newFontList.push(item)
|
||
}
|
||
})
|
||
front_list = newFontList
|
||
for (let item of front_list) {
|
||
$('#text_font_family').append("<option value='" + item + "'>" + item + '</option>')
|
||
$("#circle_text_font_family").append("<option value='" + item + "'>" + item + "</option>");
|
||
$('#out_text_font_family').append("<option value='" + item + "'>" + item + '</option>')
|
||
$('#barcode_font_family').append("<option value='" + item + "'>" + item + '</option>')
|
||
$('#count_font_family').append("<option value='" + item + "'>" + item + '</option>')
|
||
}
|
||
})
|
||
ipcRenderer.on('sys-lan', (event, data) => {
|
||
let lang = localStorage.getItem('lang')
|
||
if (lang) {
|
||
s_lan = lang
|
||
langua_ge(lang)
|
||
$('#language_select').val(lang)
|
||
return
|
||
}
|
||
switch (data) {
|
||
case 'zh-CN':
|
||
s_lan = 'zh'
|
||
langua_ge('zh')
|
||
$('#language_select').val('zh')
|
||
localStorage.setItem('lang', 'zh')
|
||
break
|
||
case 'zh':
|
||
s_lan = 'zh'
|
||
langua_ge('zh')
|
||
$('#language_select').val('zh')
|
||
localStorage.setItem('lang', 'zh')
|
||
break
|
||
case 'zh-TW':
|
||
s_lan = 'ozh'
|
||
langua_ge('ozh')
|
||
$('#language_select').val('ozh')
|
||
localStorage.setItem('lang', 'ozh')
|
||
break
|
||
case 'en':
|
||
s_lan = 'en'
|
||
langua_ge('en')
|
||
$('#language_select').val('en')
|
||
localStorage.setItem('lang', 'en')
|
||
break
|
||
case 'en-AU':
|
||
s_lan = 'en'
|
||
langua_ge('en')
|
||
$('#language_select').val('en')
|
||
localStorage.setItem('lang', 'en')
|
||
break
|
||
case 'en-CA':
|
||
s_lan = 'en'
|
||
langua_ge('en')
|
||
$('#language_select').val('en')
|
||
localStorage.setItem('lang', 'en')
|
||
break
|
||
case 'en-GB':
|
||
s_lan = 'en'
|
||
langua_ge('en')
|
||
$('#language_select').val('en')
|
||
localStorage.setItem('lang', 'en')
|
||
break
|
||
case 'en-NZ':
|
||
s_lan = 'en'
|
||
langua_ge('en')
|
||
$('#language_select').val('en')
|
||
localStorage.setItem('lang', 'en')
|
||
break
|
||
case 'en-US':
|
||
s_lan = 'en'
|
||
langua_ge('en')
|
||
$('#language_select').val('en')
|
||
localStorage.setItem('lang', 'en')
|
||
break
|
||
case 'en-ZA':
|
||
s_lan = 'en'
|
||
langua_ge('en')
|
||
$('#language_select').val('en')
|
||
localStorage.setItem('lang', 'en')
|
||
break
|
||
}
|
||
})
|
||
ipcRenderer.on('close', (event, message) => {
|
||
layer.confirm(
|
||
'<font style="color:black">' + language_str('whetherSave') + '</font>',
|
||
{
|
||
//是否保存当前文件?
|
||
btn: [language_str('save'), language_str('noSave'), language_str('cancel')], //['保存', '不保存', '取消']
|
||
btn3: function (index, layero) { }
|
||
},
|
||
function (index, layero) {
|
||
output(() => ipcRenderer.send('run-close'))
|
||
},
|
||
function (index) {
|
||
ipcRenderer.send('run-close')
|
||
}
|
||
)
|
||
})
|
||
|
||
addBackground() //添加背景 白色卡片
|
||
|
||
initAligningGuidelines(canvas1)
|
||
initAligningGuidelines(canvas2)
|
||
|
||
// 初始化 Canvas 事件监听
|
||
initCanvasEvents();
|
||
|
||
// 初始化所有 Slider
|
||
var circle_text_size_updating = false; // 标志位,防止循环更新
|
||
var circle_text_size = slider.render({
|
||
elem: '#circle_text_size',
|
||
min: 10,
|
||
max: 120,
|
||
value: 50,
|
||
change: function (value) {
|
||
if (circle_text_size_updating) return; // 如果正在更新slider,跳过change事件
|
||
if (canvas.getActiveObject()) {
|
||
canvas.getActiveObject().set('fontSize', value);
|
||
canvas.renderAll();
|
||
updateControls();
|
||
recordState();
|
||
}
|
||
}
|
||
});
|
||
|
||
var circle_text_diameter = slider.render({
|
||
elem: '#circle_text_diameter',
|
||
min: 50,
|
||
max: 1100,
|
||
value: 500,
|
||
change: function (value) {
|
||
if (canvas.getActiveObject()) {
|
||
canvas.getActiveObject().set('diameter', value);
|
||
canvas.renderAll();
|
||
updateControls();
|
||
recordState();
|
||
}
|
||
}
|
||
});
|
||
|
||
var out_pic_op = slider.render({
|
||
elem: '#out_pic_op',
|
||
min: 0,
|
||
max: 100,
|
||
value: 0,
|
||
change: function (value) {
|
||
if (canvas.getActiveObject()) {
|
||
canvas.getActiveObject().set('opacity', 1 - value / 100);
|
||
canvas.renderAll();
|
||
updateControls();
|
||
recordState();
|
||
}
|
||
}
|
||
});
|
||
|
||
var pic_op = slider.render({
|
||
elem: '#pic_op',
|
||
min: 0,
|
||
max: 100,
|
||
value: 0,
|
||
change: function (value) {
|
||
if (canvas.getActiveObject()) {
|
||
canvas.getActiveObject().set('opacity', 1 - value / 100);
|
||
canvas.renderAll();
|
||
updateControls();
|
||
recordState();
|
||
}
|
||
}
|
||
});
|
||
|
||
var rect_op = slider.render({
|
||
elem: '#rect_op',
|
||
min: 0,
|
||
max: 100,
|
||
value: 0,
|
||
change: function (value) {
|
||
if (canvas.getActiveObject()) {
|
||
canvas.getActiveObject().set('opacity', 1 - value / 100);
|
||
canvas.renderAll();
|
||
updateControls();
|
||
recordState();
|
||
}
|
||
}
|
||
});
|
||
|
||
var circle_op = slider.render({
|
||
elem: '#circle_op',
|
||
min: 0,
|
||
max: 100,
|
||
value: 0,
|
||
change: function (value) {
|
||
if (canvas.getActiveObject()) {
|
||
canvas.getActiveObject().set('opacity', 1 - value / 100);
|
||
canvas.renderAll();
|
||
updateControls();
|
||
recordState();
|
||
}
|
||
}
|
||
});
|
||
|
||
//canvas.setZoom(0.5)
|
||
//recordObjs1.push(JSON.stringify(objs1));
|
||
//recordJson1.push(canvas1.toJSON(["selectable","hoverable","hoverCursor","text","fontStyle","fontWeight","underline"]));
|
||
//recordObjs2.push(JSON.stringify(objs2));
|
||
//recordJson2.push(canvas2.toJSON(["selectable","hoverable","hoverCursor","text","fontStyle","fontWeight","underline"]));
|
||
canvas.renderAll() //重新渲染画布
|
||
var zoomSlider = slider.render({
|
||
elem: '#zoomSlide', //绑定元素
|
||
min: 25,
|
||
max: 500,
|
||
value: 100,
|
||
change(val) {
|
||
canvas.zoomToPoint(new fabric.Point(canvas.width / 2, canvas.height / 2), val / 100)
|
||
zoom = val / 100
|
||
//$(".canvas-container").css("transform","scale(" + val / 100 + ")")
|
||
}
|
||
})
|
||
window.rotate = function (id) {
|
||
let angle = $(`#${id}`).attr('angle') - 0
|
||
angle += 90
|
||
$(`#${id}`).css('transform', `rotate(${angle}deg)`)
|
||
$(`#${id}`).attr('angle', angle)
|
||
}
|
||
$('#display').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
|
||
display_func(img1, img2, img3)
|
||
})
|
||
})
|
||
})
|
||
})
|
||
// 导出文件
|
||
async function savePdf(buffer) {
|
||
let fs = require('fs');
|
||
// 弹出保存对话框
|
||
const { canceled, filePath } = await dialog.showSaveDialog({
|
||
title: '保存文件',
|
||
defaultPath: path.join(exePath, 'output.pdf'), // 默认路径
|
||
filters: [{ name: 'PDF 文件', extensions: ['pdf'] }] // 文件过滤器
|
||
});
|
||
|
||
if (canceled) {
|
||
console.log('用户取消了保存操作');
|
||
return;
|
||
}
|
||
|
||
// 将Buffer写入PNG文件到用户选择的路径
|
||
fs.writeFile(filePath, buffer, (err) => {
|
||
if (err) {
|
||
console.error('写入文件失败:', err);
|
||
} else {
|
||
layer.msg(language_str("saveSucc") + filePath);//'保存成功至'
|
||
console.log('PNG文件已保存至:', filePath);
|
||
}
|
||
});
|
||
}
|
||
function display_func(img1, img2, img3) {
|
||
$('#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()
|
||
$('#component_type').text(language_str('bg')) //"背景"
|
||
canvas1.discardActiveObject().renderAll()
|
||
canvas2.discardActiveObject().renderAll()
|
||
let _objs1 = canvas1.getObjects()
|
||
let g1 = []
|
||
let g3 = []
|
||
let g5 = []
|
||
let left = 0 //左裁剪
|
||
let top = 0 //顶裁剪
|
||
let black_left = 0 //黑色左裁剪
|
||
let black_top = 0 //黑色顶裁剪
|
||
let all_left = 0 //预览图左裁剪
|
||
let all_top = 0 //预览图顶裁剪
|
||
for (let item of _objs1) {
|
||
let idx = getIndex(item, canvas1)
|
||
//console.log("------");
|
||
//console.log(item.getCoords());
|
||
//console.log(getCoordsMinX(background_image.getCoords()));
|
||
//console.log(getCoordsMinX(item.getCoords()));
|
||
//console.log(getCoordsMinX(background_image.getCoords()) - getCoordsMinX(item.getCoords()));
|
||
//console.log("------");
|
||
if (getCoordsMinX(background_image.getCoords()) - getCoordsMinX(item.getCoords()) > all_left) {
|
||
all_left = -(getCoordsMinX(item.getCoords()) - getCoordsMinX(background_image.getCoords()))
|
||
}
|
||
if (getCoordsMinY(background_image.getCoords()) - getCoordsMinY(item.getCoords()) > all_top) {
|
||
all_top = -(getCoordsMinY(item.getCoords()) - getCoordsMinY(background_image.getCoords()))
|
||
}
|
||
g3.push(fabric.util.object.clone(item))
|
||
if (idx != 0 && (objs1[idx - 1].type == 10 || objs1[idx - 1].type == 4)) {
|
||
continue //计数器 或 合成文字
|
||
}
|
||
if (idx != 0 && (objs1[idx - 1].type == 8 || objs1[idx - 1].type == 9)) {
|
||
continue //二维码 条形码
|
||
}
|
||
if (idx != 0 && objs1[idx - 1].type == 2) {
|
||
continue //合成图片
|
||
}
|
||
if (
|
||
idx != 0 &&
|
||
((objs1[idx - 1].type == 3 && (item.get('fill') == '#000000' || (item.get('fill') == '#ffffff' && false))) ||
|
||
(
|
||
objs1[idx - 1].type == 11
|
||
&&
|
||
(item.get("fill") == "#000000" || (item.get("fill") == "#ffffff" && false))
|
||
//圆形文字 && 黑色
|
||
) ||
|
||
//文字 && 黑色
|
||
(objs1[idx - 1].type == 5 && //矩形
|
||
(((item.get('fill') == '#000000' || item.get('fill') == '#ffffff') && item.get('stroke') == '') || //黑填充 透明边框
|
||
(item.get('fill') == '' && (item.get('stroke') == '#000000' || item.get('stroke') == '#ffffff')) || //透明填充 黑边框
|
||
((item.get('fill') == '#000000' || item.get('fill') == '#ffffff') && (item.get('stroke') == '#000000' || item.get('stroke') == '#ffffff')) || //黑填充 黑边框
|
||
((item.get('fill') == '#000000' || item.get('fill') == '#ffffff') && item.get('strokeWidth') == 0))) || //黑填充 0边框
|
||
(objs1[idx - 1].type == 6 && //圆形
|
||
(((item.get('fill') == '#000000' || item.get('fill') == '#ffffff') && item.get('stroke') == '') || //黑填充 透明边框
|
||
(item.get('fill') == '' && (item.get('stroke') == '#000000' || item.get('stroke') == '#ffffff')) || //透明填充 黑边框
|
||
((item.get('fill') == '#000000' || item.get('fill') == '#ffffff') && (item.get('stroke') == '#000000' || item.get('stroke') == '#ffffff')) || //黑填充 黑边框
|
||
((item.get('fill') == '#000000' || item.get('fill') == '#ffffff') && item.get('strokeWidth') == 0))) || //黑填充 0边框
|
||
(objs1[idx - 1].type == 7 && //直线
|
||
(item.get('stroke') == '#000000' || item.get('stroke') == '#ffffff')) ||
|
||
objs1[idx - 1].black == true) //勾选并入黑色图层
|
||
// (
|
||
// objs1[idx-1].type == 1//固定图片
|
||
// &&
|
||
// objs1[idx-1].black == true //勾选并入黑色图层
|
||
// )
|
||
) {
|
||
if (getCoordsMinX(background_image.getCoords()) - getCoordsMinX(item.getCoords()) > black_left) {
|
||
black_left = -(getCoordsMinX(item.getCoords()) - getCoordsMinX(background_image.getCoords()))
|
||
}
|
||
if (getCoordsMinY(background_image.getCoords()) - getCoordsMinY(item.getCoords()) > black_top) {
|
||
black_top = -(getCoordsMinY(item.getCoords()) - getCoordsMinY(background_image.getCoords()))
|
||
}
|
||
g5.push(fabric.util.object.clone(item))
|
||
continue //黑色文字 黑色矩形 黑色线条 黑色圆形
|
||
} else if (idx == 0) {
|
||
g5.push(fabric.util.object.clone(item))
|
||
}
|
||
|
||
if (getCoordsMinX(background_image.getCoords()) - getCoordsMinX(item.getCoords()) > left) {
|
||
left = -(getCoordsMinX(item.getCoords()) - getCoordsMinX(background_image.getCoords()))
|
||
}
|
||
if (getCoordsMinY(background_image.getCoords()) - getCoordsMinY(item.getCoords()) > top) {
|
||
top = -(getCoordsMinY(item.getCoords()) - getCoordsMinY(background_image.getCoords()))
|
||
}
|
||
g1.push(fabric.util.object.clone(item))
|
||
}
|
||
let url1 = new fabric.Group(g1).toDataURL({
|
||
height: 648,
|
||
width: 1012,
|
||
top: top / zoom,
|
||
left: left / zoom
|
||
})
|
||
|
||
// g3.push(img1)
|
||
let url3 = new fabric.Group(g3).toDataURL({
|
||
height: 648,
|
||
width: 1012,
|
||
top: all_top / zoom,
|
||
left: all_left / zoom
|
||
})
|
||
let url5 = new fabric.Group(g5).toDataURL({
|
||
height: 648,
|
||
width: 1012,
|
||
top: black_top / zoom,
|
||
left: black_left / zoom
|
||
})
|
||
let _objs2 = canvas2.getObjects()
|
||
let g2 = []
|
||
let g4 = []
|
||
let g6 = []
|
||
left = 0
|
||
top = 0
|
||
black_top = 0
|
||
black_left = 0
|
||
all_top = 0
|
||
all_left = 0
|
||
for (let item of _objs2) {
|
||
let idx = getIndex(item, canvas2)
|
||
if (getCoordsMinX(background_image.getCoords()) - getCoordsMinX(item.getCoords()) > all_left) {
|
||
all_left = -(getCoordsMinX(item.getCoords()) - getCoordsMinX(background_image.getCoords()))
|
||
}
|
||
if (getCoordsMinY(background_image.getCoords()) - getCoordsMinY(item.getCoords()) > all_top) {
|
||
all_top = -(getCoordsMinY(item.getCoords()) - getCoordsMinY(background_image.getCoords()))
|
||
}
|
||
g4.push(fabric.util.object.clone(item))
|
||
if (idx != 0 && (objs2[idx - 1].type == 10 || objs2[idx - 1].type == 4)) {
|
||
continue //黑色字或计数器 或 合成文字
|
||
}
|
||
if (idx != 0 && (objs2[idx - 1].type == 8 || objs2[idx - 1].type == 9)) {
|
||
continue //二维码 条形码
|
||
}
|
||
if (idx != 0 && objs2[idx - 1].type == 2) {
|
||
continue //合成图片
|
||
}
|
||
if (idx != 0 && objs2[idx - 1].type == 10) {
|
||
continue //合成图片
|
||
}
|
||
if (
|
||
idx != 0 &&
|
||
((objs2[idx - 1].type == 3 && (item.get('fill') == '#000000' || (item.get('fill') == '#ffffff' && false))) ||
|
||
(
|
||
objs2[idx - 1].type == 11
|
||
&&
|
||
(item.get("fill") == "#000000" || (item.get("fill") == "#ffffff" && false))
|
||
//圆形文字 && 黑色
|
||
) ||
|
||
//文字 && 黑色
|
||
(objs2[idx - 1].type == 5 && //矩形
|
||
(((item.get('fill') == '#000000' || item.get('fill') == '#ffffff') && item.get('stroke') == '') || //黑填充 透明边框
|
||
(item.get('fill') == '' && (item.get('stroke') == '#000000' || item.get('stroke') == '#ffffff')) || //透明填充 黑边框
|
||
((item.get('fill') == '#000000' || item.get('fill') == '#ffffff') && (item.get('stroke') == '#000000' || item.get('stroke') == '#ffffff')) || //黑填充 黑边框
|
||
((item.get('fill') == '#000000' || item.get('fill') == '#ffffff') && item.get('strokeWidth') == 0))) || //黑填充 0边框
|
||
(objs2[idx - 1].type == 6 && //圆形
|
||
(((item.get('fill') == '#000000' || item.get('fill') == '#ffffff') && item.get('stroke') == '') || //黑填充 透明边框
|
||
(item.get('fill') == '' && (item.get('stroke') == '#000000' || item.get('stroke') == '#ffffff')) || //透明填充 黑边框
|
||
((item.get('fill') == '#000000' || item.get('fill') == '#ffffff') && (item.get('stroke') == '#000000' || item.get('stroke') == '#ffffff')) || //黑填充 黑边框
|
||
((item.get('fill') == '#000000' || item.get('fill') == '#ffffff') && item.get('strokeWidth') == 0))) || //黑填充 0边框
|
||
(objs2[idx - 1].type == 7 && //直线
|
||
(item.get('stroke') == '#000000' || item.get('stroke') == '#ffffff')) ||
|
||
objs2[idx - 1].black == true) //勾选并入黑色图层
|
||
// (
|
||
// objs2[idx-1].type == 1//固定图片
|
||
// &&
|
||
// objs2[idx-1].black == true //勾选并入黑色图层
|
||
// )
|
||
) {
|
||
if (getCoordsMinX(background_image.getCoords()) - getCoordsMinX(item.getCoords()) > black_left) {
|
||
black_left = -(getCoordsMinX(item.getCoords()) - getCoordsMinX(background_image.getCoords()))
|
||
}
|
||
if (getCoordsMinY(background_image.getCoords()) - getCoordsMinY(item.getCoords()) > black_top) {
|
||
black_top = -(getCoordsMinY(item.getCoords()) - getCoordsMinY(background_image.getCoords()))
|
||
}
|
||
g6.push(fabric.util.object.clone(item))
|
||
continue //黑色文字 黑色矩形 黑色线条 黑色圆形
|
||
} else if (idx == 0) {
|
||
g6.push(fabric.util.object.clone(item))
|
||
}
|
||
if (getCoordsMinX(background_image.getCoords()) - getCoordsMinX(item.getCoords()) > left) {
|
||
left = -(getCoordsMinX(item.getCoords()) - getCoordsMinX(background_image.getCoords()))
|
||
}
|
||
if (getCoordsMinY(background_image.getCoords()) - getCoordsMinY(item.getCoords()) > top) {
|
||
top = -(getCoordsMinY(item.getCoords()) - getCoordsMinY(background_image.getCoords()))
|
||
}
|
||
g2.push(fabric.util.object.clone(item))
|
||
}
|
||
let url2 = new fabric.Group(g2).toDataURL({
|
||
height: 648,
|
||
width: 1012,
|
||
top: top / zoom,
|
||
left: left / zoom
|
||
})
|
||
let white_url1 = canvas1.getObjects()[0].toDataURL({
|
||
height: 648,
|
||
width: 1012
|
||
})
|
||
// g4.push(img2)
|
||
let url4 = new fabric.Group(g4).toDataURL({
|
||
height: 648,
|
||
width: 1012,
|
||
top: all_top / zoom,
|
||
left: all_left / zoom
|
||
})
|
||
let url6 = new fabric.Group(g6).toDataURL({
|
||
height: 648,
|
||
width: 1012,
|
||
top: black_top / zoom,
|
||
left: black_left / zoom
|
||
})
|
||
let white_url2 = canvas2.getObjects()[0].toDataURL({
|
||
height: 648,
|
||
width: 1012
|
||
})
|
||
//console.log(canvas.getObjects())
|
||
let w = document.body.clientWidth * 0.7 + 'px'
|
||
let h = (document.body.clientWidth * 0.7 - 40 - 0.06 * document.body.clientWidth * 0.7) * 0.62548 + 150 + 'px'
|
||
let h1 = (document.body.clientWidth * 0.7 - 40 - 0.06 * document.body.clientWidth * 0.7) * 0.62548 + 'px'
|
||
|
||
if ((document.body.clientWidth * 0.7 - 40 - 0.06 * document.body.clientWidth * 0.7) * 0.62548 > document.body.clientHeight) {
|
||
//高度超出,则按高度计算
|
||
h = document.body.clientHeight * 0.8 + 'px'
|
||
h1 = document.body.clientHeight * 0.8 - 150 + 'px'
|
||
w = ((document.body.clientHeight * 0.8 - 150) / 0.62548 + 40) / 0.94
|
||
}
|
||
let fs = require('fs');
|
||
const Buffer = require('buffer').Buffer;
|
||
const buffer3 = Buffer.from(url3.replace(/^data:image\/\w+;base64,/, ""), 'base64');
|
||
const printPath3 = path.join(exePath, 'print3.png');
|
||
fs.writeFileSync(printPath3, buffer3);
|
||
const buffer4 = Buffer.from(url4.replace(/^data:image\/\w+;base64,/, ""), 'base64');
|
||
const printPath4 = path.join(exePath, 'print4.png');
|
||
fs.writeFileSync(printPath4, buffer4);
|
||
// 创建 PDF 实例
|
||
const pdf = new jspdf.jsPDF({
|
||
orientation: 'landscape',
|
||
unit: 'px',
|
||
format: [1012, 648]
|
||
});
|
||
let btns = [language_str('output')]
|
||
if ((objs1.length != 0) & (objs2.length == 0)) {
|
||
//只有正面
|
||
let img = new Image()
|
||
img.src = printPath3
|
||
|
||
pdf.addImage(img, 'JPEG', 0, 0, 1012, 648)
|
||
btns.push('打印正面')
|
||
} else if ((objs1.length == 0) & (objs2.length != 0)) {
|
||
//只有背面
|
||
let img = new Image()
|
||
img.src = printPath4
|
||
|
||
pdf.addImage(img, 'JPEG', 0, 0, 1012, 648)
|
||
btns.push('打印背面')
|
||
} else {
|
||
let img = new Image()
|
||
img.src = printPath3
|
||
|
||
pdf.addImage(img, 'JPEG', 0, 0, 1012, 648)
|
||
|
||
pdf.addPage()
|
||
let img2 = new Image()
|
||
img2.src = printPath4
|
||
pdf.addImage(img2, 'JPEG', 0, 0, 1012, 648)
|
||
btns.push('打印正面')
|
||
btns.push('打印背面')
|
||
}
|
||
|
||
var pdfBlob = pdf.output('blob')
|
||
var pdfBuffer = pdf.output('arraybuffer')
|
||
|
||
layer.open({
|
||
type: 1,
|
||
area: [w, h],
|
||
title: language_str('display'), //不显示标题栏"预览"
|
||
shadeClose: true, //点击遮罩关闭
|
||
content: `
|
||
<div style="padding:20px;background-color:#1E252D;height:${h1};display:flex;align-items: center;overflow:hidden;">
|
||
<div style="/*position: relative;top: 50%;transform: translateY(-50%);*/display: flex;justify-content: space-between;">
|
||
<div class="rotate-div" id="displayImg1" angle="0">
|
||
<img src="${printPath3}" style="width:95%"/>
|
||
<div class="rotate-wrap" onclick="window.rotate('displayImg1')">
|
||
<img src="./public/images/rotate.png" style="height: 64px;width: 64px"/>
|
||
</div>
|
||
</div>
|
||
<div class="rotate-div" id="displayImg2" angle="0">
|
||
<img style="width:95%;/*margin-left:6%*/" src="${printPath4}"/>
|
||
<div class="rotate-wrap" onclick="window.rotate('displayImg2')">
|
||
<img src="./public/images/rotate.png" style="height: 64px;width: 64px"/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>`,
|
||
btn: btns, //'导出'
|
||
btn1: function (index, layero) {
|
||
savePdf(Buffer.from(pdfBuffer))
|
||
},
|
||
btn2: function () {
|
||
if (btns[1] === '打印正面') {
|
||
printJS({ printable: printPath3, type: 'image', style: 'img { width: 100%; height: auto; }' })
|
||
} else {
|
||
printJS({ printable: printPath4, type: 'image', style: 'img { width: 100%; height: auto; }' })
|
||
}
|
||
},
|
||
btn3: function () {
|
||
//打印背面
|
||
printJS({ printable: printPath4, type: 'image', style: 'img { width: 100%; height: auto; }' })
|
||
}
|
||
})
|
||
}
|
||
function output(callback = null, _save = save) {
|
||
// 类型改变
|
||
fabric.Image.fromURL('./public/images/op_2.png', function (i1) {
|
||
i1.left = background_image.left
|
||
i1.top = background_image.top
|
||
let img1 = i1
|
||
fabric.Image.fromURL('./public/images/op_2.png', function (i2) {
|
||
i2.left = background_image.left
|
||
i2.top = background_image.top
|
||
let img2 = i2
|
||
|
||
$('#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()
|
||
$('#component_type').text(language_str('bg')) //"背景"
|
||
canvas1.discardActiveObject().renderAll()
|
||
canvas2.discardActiveObject().renderAll()
|
||
let _objs1 = canvas1.getObjects()
|
||
let g1 = []
|
||
let g3 = []
|
||
let g5 = [] //黑色图层
|
||
let left = 0 //左裁剪
|
||
let top = 0 //顶裁剪
|
||
let black_left = 0 //黑色左裁剪
|
||
let black_top = 0 //黑色顶裁剪
|
||
let all_left = 0 //预览图左裁剪
|
||
let all_top = 0 //预览图顶裁剪
|
||
for (let item of _objs1) {
|
||
let idx = getIndex(item, canvas1)
|
||
//console.log("------");
|
||
//console.log(item.getCoords());
|
||
//console.log(getCoordsMinX(background_image.getCoords()));
|
||
//console.log(getCoordsMinX(item.getCoords()));
|
||
//console.log(getCoordsMinX(background_image.getCoords()) - getCoordsMinX(item.getCoords()));
|
||
//console.log("------");
|
||
|
||
if (getCoordsMinX(background_image.getCoords()) - getCoordsMinX(item.getCoords()) > all_left) {
|
||
all_left = -(getCoordsMinX(item.getCoords()) - getCoordsMinX(background_image.getCoords()))
|
||
}
|
||
if (getCoordsMinY(background_image.getCoords()) - getCoordsMinY(item.getCoords()) > all_top) {
|
||
all_top = -(getCoordsMinY(item.getCoords()) - getCoordsMinY(background_image.getCoords()))
|
||
}
|
||
g3.push(fabric.util.object.clone(item))
|
||
if (idx != 0 && (objs1[idx - 1].type == 10 || objs1[idx - 1].type == 4)) {
|
||
continue //计数器 或 合成文字
|
||
}
|
||
if (idx != 0 && (objs1[idx - 1].type == 8 || objs1[idx - 1].type == 9)) {
|
||
continue //二维码 条形码
|
||
}
|
||
if (idx != 0 && objs1[idx - 1].type == 2) {
|
||
continue //合成图片
|
||
}
|
||
if (
|
||
idx != 0 &&
|
||
((objs1[idx - 1].type == 3 && item.get('fill') == '#000000') ||
|
||
(
|
||
objs1[idx - 1].type == 11
|
||
&&
|
||
item.get("fill") == "#000000"
|
||
//圆形文字 && 黑色
|
||
) ||
|
||
//文字 && 黑色
|
||
(objs1[idx - 1].type == 5 && //矩形
|
||
(((item.get('fill') == '#000000' || item.get('fill') == '#ffffff') && item.get('stroke') == '') || //黑填充 透明边框
|
||
(item.get('fill') == '' && (item.get('stroke') == '#000000' || item.get('stroke') == '#ffffff')) || //透明填充 黑边框
|
||
((item.get('fill') == '#000000' || item.get('fill') == '#ffffff') && (item.get('stroke') == '#000000' || item.get('stroke') == '#ffffff')) || //黑填充 黑边框
|
||
((item.get('fill') == '#000000' || item.get('fill') == '#ffffff') && item.get('strokeWidth') == 0))) || //黑填充 0边框
|
||
(objs1[idx - 1].type == 6 && //圆形
|
||
(((item.get('fill') == '#000000' || item.get('fill') == '#ffffff') && item.get('stroke') == '') || //黑填充 透明边框
|
||
(item.get('fill') == '' && (item.get('stroke') == '#000000' || item.get('stroke') == '#ffffff')) || //透明填充 黑边框
|
||
((item.get('fill') == '#000000' || item.get('fill') == '#ffffff') && (item.get('stroke') == '#000000' || item.get('stroke') == '#ffffff')) || //黑填充 黑边框
|
||
((item.get('fill') == '#000000' || item.get('fill') == '#ffffff') && item.get('strokeWidth') == 0))) || //黑填充 0边框
|
||
(objs1[idx - 1].type == 7 && //直线
|
||
(item.get('stroke') == '#000000' || item.get('stroke') == '#ffffff')) ||
|
||
objs1[idx - 1].black == true) //勾选并入黑色图层
|
||
// ||
|
||
// (
|
||
// objs1[idx-1].type == 1//固定图片
|
||
// &&
|
||
// objs1[idx-1].black == true //勾选并入黑色图层
|
||
// )
|
||
) {
|
||
if (getCoordsMinX(background_image.getCoords()) - getCoordsMinX(item.getCoords()) > black_left) {
|
||
black_left = -(getCoordsMinX(item.getCoords()) - getCoordsMinX(background_image.getCoords()))
|
||
}
|
||
if (getCoordsMinY(background_image.getCoords()) - getCoordsMinY(item.getCoords()) > black_top) {
|
||
black_top = -(getCoordsMinY(item.getCoords()) - getCoordsMinY(background_image.getCoords()))
|
||
}
|
||
g5.push(fabric.util.object.clone(item))
|
||
continue //黑色文字 黑色矩形 黑色线条 黑色圆形
|
||
} else if (idx == 0) {
|
||
g5.push(fabric.util.object.clone(item))
|
||
}
|
||
if (getCoordsMinX(background_image.getCoords()) - getCoordsMinX(item.getCoords()) > left) {
|
||
left = -(getCoordsMinX(item.getCoords()) - getCoordsMinX(background_image.getCoords()))
|
||
}
|
||
if (getCoordsMinY(background_image.getCoords()) - getCoordsMinY(item.getCoords()) > top) {
|
||
top = -(getCoordsMinY(item.getCoords()) - getCoordsMinY(background_image.getCoords()))
|
||
}
|
||
g1.push(fabric.util.object.clone(item))
|
||
}
|
||
let url1 = new fabric.Group(g1).toDataURL({
|
||
height: 648,
|
||
width: 1012,
|
||
top: top / zoom,
|
||
left: left / zoom
|
||
})
|
||
g3.push(img1)
|
||
let url3 = new fabric.Group(g3).toDataURL({
|
||
height: 648,
|
||
width: 1012,
|
||
top: all_top / zoom,
|
||
left: all_left / zoom
|
||
})
|
||
let url5 = new fabric.Group(g5).toDataURL({
|
||
height: 648,
|
||
width: 1012,
|
||
top: black_top / zoom,
|
||
left: black_left / zoom
|
||
})
|
||
let _objs2 = canvas2.getObjects()
|
||
let g2 = []
|
||
let g4 = []
|
||
let g6 = [] //黑色图层
|
||
left = 0
|
||
top = 0
|
||
black_left = 0 //黑色左裁剪
|
||
black_top = 0 //黑色顶裁剪
|
||
all_left = 0 //黑色左裁剪
|
||
all_top = 0 //黑色顶裁剪
|
||
for (let item of _objs2) {
|
||
let idx = getIndex(item, canvas2)
|
||
if (getCoordsMinX(background_image.getCoords()) - getCoordsMinX(item.getCoords()) > all_left) {
|
||
all_left = -(getCoordsMinX(item.getCoords()) - getCoordsMinX(background_image.getCoords()))
|
||
}
|
||
if (getCoordsMinY(background_image.getCoords()) - getCoordsMinY(item.getCoords()) > all_top) {
|
||
all_top = -(getCoordsMinY(item.getCoords()) - getCoordsMinY(background_image.getCoords()))
|
||
}
|
||
g4.push(fabric.util.object.clone(item))
|
||
if (idx != 0 && (objs2[idx - 1].type == 10 || objs2[idx - 1].type == 4)) {
|
||
continue //计数器 或 合成文字
|
||
}
|
||
if (idx != 0 && (objs2[idx - 1].type == 8 || objs2[idx - 1].type == 9)) {
|
||
continue //二维码 条形码
|
||
}
|
||
if (idx != 0 && objs2[idx - 1].type == 2) {
|
||
continue //合成图片
|
||
}
|
||
if (
|
||
idx != 0 &&
|
||
((objs2[idx - 1].type == 3 && (item.get('fill') == '#000000' || (item.get('fill') == '#ffffff' && false))) ||
|
||
(
|
||
objs2[idx - 1].type == 11
|
||
&&
|
||
(item.get("fill") == "#000000" || (item.get("fill") == "#ffffff" && false))
|
||
//圆形文字 && 黑色
|
||
) ||
|
||
//文字 && 黑色
|
||
(objs2[idx - 1].type == 5 && //矩形
|
||
(((item.get('fill') == '#000000' || item.get('fill') == '#ffffff') && item.get('stroke') == '') || //黑填充 透明边框
|
||
(item.get('fill') == '' && (item.get('stroke') == '#000000' || item.get('stroke') == '#ffffff')) || //透明填充 黑边框
|
||
((item.get('fill') == '#000000' || item.get('fill') == '#ffffff') && (item.get('stroke') == '#000000' || item.get('stroke') == '#ffffff')) || //黑填充 黑边框
|
||
((item.get('fill') == '#000000' || item.get('fill') == '#ffffff') && item.get('strokeWidth') == 0))) || //黑填充 0边框
|
||
(objs2[idx - 1].type == 6 && //圆形
|
||
(((item.get('fill') == '#000000' || item.get('fill') == '#ffffff') && item.get('stroke') == '') || //黑填充 透明边框
|
||
(item.get('fill') == '' && (item.get('stroke') == '#000000' || item.get('stroke') == '#ffffff')) || //透明填充 黑边框
|
||
((item.get('fill') == '#000000' || item.get('fill') == '#ffffff') && (item.get('stroke') == '#000000' || item.get('stroke') == '#ffffff')) || //黑填充 黑边框
|
||
((item.get('fill') == '#000000' || item.get('fill') == '#ffffff') && item.get('strokeWidth') == 0))) || //黑填充 0边框
|
||
(objs2[idx - 1].type == 7 && //直线
|
||
(item.get('stroke') == '#000000' || item.get('stroke') == '#ffffff')) ||
|
||
objs2[idx - 1].black == true) //勾选并入黑色图层
|
||
// (
|
||
// objs2[idx-1].type == 1//固定图片
|
||
// &&
|
||
// objs2[idx-1].black == true //勾选并入黑色图层
|
||
// )
|
||
) {
|
||
if (getCoordsMinX(background_image.getCoords()) - getCoordsMinX(item.getCoords()) > black_left) {
|
||
black_left = -(getCoordsMinX(item.getCoords()) - getCoordsMinX(background_image.getCoords()))
|
||
}
|
||
if (getCoordsMinY(background_image.getCoords()) - getCoordsMinY(item.getCoords()) > black_top) {
|
||
black_top = -(getCoordsMinY(item.getCoords()) - getCoordsMinY(background_image.getCoords()))
|
||
}
|
||
g6.push(fabric.util.object.clone(item))
|
||
continue //黑色文字 黑色矩形 黑色线条 黑色圆形
|
||
} else if (idx == 0) {
|
||
g6.push(fabric.util.object.clone(item))
|
||
}
|
||
if (getCoordsMinX(background_image.getCoords()) - getCoordsMinX(item.getCoords()) > left) {
|
||
left = -(getCoordsMinX(item.getCoords()) - getCoordsMinX(background_image.getCoords()))
|
||
}
|
||
if (getCoordsMinY(background_image.getCoords()) - getCoordsMinY(item.getCoords()) > top) {
|
||
top = -(getCoordsMinY(item.getCoords()) - getCoordsMinY(background_image.getCoords()))
|
||
}
|
||
g2.push(fabric.util.object.clone(item))
|
||
}
|
||
let url2 = new fabric.Group(g2).toDataURL({
|
||
height: 648,
|
||
width: 1012,
|
||
top: top / zoom,
|
||
left: left / zoom
|
||
})
|
||
let white_url1 = canvas1.getObjects()[0].toDataURL({
|
||
height: 648,
|
||
width: 1012
|
||
})
|
||
g4.push(img2)
|
||
let url4 = new fabric.Group(g4).toDataURL({
|
||
height: 648,
|
||
width: 1012,
|
||
top: all_top / zoom,
|
||
left: all_left / zoom
|
||
})
|
||
let url6 = new fabric.Group(g6).toDataURL({
|
||
height: 648,
|
||
width: 1012,
|
||
top: black_top / zoom,
|
||
left: black_left / zoom
|
||
})
|
||
let white_url2 = canvas2.getObjects()[0].toDataURL({
|
||
height: 648,
|
||
width: 1012
|
||
})
|
||
//console.log(canvas.getObjects())
|
||
let w = document.body.clientWidth * 0.7 + 'px'
|
||
let h = (document.body.clientWidth * 0.7 - 40 - 0.06 * document.body.clientWidth * 0.7) * 0.62548 + 150 + 'px'
|
||
let h1 = (document.body.clientWidth * 0.7 - 40 - 0.06 * document.body.clientWidth * 0.7) * 0.62548 + 'px'
|
||
|
||
if ((document.body.clientWidth * 0.7 - 40 - 0.06 * document.body.clientWidth * 0.7) * 0.62548 > document.body.clientHeight) {
|
||
//高度超出,则按高度计算
|
||
h = document.body.clientHeight * 0.8 + 'px'
|
||
h1 = document.body.clientHeight * 0.8 - 150 + 'px'
|
||
w = ((document.body.clientHeight * 0.8 - 150) / 0.62548 + 40) / 0.94
|
||
}
|
||
|
||
let op = { frontColorPic: '', backColorPic: '', frontBlackPic: '', backBlackPic: '', frontData: [], backData: [], flag: 1, frontDisplayPic: url3, backDisplayPic: url4 }
|
||
if ((objs1.length != 0) & (objs2.length == 0)) {
|
||
op.flag = 2
|
||
} else if ((objs1.length == 0) & (objs2.length != 0)) {
|
||
op.flag = 3
|
||
}
|
||
op.frontColorPic = desEncrypt(url1)
|
||
op.backColorPic = desEncrypt(url2)
|
||
//op.frontBlPic = url5;
|
||
//op.backBlPic = url6;
|
||
op.frontBlackPic = desEncrypt(url5)
|
||
op.backBlackPic = desEncrypt(url6)
|
||
for (let item of _objs1) {
|
||
let idx = getIndex(item, canvas1)
|
||
if (idx == 0) continue //background-image
|
||
let type = objs1[idx - 1].type
|
||
if (type == 2) {
|
||
//out_pic
|
||
let xy = getAbsoluteXY(item)
|
||
op.frontData.push({
|
||
type: 1,
|
||
name: objs1[idx - 1].name,
|
||
FontColor: objs1[idx - 1].black ? '#000000' : '@',
|
||
transparency: item.get('opacity'),
|
||
x: parseInt((xy[0] - background_image1.left).toFixed(0)),
|
||
y: parseInt((xy[1] - background_image1.top).toFixed(0)),
|
||
h: parseInt((item.get('scaleY') * item.get('height')).toFixed(0)),
|
||
w: parseInt((item.get('scaleX') * item.get('width')).toFixed(0)),
|
||
rotate: parseInt(item.get('angle').toFixed(0))
|
||
})
|
||
} else if (type == 3) {
|
||
//text
|
||
/*2022-07-26 黑色并入黑色图层
|
||
if(item.get("fill") == "#000000"){
|
||
//纯黑
|
||
op.frontData.push({
|
||
"type" : 2,
|
||
"Text" : item.get("text"),
|
||
"FontFamily" : item.get("fontFamily"),
|
||
"FontSize" : parseInt(item.get("fontSize")),
|
||
"FontColor" : "#000000",
|
||
"FontBackgroudColor" : item.get("textBackgroundColor"),
|
||
"Bold" : item.get("fontWeight") == "bold",
|
||
"Underline" : item.get("underline"),
|
||
"Italic" : item.get("fontStyle") == "italic",
|
||
"Strikeout" : item.get("linethrough"),
|
||
"x" : parseInt((item.get("left") - background_image1.left).toFixed(0)),
|
||
"y" : parseInt((item.get("top") - background_image1.top).toFixed(0)),
|
||
"h" : parseInt((item.get("scaleY") * item.get("height")).toFixed(0)),
|
||
"w" : parseInt((item.get("scaleX") * item.get("width")).toFixed(0)),
|
||
"rotate" : parseInt(item.get("angle").toFixed(0))
|
||
});
|
||
}
|
||
*/
|
||
} else if (type == 11) {
|
||
//circle_text
|
||
op.frontData.push({
|
||
"type": 2,
|
||
"Text": item.get("text"),
|
||
"FontFamily": item.get("fontFamily"),
|
||
"FontSize": parseInt(item.get("fontSize")),
|
||
"FontColor": "#000000",
|
||
"FontBackgroudColor": item.get("textBackgroundColor"),
|
||
"Bold": item.get("fontWeight") == "bold",
|
||
"Underline": item.get("underline"),
|
||
"Italic": item.get("fontStyle") == "italic",
|
||
"Strikeout": item.get("linethrough"),
|
||
"x": parseInt((item.get("left") - background_image1.left).toFixed(0)),
|
||
"y": parseInt((item.get("top") - background_image1.top).toFixed(0)),
|
||
"h": parseInt((item.get("scaleY") * item.get("height")).toFixed(0)),
|
||
"w": parseInt((item.get("scaleX") * item.get("width")).toFixed(0)),
|
||
"rotate": parseInt(item.get("angle").toFixed(0)),
|
||
"circleCenter": objs1[idx - 1].circleCenter || 0
|
||
});
|
||
} else if (type == 4) {
|
||
//out_text
|
||
let xy = getAbsoluteXY(item)
|
||
op.frontData.push({
|
||
type: 3,
|
||
name: objs1[idx - 1].name,
|
||
FontFamily: item.get('fontFamily'),
|
||
DefaultText: item.get('text'),
|
||
FontBackgroudColor: item.get('textBackgroundColor'),
|
||
FontSize: parseInt(item.get('fontSize')),
|
||
FontColor: item.get('fill'),
|
||
Exceed: objs1[idx - 1].exceed,
|
||
AutoWrap: objs1[idx - 1].autoWrap,
|
||
FixSize: objs1[idx - 1].fixSize,
|
||
Bold: item.get('fontWeight') == 'bold',
|
||
Underline: item.get('underline'),
|
||
Italic: item.get('fontStyle') == 'italic',
|
||
Strikeout: item.get('linethrough'),
|
||
x: parseInt((xy[0] - background_image1.left).toFixed(0)),
|
||
y: parseInt((xy[1] - background_image1.top).toFixed(0)),
|
||
h: parseInt((item.get('scaleY') * item.get('height')).toFixed(0)),
|
||
w: parseInt((item.get('scaleX') * item.get('width')).toFixed(0)),
|
||
rotate: parseInt(item.get('angle').toFixed(0)),
|
||
align: objs1[idx - 1].align
|
||
})
|
||
} else if (type == 8) {
|
||
//二维码
|
||
let xy = getAbsoluteXY(item)
|
||
op.frontData.push({
|
||
type: 4,
|
||
name: objs1[idx - 1].name,
|
||
FontColor: objs1[idx - 1].color,
|
||
DefaultText: objs1[idx - 1].val,
|
||
x: parseInt((xy[0] - background_image1.left).toFixed(0)),
|
||
y: parseInt((xy[1] - background_image1.top).toFixed(0)),
|
||
h: parseInt((item.get('scaleY') * item.get('height')).toFixed(0)),
|
||
w: parseInt((item.get('scaleX') * item.get('width')).toFixed(0)),
|
||
rotate: parseInt(item.get('angle').toFixed(0))
|
||
})
|
||
} else if (type == 9) {
|
||
//条形码
|
||
let xy = getAbsoluteXY(item)
|
||
op.frontData.push({
|
||
type: 5,
|
||
name: objs1[idx - 1].name,
|
||
FontSize: parseInt(objs1[idx - 1].fontSize),
|
||
DefaultText: objs1[idx - 1].val,
|
||
HideText: objs1[idx - 1].show,
|
||
FontFamily: objs1[idx - 1].font,
|
||
FontColor: objs1[idx - 1].color,
|
||
x: parseInt((xy[0] - background_image1.left).toFixed(0)),
|
||
y: parseInt((xy[1] - background_image1.top).toFixed(0)),
|
||
h: parseInt((item.get('scaleY') * item.get('height')).toFixed(0)),
|
||
w: parseInt((item.get('scaleX') * item.get('width')).toFixed(0)),
|
||
rotate: parseInt(item.get('angle').toFixed(0))
|
||
})
|
||
} else if (type == 10) {
|
||
let xy = getAbsoluteXY(item)
|
||
op.frontData.push({
|
||
type: 6,
|
||
name: objs1[idx - 1].name,
|
||
FontFamily: item.get('fontFamily'),
|
||
FontSize: parseInt(item.get('fontSize')),
|
||
FontColor: item.get('fill'),
|
||
start: objs1[idx - 1].start,
|
||
add: parseInt(objs1[idx - 1].add),
|
||
x: parseInt((xy[0] - background_image1.left).toFixed(0)),
|
||
y: parseInt((xy[1] - background_image1.top).toFixed(0)),
|
||
h: parseInt((item.get('scaleY') * item.get('height')).toFixed(0)),
|
||
w: parseInt((item.get('scaleX') * item.get('width')).toFixed(0)),
|
||
rotate: parseInt(item.get('angle').toFixed(0))
|
||
})
|
||
}
|
||
}
|
||
//obj2
|
||
for (let item of _objs2) {
|
||
let idx = getIndex(item, canvas2)
|
||
if (idx == 0) continue //background-image
|
||
let type = objs2[idx - 1].type
|
||
if (type == 2) {
|
||
//out_pic
|
||
let xy = getAbsoluteXY(item)
|
||
op.backData.push({
|
||
type: 1,
|
||
name: objs2[idx - 1].name,
|
||
FontColor: objs2[idx - 1].black ? '#000000' : '@',
|
||
transparency: item.get('opacity'),
|
||
x: parseInt((xy[0] - background_image2.left).toFixed(0)),
|
||
y: parseInt((xy[1] - background_image2.top).toFixed(0)),
|
||
h: parseInt((item.get('scaleY') * item.get('height')).toFixed(0)),
|
||
w: parseInt((item.get('scaleX') * item.get('width')).toFixed(0)),
|
||
rotate: parseInt(item.get('angle').toFixed(0))
|
||
})
|
||
} else if (type == 3) {
|
||
//text
|
||
/*2022-07-26 黑色并入黑色图层
|
||
if(item.get("fill") == "#000000"){
|
||
//纯黑
|
||
op.backData.push({
|
||
"type" : 2,
|
||
"Text" : item.get("text"),
|
||
"FontFamily" : item.get("fontFamily"),
|
||
"FontSize" : parseInt(item.get("fontSize")),
|
||
"FontColor" : "#000000",
|
||
"FontBackgroudColor" : item.get("textBackgroundColor"),
|
||
"Bold" : item.get("fontWeight") == "bold",
|
||
"Underline" : item.get("underline"),
|
||
"Italic" : item.get("fontStyle") == "italic",
|
||
"Strikeout" : item.get("linethrough"),
|
||
"x" : parseInt((item.get("left") - background_image2.left).toFixed(0)),
|
||
"y" : parseInt((item.get("top") - background_image2.top).toFixed(0)),
|
||
"h" : parseInt((item.get("scaleY") * item.get("height")).toFixed(0)),
|
||
"w" : parseInt((item.get("scaleX") * item.get("width")).toFixed(0)),
|
||
"rotate" : parseInt(item.get("angle").toFixed(0))
|
||
});
|
||
}
|
||
*/
|
||
} else if (type == 11) {
|
||
//circle_text
|
||
op.backData.push({
|
||
"type": 2,
|
||
"Text": item.get("text"),
|
||
"FontFamily": item.get("fontFamily"),
|
||
"FontSize": parseInt(item.get("fontSize")),
|
||
"FontColor": "#000000",
|
||
"FontBackgroudColor": item.get("textBackgroundColor"),
|
||
"Bold": item.get("fontWeight") == "bold",
|
||
"Underline": item.get("underline"),
|
||
"Italic": item.get("fontStyle") == "italic",
|
||
"Strikeout": item.get("linethrough"),
|
||
"x": parseInt((item.get("left") - background_image2.left).toFixed(0)),
|
||
"y": parseInt((item.get("top") - background_image2.top).toFixed(0)),
|
||
"h": parseInt((item.get("scaleY") * item.get("height")).toFixed(0)),
|
||
"w": parseInt((item.get("scaleX") * item.get("width")).toFixed(0)),
|
||
"rotate": parseInt(item.get("angle").toFixed(0)),
|
||
"circleCenter": objs2[idx - 1].circleCenter || 0
|
||
});
|
||
} else if (type == 4) {
|
||
let xy = getAbsoluteXY(item)
|
||
op.backData.push({
|
||
type: 3,
|
||
name: objs2[idx - 1].name,
|
||
FontFamily: item.get('fontFamily'),
|
||
DefaultText: item.get('text'),
|
||
FontSize: parseInt(item.get('fontSize')),
|
||
FontBackgroudColor: item.get('textBackgroundColor'),
|
||
FontColor: item.get('fill'),
|
||
Exceed: objs2[idx - 1].exceed,
|
||
AutoWrap: objs2[idx - 1].autoWrap,
|
||
FixSize: objs2[idx - 1].fixSize,
|
||
Bold: item.get('fontWeight') == 'bold',
|
||
Underline: item.get('underline'),
|
||
Italic: item.get('fontStyle') == 'italic',
|
||
Strikeout: item.get('linethrough'),
|
||
x: parseInt((xy[0] - background_image2.left).toFixed(0)),
|
||
y: parseInt((xy[1] - background_image2.top).toFixed(0)),
|
||
h: parseInt((item.get('scaleY') * item.get('height')).toFixed(0)),
|
||
w: parseInt((item.get('scaleX') * item.get('width')).toFixed(0)),
|
||
rotate: parseInt(item.get('angle').toFixed(0)),
|
||
align: objs2[idx - 1].align
|
||
})
|
||
} else if (type == 8) {
|
||
//二维码
|
||
let xy = getAbsoluteXY(item)
|
||
op.backData.push({
|
||
type: 4,
|
||
name: objs2[idx - 1].name,
|
||
FontColor: objs2[idx - 1].color,
|
||
DefaultText: objs2[idx - 1].val,
|
||
x: parseInt((xy[0] - background_image2.left).toFixed(0)),
|
||
y: parseInt((xy[1] - background_image2.top).toFixed(0)),
|
||
h: parseInt((item.get('scaleY') * item.get('height')).toFixed(0)),
|
||
w: parseInt((item.get('scaleX') * item.get('width')).toFixed(0)),
|
||
rotate: parseInt(item.get('angle').toFixed(0))
|
||
})
|
||
} else if (type == 9) {
|
||
let xy = getAbsoluteXY(item)
|
||
op.backData.push({
|
||
type: 5,
|
||
name: objs2[idx - 1].name,
|
||
DefaultText: objs2[idx - 1].val,
|
||
HideText: objs1[idx - 1].show,
|
||
FontSize: parseInt(objs2[idx - 1].fontSize),
|
||
FontFamily: objs2[idx - 1].font,
|
||
FontColor: objs2[idx - 1].color,
|
||
x: parseInt((xy[0] - background_image2.left).toFixed(0)),
|
||
y: parseInt((xy[1] - background_image2.top).toFixed(0)),
|
||
h: parseInt((item.get('scaleY') * item.get('height')).toFixed(0)),
|
||
w: parseInt((item.get('scaleX') * item.get('width')).toFixed(0)),
|
||
rotate: parseInt(item.get('angle').toFixed(0))
|
||
})
|
||
} else if (type == 10) {
|
||
let xy = getAbsoluteXY(item)
|
||
op.backData.push({
|
||
type: 6,
|
||
name: objs2[idx - 1].name,
|
||
FontFamily: item.get('fontFamily'),
|
||
FontSize: parseInt(item.get('fontSize')),
|
||
FontColor: item.get('fill'),
|
||
start: parseInt(objs2[idx - 1].start),
|
||
add: parseInt(objs2[idx - 1].add),
|
||
x: parseInt((xy[0] - background_image2.left).toFixed(0)),
|
||
y: parseInt((xy[1] - background_image2.top).toFixed(0)),
|
||
h: parseInt((item.get('scaleY') * item.get('height')).toFixed(0)),
|
||
w: parseInt((item.get('scaleX') * item.get('width')).toFixed(0)),
|
||
rotate: parseInt(item.get('angle').toFixed(0))
|
||
})
|
||
}
|
||
}
|
||
_save(op, callback)
|
||
//return false 开启该代码可禁止点击该按钮关闭
|
||
})
|
||
})
|
||
}
|
||
$('#output').on('click', function () {
|
||
output(null, saveAs)
|
||
})
|
||
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();
|
||
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();
|
||
copySelection();
|
||
return;
|
||
}
|
||
// CTRL/CMD+V - 粘贴
|
||
if (isModifierKey && event.keyCode == 86 && event.target.nodeName == 'BODY') {
|
||
event.preventDefault();
|
||
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) {
|
||
let actObjs = canvas.getActiveObjects()
|
||
let allObjs = canvas.getObjects()
|
||
let flag = 0
|
||
for (let item of actObjs) {
|
||
if (item != allObjs[0]) {
|
||
let i = getIndex(item, canvas) //0是背景,所以从1开始,但objs不包含背景图片,故要-1
|
||
objs.splice(i - 1, 1)
|
||
canvas.remove(item)
|
||
flag = 1
|
||
}
|
||
}
|
||
updateList()
|
||
canvas.discardActiveObject()
|
||
if (flag == 1) {
|
||
recordState()
|
||
canvas.renderAll()
|
||
handleObjectSelected()
|
||
}
|
||
}
|
||
})
|
||
|
||
// 复制选中对象
|
||
function copySelection() {
|
||
const activeObjects = canvas.getActiveObjects();
|
||
|
||
if (!activeObjects || activeObjects.length === 0) {
|
||
layer.msg("未选中任何对象")
|
||
return;
|
||
}
|
||
|
||
// 存储原始对象用于克隆
|
||
clipboardData.objects = activeObjects;
|
||
}
|
||
|
||
// 粘贴对象
|
||
function pasteFromClipboard() {
|
||
if (!clipboardData.objects || clipboardData.objects.length === 0) {
|
||
layer.msg("剪贴板为空")
|
||
return;
|
||
}
|
||
|
||
// 克隆所有对象
|
||
fabric.util.enlivenObjects(
|
||
clipboardData.objects.map(obj => obj.toObject()),
|
||
clonedObjects => {
|
||
// 设置新位置(添加偏移)
|
||
clonedObjects.forEach((clone, index) => {
|
||
let idx = getIndex(clipboardData.objects[index], canvas)
|
||
clone.set({
|
||
left: clone.left + clipboardData.offset,
|
||
top: clone.top + clipboardData.offset,
|
||
evented: true
|
||
});
|
||
|
||
// 添加到画布
|
||
canvas.add(clone);
|
||
let tobj = { ...objs[idx - 1] }
|
||
if (tobj.name) tobj.name = tobj.name + objs.length
|
||
objs.push(tobj);
|
||
canvas.renderAll();
|
||
updateList();
|
||
recordState();
|
||
});
|
||
|
||
// 选中粘贴的对象
|
||
canvas.discardActiveObject();
|
||
const sel = new fabric.ActiveSelection(clonedObjects, {
|
||
canvas: canvas
|
||
});
|
||
canvas.setActiveObject(sel);
|
||
canvas.requestRenderAll();
|
||
selectObj(objs.length - 1);
|
||
// 增加下次偏移
|
||
clipboardData.offset += 10;
|
||
}
|
||
);
|
||
}
|