Giới thiệu
Chào các bạn, mình là Maneshwar. Mình đang làm việc trên FreeDevTools, nơi cung cấp một kho công cụ cho tất cả các lập trình viên — một nền tảng miễn phí, mã nguồn mở giúp các nhà phát triển nhanh chóng tìm và sử dụng công cụ mà không cần phải tìm kiếm khắp nơi trên internet.
Khi bạn xây dựng một thư viện biểu tượng SVG, một tính năng quan trọng là khả năng xuất biểu tượng dưới dạng PNG. PNG vẫn là định dạng phổ biến cho nhiều lập trình viên và nhà thiết kế vì chúng được hỗ trợ rộng rãi và dễ dàng sử dụng trong các ứng dụng, tài liệu hoặc công cụ thiết kế.
Thay vì dựa vào chuyển đổi phía máy chủ hoặc các trình chỉnh sửa đồ họa bên ngoài, chúng ta có thể thực hiện điều này hoàn toàn trong trình duyệt.
Hãy cùng khám phá Konva.js — một framework canvas 2D giúp việc vẽ, biến đổi và xuất đồ họa trở nên đơn giản hơn bao giờ hết.
Trong dự án của chúng tôi, chúng tôi đã triển khai hai tính năng hữu ích cho thư viện biểu tượng:
- Sao chép dưới dạng PNG → đặt phiên bản PNG của một SVG trực tiếp vào clipboard.
- Tải xuống dưới dạng PNG → cho phép người dùng chọn kích thước (32px → 512px) và tải xuống ngay lập tức.
👉 Thực hiện đầy đủ tại đây:
- CopyPngButton.tsx
- DownloadPngButton.tsx
Tại sao chọn Konva.js?
Về lý thuyết, bạn có thể vẽ một SVG vào một <canvas> bằng cách sử dụng Canvas API. Nhưng Konva cung cấp một lớp trừu tượng thân thiện với lập trình viên hơn với:
- Stages & Layers → cách tổ chức hình vẽ rõ ràng.
- Image.fromURL → dễ dàng tải hình ảnh & SVG.
- Stage.toDataURL → xuất sang PNG hoặc JPEG chỉ trong một lệnh gọi.
- Các biến đổi tích hợp (thu nhỏ, vị trí, xoay) mà không cần viết mã toán học phức tạp.
Điều này khiến nó trở nên hoàn hảo cho việc vẽ biểu tượng, nơi độ chính xác và chất lượng rất quan trọng.
Thiết lập một Konva Stage
Bước đầu tiên trong quy trình của chúng ta là tạo một Konva stage ẩn. Vì người dùng không cần thấy quá trình vẽ, chúng ta sẽ gắn nó ra ngoài màn hình:
javascript
const stage = new Konva.Stage({
container: container, // <div> tạm thời ẩn
width: size,
height: size,
});
const layer = new Konva.Layer();
stage.add(layer);
📖 Tài liệu về Konva Stage
📖 Tài liệu về Konva Layer
Hãy nghĩ về một Stage như một canvas gốc, và một Layer như một tấm trong suốt mà bạn có thể vẽ lên. Bạn có thể chồng nhiều layer nếu cần.
Tải SVG
Tiếp theo, chúng ta tải chuỗi SVG thô vào Konva stage. Vì Konva làm việc với các node hình ảnh, chúng ta trước tiên sẽ chuyển đổi SVG thành một data URL:
javascript
const svgDataUrl = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svgData);
Konva.Image.fromURL(svgDataUrl, (imageNode) => {
// thêm imageNode vào layer
});
📖 Tài liệu về Konva.Image.fromURL
Mẹo: hãy chắc chắn rằng chuỗi SVG của bạn có thuộc tính
xmlns(xmlns="http://www.w3.org/2000/svg"). Nếu không, một số trình duyệt có thể không thể hiển thị.
Tỉ lệ & Căn giữa biểu tượng
Các biểu tượng hiếm khi có tỷ lệ vuông hoàn hảo. Nếu chúng ta chỉ kéo dài chúng, chúng sẽ bị biến dạng. Để giữ tỷ lệ khung hình, chúng ta tính toán và vừa vặn hình ảnh vào ~80% của stage:
javascript
const imageAspect = imageNode.width() / imageNode.height();
if (imageAspect > 1) {
imageWidth = size * 0.8;
imageHeight = imageWidth / imageAspect;
} else {
imageHeight = size * 0.8;
imageWidth = imageHeight * imageAspect;
}
imageNode.setAttrs({
x: (size - imageWidth) / 2,
y: (size - imageHeight) / 2,
width: imageWidth,
height: imageHeight,
});
Với cách này:
- Các biểu tượng rộng thu nhỏ theo chiều ngang.
- Các biểu tượng cao thu nhỏ theo chiều dọc.
- Mọi thứ đều được căn giữa trong PNG cuối cùng.
Xuất sang PNG
Phép màu diễn ra với phương thức toDataURL của Konva:
javascript
const dataURL = stage.toDataURL({
mimeType: 'image/png',
quality: 1,
pixelRatio: 2, // Xuất độ phân giải cao
});
📖 Tài liệu về Stage.toDataURL
Vào thời điểm này, chúng ta có một chuỗi PNG base64. Từ đây, chúng ta có thể:
- Đường dẫn clipboard → biến nó thành một
Blob, bọc vớiClipboardItem, và sử dụngnavigator.clipboard.write(). - Đường dẫn tải xuống → tạo một liên kết
<a>tạm thời, thiết lậphref = dataURL, và kích hoạtclick().
Thế là xong!
👉 Mã đầy đủ tại đây:
- Tải xuống PNG → cho phép người dùng chọn độ phân giải đầu ra (32px–512px) và lưu dưới dạng PNG.
Kết luận
Chỉ với một vài primitive của Konva (Stage, Layer, Image.fromURL, Stage.toDataURL), bạn có thể chuyển đổi các biểu tượng SVG thô thành PNG đẹp và trong suốt ngay trong trình duyệt.
Lợi ích của phương pháp này:
- 100% phía khách hàng → không có máy chủ, không có độ trễ.
- Hỗ trợ clipboard + tải xuống.
- Duy trì được độ sắc nét & trong suốt.
- Dễ dàng mở rộng (bạn có thể thêm nền, hình dạng hoặc biến đổi).
Nếu bạn đang xây dựng các công cụ xung quanh SVG, Konva là lựa chọn tuyệt vời, đủ linh hoạt cho các ứng dụng vẽ hoàn chỉnh nhưng đủ nhẹ để sử dụng cho các tiện ích xuất đơn giản như của chúng tôi.
Mình đang xây dựng cho FreeDevTools. Một bộ công cụ tập trung vào UI/UX được thiết kế để đơn giản hóa quy trình làm việc, tiết kiệm thời gian và giảm bớt sự khó khăn trong việc tìm kiếm công cụ/tài liệu.
Mọi phản hồi hoặc đóng góp đều được hoan nghênh!
Nó đã có sẵn trực tuyến, mã nguồn mở và sẵn sàng cho bất kỳ ai sử dụng.
👉 Kiểm tra tại: FreeDevTools
⭐ Đánh dấu nó trên GitHub: freedevtools
Hãy cùng nhau làm cho nó tốt hơn!