插件窝 干货文章 如何用fabric.js构建一个支持标尺、拖拽和打印功能的在线可视化设计编辑器?

如何用fabric.js构建一个支持标尺、拖拽和打印功能的在线可视化设计编辑器?

Canvas tick style document 925    来源:    2025-03-24

要使用Fabric.js构建一个支持标尺、拖拽和打印功能的在线可视化设计编辑器,你可以按照以下步骤进行:

1. 引入Fabric.js库

首先,你需要在HTML文件中引入Fabric.js库。你可以通过CDN或下载本地文件来引入。

<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/5.2.4/fabric.min.js"></script>

2. 创建Canvas

在HTML中创建一个<canvas>元素,用于渲染设计内容。

<canvas id="design-canvas" width="800" height="600"></canvas>

3. 初始化Fabric.js Canvas

在JavaScript中初始化Fabric.js的Canvas对象。

const canvas = new fabric.Canvas('design-canvas', {
    isDrawingMode: false, // 禁用绘图模式
    selection: true,      // 启用选择功能
    preserveObjectStacking: true // 保持对象堆叠顺序
});

4. 添加标尺功能

标尺功能可以通过在Canvas周围绘制标尺来实现。你可以使用HTML和CSS来创建标尺,并通过JavaScript来更新标尺的刻度。

<div id="ruler-x" class="ruler"></div>
<div id="ruler-y" class="ruler"></div>
.ruler {
    position: absolute;
    background-color: #f0f0f0;
    z-index: 1;
}

#ruler-x {
    width: 800px;
    height: 20px;
    top: 0;
    left: 20px;
}

#ruler-y {
    width: 20px;
    height: 600px;
    top: 20px;
    left: 0;
}
function updateRulers() {
    const rulerX = document.getElementById('ruler-x');
    const rulerY = document.getElementById('ruler-y');

    // 更新水平标尺
    rulerX.innerHTML = '';
    for (let i = 0; i < 800; i += 50) {
        const tick = document.createElement('div');
        tick.style.position = 'absolute';
        tick.style.left = `${i}px`;
        tick.style.width = '1px';
        tick.style.height = '10px';
        tick.style.backgroundColor = '#000';
        rulerX.appendChild(tick);
    }

    // 更新垂直标尺
    rulerY.innerHTML = '';
    for (let i = 0; i < 600; i += 50) {
        const tick = document.createElement('div');
        tick.style.position = 'absolute';
        tick.style.top = `${i}px`;
        tick.style.width = '10px';
        tick.style.height = '1px';
        tick.style.backgroundColor = '#000';
        rulerY.appendChild(tick);
    }
}

// 初始化标尺
updateRulers();

5. 实现拖拽功能

Fabric.js默认支持对象的拖拽功能。你可以通过设置对象的selectableevented属性来控制对象是否可以被选择和拖拽。

const rect = new fabric.Rect({
    left: 100,
    top: 100,
    width: 100,
    height: 100,
    fill: 'red',
    selectable: true,
    evented: true
});

canvas.add(rect);

6. 实现打印功能

打印功能可以通过将Canvas内容导出为图像,然后调用浏览器的打印功能来实现。

function printCanvas() {
    const dataURL = canvas.toDataURL({
        format: 'png',
        quality: 1.0
    });

    const printWindow = window.open('', '_blank');
    printWindow.document.write(`<img src="${dataURL}" onload="window.print()">`);
    printWindow.document.close();
}

// 添加打印按钮
const printButton = document.createElement('button');
printButton.innerText = 'Print';
printButton.onclick = printCanvas;
document.body.appendChild(printButton);

7. 完整代码示例

以下是一个完整的代码示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Fabric.js Design Editor</title>
    <style>
        .ruler {
            position: absolute;
            background-color: #f0f0f0;
            z-index: 1;
        }

        #ruler-x {
            width: 800px;
            height: 20px;
            top: 0;
            left: 20px;
        }

        #ruler-y {
            width: 20px;
            height: 600px;
            top: 20px;
            left: 0;
        }

        canvas {
            border: 1px solid #ccc;
            margin-top: 20px;
            margin-left: 20px;
        }
    </style>
</head>
<body>
    <div id="ruler-x" class="ruler"></div>
    <div id="ruler-y" class="ruler"></div>
    <canvas id="design-canvas" width="800" height="600"></canvas>
    <button id="print-button">Print</button>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/5.2.4/fabric.min.js"></script>
    <script>
        const canvas = new fabric.Canvas('design-canvas', {
            isDrawingMode: false,
            selection: true,
            preserveObjectStacking: true
        });

        function updateRulers() {
            const rulerX = document.getElementById('ruler-x');
            const rulerY = document.getElementById('ruler-y');

            rulerX.innerHTML = '';
            for (let i = 0; i < 800; i += 50) {
                const tick = document.createElement('div');
                tick.style.position = 'absolute';
                tick.style.left = `${i}px`;
                tick.style.width = '1px';
                tick.style.height = '10px';
                tick.style.backgroundColor = '#000';
                rulerX.appendChild(tick);
            }

            rulerY.innerHTML = '';
            for (let i = 0; i < 600; i += 50) {
                const tick = document.createElement('div');
                tick.style.position = 'absolute';
                tick.style.top = `${i}px`;
                tick.style.width = '10px';
                tick.style.height = '1px';
                tick.style.backgroundColor = '#000';
                rulerY.appendChild(tick);
            }
        }

        updateRulers();

        const rect = new fabric.Rect({
            left: 100,
            top: 100,
            width: 100,
            height: 100,
            fill: 'red',
            selectable: true,
            evented: true
        });

        canvas.add(rect);

        function printCanvas() {
            const dataURL = canvas.toDataURL({
                format: 'png',
                quality: 1.0
            });

            const printWindow = window.open('', '_blank');
            printWindow.document.write(`<img src="${dataURL}" onload="window.print()">`);
            printWindow.document.close();
        }

        document.getElementById('print-button').onclick = printCanvas;
    </script>
</body>
</html>

8. 进一步优化

  • 缩放和滚动:你可以通过监听鼠标滚轮事件来实现Canvas的缩放和滚动功能。
  • 网格对齐:可以在Canvas上绘制网格线,并实现对象的对齐功能。
  • 保存和加载:可以将Canvas的内容保存为JSON,并在需要时加载回来。

通过这些步骤,你可以构建一个功能丰富的在线可视化设计编辑器。