Konva调用stage.toJSON导出JSON时Text节点空格被移除问题咨询
stage.toJSON() Ah, I’ve dealt with this exact frustration before—Konva’s stage.toJSON() method automatically trims whitespace from all Text nodes by default, which wipes out leading/trailing spaces, line breaks, and intentional spacing you’ve added. Let’s break down why this happens and how to fix it.
Why This Happens
Under the hood, Konva’s default serialization for Text nodes runs text.trim() when generating the JSON output. This is a sensible default for most cases, but it breaks when you need to preserve raw text with whitespace.
Solutions
1. Globally Override Text Node Serialization
The cleanest fix is to override the toJSON method for all Konva.Text instances so it uses the untrimmed original text instead:
// Override the default Text toJSON behavior Konva.Text.prototype.toJSON = function() { // Get the base node JSON (without the trimmed text) const baseJson = Konva.Node.prototype.toJSON.call(this); // Replace the trimmed text with the original untrimmed value baseJson.attrs.text = this.text(); return baseJson; };
Now whenever you call stage.toJSON(), all Text nodes will retain their full original text, including whitespace. Just make sure to add this code before you start serializing your stage.
2. Fix Text Nodes Post-Serialization (Non-Global)
If you don’t want to modify Konva’s global behavior, you can serialize the stage first, then manually fix the Text node attributes in the resulting JSON object:
function serializeStageWithRawText(stage) { // Get the default serialized JSON object const stageJson = stage.toJSON(); // Recursively fix all Text nodes in the JSON function restoreTextWhitespace(nodes) { nodes.forEach(node => { if (node.className === 'Text') { // Find the corresponding live Text node in the stage const liveNode = stage.findOne(`#${node.id}`); // Replace the trimmed text with the original untrimmed value node.attrs.text = liveNode.text(); } // Recurse into child nodes if any if (node.children?.length) { restoreTextWhitespace(node.children); } }); } restoreTextWhitespace(stageJson.children); return stageJson; } // Usage example const rawStageJson = serializeStageWithRawText(yourKonvaStage); const jsonString = JSON.stringify(rawStageJson);
This approach targets only the serialized data without altering Konva’s core methods. It finds each Text node in the live stage and replaces the trimmed text in the JSON with the original value.
3. Use stage.toObject() and Custom Serialization
Another option is to use stage.toObject() (which returns a plain JavaScript object instead of a JSON string) and modify the text attributes before converting to JSON:
const stageObj = yourKonvaStage.toObject(); // Recursively update Text node text attributes function fixTextAttributes(obj) { if (obj.className === 'Text') { // Get the live node to fetch the untrimmed text const liveNode = yourKonvaStage.findOne(`#${obj.id}`); obj.attrs.text = liveNode.text(); } if (obj.children?.length) { obj.children.forEach(fixTextAttributes); } } fixTextAttributes(stageObj); const jsonString = JSON.stringify(stageObj);
Important Notes
- When loading the JSON back into Konva (via
Konva.Node.create(jsonString)), make sure your Text nodes have the correctwhiteSpaceproperty set (e.g.,whiteSpace: 'pre'or'pre-wrap') if you need to preserve line breaks and spacing visually. - If you’re using custom Text subclasses, adjust the solutions above to target your specific class instead of
Konva.Text.
内容的提问来源于stack exchange,提问作者amiel

