После добавления изображения на холст (и разрешения Fabric.js сделать это) я хочу изменить URL-адрес изображения.
Проблема в том, что работает только часть. После того, как я нажимаю кнопку (что приводит к изменению кодировки), изображение не отображается. Просто место, где был образ, которым я все еще могу манипулировать. Когда я манипулирую изображением, оно внезапно становится видимым. Однако хотелось бы сразу увидеть изображение.
В качестве примера
<button id = "change">Change</button>
<canvas id = "canvas" class = "myStage" width = "800" height = "400"></canvas>
<script>
"use strict";
const canvas = new fabric.Canvas("canvas", { containerClass: "myStage" });
const changeBtn = document.getElementById("change");
changeBtn.addEventListener("click", changeSelected);
let _selectedInstrument = null;
fabric.Image.fromURL("https://stackoverflow.design/assets/img/logos/teams/teams-logo-compact.svg", function (img) {
canvas.add(img);
img.on("mouseup", function (e) {
_selectedInstrument = e;
}
);
});
//this has the same result as the uncommented method beneath
//function changeSelected() {
// fabric.util.loadImage(
// "https://stackoverflow.design/assets/img/logos/so/logo-stackoverflow.svg",
// function (img) {
// return _selectedInstrument.currentTarget.setElement(img);
// }, this);
//}
function changeSelected() {
_selectedInstrument.target._element.src =
"https://stackoverflow.design/assets/img/logos/so/logo-stackoverflow.svg";
canvas.renderAll();
}
Чтобы использовать демо-версию в Fiddle, сначала щелкните логотип «SO For Teams» (чтобы выбрать его), а затем нажмите кнопку «Изменить». Затем перетащите пустое изображение, и оно внезапно отобразит логотип stackoverflow.
Я бы предпочел, чтобы изображение просто изменилось, без необходимости его затем перемещать.
Я попробовал 2 разных подхода (согласно моему коду выше). Я звоню renderAll() согласно документации Fabric.js.
Я не уверен, что я делаю неправильно



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


При настройке нового изображения src браузер должен загрузить данные изображения. Немедленно вызвав canvas.renderAll(), вы повторно визуализируете холст, пока новое изображение еще загружается.
Вместо этого добавьте прослушиватель событий «загрузки» к созданному изображению и повторно визуализируйте холст только тогда, когда новое изображение будет готово.
<button id = "change">Change</button>
<canvas id = "canvas" class = "myStage" width = "800" height = "400"></canvas>
<script>
"use strict";
const canvas = new fabric.Canvas("canvas", { containerClass: "myStage" });
const changeBtn = document.getElementById("change");
changeBtn.addEventListener("click", changeSelected);
let _selectedInstrument = null;
fabric.Image.fromURL("https://stackoverflow.design/assets/img/logos/teams/teams-logo-compact.svg", function (img) {
canvas.add(img);
img._element.addEventListener("load", canvas.renderAll.bind(canvas)); // <-- automatically re-renders the canvas when a new image is ready
img.on("mouseup", function (e) {
_selectedInstrument = e;
});
});
function changeSelected() {
_selectedInstrument.target._element.src =
"https://stackoverflow.design/assets/img/logos/so/logo-stackoverflow.svg";
// canvas.renderAll(); <-- Removed, is called when the new image has been loaded
}
Это потрясающе, и я полностью понимаю, почему ваше объяснение не сработало. Спасибо