Fabric.js KitchenSink切换i-text对象时控件未更新的问题咨询
Got it, let's tackle this annoying sync problem with the i-text controls in Fabric.js KitchenSink. The core issue here is that the text controls aren't properly resetting their association when you switch between i-text objects directly—they're still tied to the first one you selected, leading to overwrites and stale data.
Here's how to fix it by leveraging Fabric.js's selection events to keep the controls in sync with the currently selected object:
Step 1: Track the currently bound text object
First, we'll keep a reference to the i-text object that's currently linked to the controls, so we can clean up old bindings when switching.
let currentTextObject = null; // Grab the text input element from the "Text specific controls" section // Update this selector to match the actual input ID in KitchenSink const textControlInput = document.querySelector('#text-control-input');
Step 2: Listen for selection changes
Fabric.js emits events when the selected object changes. We'll hook into selection:created (when you first select an object) and selection:updated (when you switch to another selected object) to update our controls. We'll also handle selection:cleared to reset the controls when nothing is selected.
// Handle selection of new objects canvas.on('selection:created selection:updated', (e) => { const selectedObj = e.target; // Only process i-text objects if (selectedObj?.type === 'i-text') { // Clean up old bindings if there's a previous text object if (currentTextObject) { currentTextObject.off('text:changed', syncInputToObject); } // Update our reference to the new text object currentTextObject = selectedObj; // Sync the control input with the new object's text textControlInput.value = currentTextObject.text; // Bind events to keep input and object in sync // 1. Update input when the object's text changes (e.g., editing directly on canvas) currentTextObject.on('text:changed', syncInputToObject); // 2. Update the object when the input's text changes textControlInput.oninput = () => { currentTextObject.setText(textControlInput.value); canvas.renderAll(); }; } else { // If selected object isn't i-text, reset controls resetTextControls(); } }); // Handle when no objects are selected canvas.on('selection:cleared', resetTextControls);
Step 3: Add helper functions for sync and reset
These functions will keep our code clean and reusable:
// Sync the input field with the current text object's content function syncInputToObject() { if (currentTextObject && textControlInput.value !== currentTextObject.text) { textControlInput.value = currentTextObject.text; } } // Reset controls and clean up bindings function resetTextControls() { if (currentTextObject) { currentTextObject.off('text:changed', syncInputToObject); currentTextObject = null; } textControlInput.value = ''; textControlInput.oninput = null; }
How this works
- Every time you select a new i-text object, we first disconnect any existing links to the old object (so it stops listening for changes).
- We then sync the control input with the new object's text and set up two-way binding: changes in the input update the object, and changes to the object (like editing directly on the canvas) update the input.
- When you deselect all objects or select a non-i-text object, the controls reset to avoid stale state.
Just drop this code into the KitchenSink's console or integrate it into the existing control logic, and you'll see the text controls now properly update when switching between i-text objects—no more overwriting or locked state!
内容的提问来源于stack exchange,提问作者snucky

