Изображение, созданное с помощью SignaturePad, не сохраняет рукописный текст, а только фон [закрыто]

Вопрос или проблема

Я использую библиотеку 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, до того, как пользователь успевает нарисовать что-либо на холсте.

Для того чтобы сохранить как фон, так и подпись, вам необходимо обновить код так, чтобы данные изображения обновлялись в момент, когда пользователь нажимает кнопку "Сохранить". Вот шаги, которые вы можете предпринять для решения вашей проблемы:

  1. Переместите логику сохранения подписи в метод кнопки "Сохранить". Это гарантирует, что вы сохраните актуальную подпись в момент нажатия кнопки.

  2. Обновите ваше событие, чтобы получать новое изображение только при его сохранении.

Используя эти рекомендации, ваш модифицированный код будет выглядеть следующим образом:

Изменения в файле 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. Это должно устранить проблему, когда изображение сохранялось только с фоном, без подписи. Теперь при сохранении должно сохраняться как изображение с фоном, так и с подписанным компонентом.

Оцените материал
Добавить комментарий

Капча загружается...