Вопрос или проблема
Я использую библиотеку signature-pad с livewire и alpine.
Я поместил элемент canvas в модальное окно, и элемент отображается без проблем. Например, я установил фон синего цвета и рукописный текст желтого цвета.
Проблема возникает, когда я сохраняю изображение. Когда оно отправляется в компонент и сохраняется в приложении, изображение имеет только синий фон, и желтое написание не передается при генерации сохраненного изображения, остается только синее изображение.
представление
<x-jet-dialog-modal wire:model="showJetstreamModalCreate" maxWidth="lg"
class="modal-dialog-centered modal-dialog-scrollable">
<x-slot name="title">Новая Анамнез</x-slot>
<x-slot name="content">
<div class="modal-body">
<div class="mt-2">
Запросить подпись:
<div x-data="signaturePad()">
<canvas x-ref="signature_canvas" style="border: 1px solid #cecaca;"></canvas>
</div>
</div>
</div>
</x-slot>
<x-slot name="footer">
<x-jet-secondary-button wire:click="$toggle('showJetstreamModalCreate')">
Закрыть
</x-jet-secondary-button>
<x-jet-button wire:click.prevent="create" wire:loading.remove>
Сохранить Анамнез
</x-jet-button>
<x-jet-button wire:loading wire:target="create">
Обрабатывается...
</x-jet-button>
</x-slot>
</x-jet-dialog-modal>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/signature_pad.umd.min.js"></script>
<script>
document.addEventListener('alpine:init', () => {
Alpine.data('signaturePad', () => ({
signaturePadInstance: null,
init() {
this.signaturePadInstance = new SignaturePad(this.$refs.signature_canvas, {
minWidth: 5,
maxWidth: 10,
backgroundColor: 'rgb(5,5,255)',
penColor: "rgb(255, 255, 25)"
});
@this.set('signature', this.signaturePadInstance.toDataURL('image/png'));
}
}))
})
</script>
компонент
<?php
namespace App\Http\Livewire\Patient\Anamnesis;
use Illuminate\Support\Str;
use Livewire\Component;
use Illuminate\Support\Facades\Storage;
class Create extends Component
{
public $signature;
public function render()
{
return view('livewire.patient.anamnesis.create');
}
public function create(){
Storage::disk('public')->put('signature.png', base64_decode(Str::of($this->signature)->after(',')));
}
}
Я удалил много кода из обоих файлов, отправив только то, что необходимо для функциональности, которую я показываю.
Как вы можете видеть, у меня есть элемент canvas, и я захватываю подпись с помощью alpine, чтобы отправить ее в компонент Livewire, но только фон отображается в сгенерированном изображении без написания.
Ответ или решение
Проблема, с которой вы столкнулись, заключается в том, что данные изображения, полученные от компонента SignaturePad
, не обновляются должным образом, прежде чем вы их отправляете на сервер. Ваша текущая реализация передает данные в Livewire сразу после инициализации signaturePadInstance
, до того, как пользователь успевает нарисовать что-либо на холсте.
Для того чтобы сохранить как фон, так и подпись, вам необходимо обновить код так, чтобы данные изображения обновлялись в момент, когда пользователь нажимает кнопку "Сохранить". Вот шаги, которые вы можете предпринять для решения вашей проблемы:
-
Переместите логику сохранения подписи в метод кнопки "Сохранить". Это гарантирует, что вы сохраните актуальную подпись в момент нажатия кнопки.
-
Обновите ваше событие, чтобы получать новое изображение только при его сохранении.
Используя эти рекомендации, ваш модифицированный код будет выглядеть следующим образом:
Изменения в файле JavaScript:
<script>
document.addEventListener('alpine:init', () => {
Alpine.data('signaturePad', () => ({
signaturePadInstance: null,
init() {
this.signaturePadInstance = new SignaturePad(this.$refs.signature_canvas, {
minWidth: 5,
maxWidth: 10,
backgroundColor: 'rgb(5,5,255)', // Цвет фона
penColor: "rgb(255, 255, 25)" // Цвет подписи
});
},
save() {
// Сохраняем текущую подпись как DataURL
if (this.signaturePadInstance.isEmpty()) {
alert("Пожалуйста, подпишите перед сохранением.");
} else {
// Получаем DataURL и обновляем переменную в Livewire
const dataURL = this.signaturePadInstance.toDataURL('image/png');
@this.set('signature', dataURL); // Устанавливаем значение переменной в Livewire
}
}
}))
})
</script>
Изменения в компоненте Livewire:
В методе create
не потребуется изменения, однако убедитесь, что он срабатывает после успешного сохранения подписи.
Изменения в модальном окне:
Дополнив ваш вид, метод кнопки "Сохранить" должен выглядеть следующим образом:
<x-jet-button wire:click.prevent="create" wire:loading.remove x-on:click="save">
Salvar Anamnese
</x-jet-button>
Итог
Теперь, когда пользователь нажимает кнопку "Сохранить", функция save
из вашего Alpine компонента будет вызываться и собирать актуальные данные из холста, прежде чем они будут отправлены на сервер с помощью Livewire. Это должно устранить проблему, когда изображение сохранялось только с фоном, без подписи. Теперь при сохранении должно сохраняться как изображение с фоном, так и с подписанным компонентом.