live() deletes my cropper instance, custom field
I made a form field that incorporates Cropper.js to select part of an image and give back the coordinates to four other input form fields. This works perfectly so far, but after the very first update to the state, the Cropper instance seems to completely disappear... When removing live(), this doesn't happen, but obviously the other four form fields are no longer being updated.
Does anyone know what the issue is here? Thank you!
image 1: without live()
image 2: with live(), cropper instance dissappeared
Field:
Class:
Blade:
Script:
Does anyone know what the issue is here? Thank you!
image 1: without live()
image 2: with live(), cropper instance dissappeared
Field:
ImageCropper::make('coordinates')
->image(fn (CreateMapping $livewire) => Storage::disk('public')->url($livewire->getMapType()->preview))
->columnSpan(3)
->default('0, 0, 0, 0')
->afterStateUpdated(function(Set $set, string $state)
{
[$x, $y, $width, $height] = explode(', ',$state);
$set('x', $x);
$set('y', $y);
$set('width', $width);
$set('height', $height);
})
->live() ImageCropper::make('coordinates')
->image(fn (CreateMapping $livewire) => Storage::disk('public')->url($livewire->getMapType()->preview))
->columnSpan(3)
->default('0, 0, 0, 0')
->afterStateUpdated(function(Set $set, string $state)
{
[$x, $y, $width, $height] = explode(', ',$state);
$set('x', $x);
$set('y', $y);
$set('width', $width);
$set('height', $height);
})
->live()Class:
<?php
namespace App\Forms\Components;
use Filament\Forms\Components\Field;
use Filament\Forms\Get;
use Illuminate\Support\Facades\Storage;
class ImageCropper extends Field
{
protected string $view = 'forms.components.image-cropper';
public $image;
public function image(string|\Closure|null $image) :static
{
$this->image = $image;
return $this;
}
public function getImageUrl(): ?string
{
if($result = $this->evaluate($this->image))
{
return $result;
}
return null;
}
}<?php
namespace App\Forms\Components;
use Filament\Forms\Components\Field;
use Filament\Forms\Get;
use Illuminate\Support\Facades\Storage;
class ImageCropper extends Field
{
protected string $view = 'forms.components.image-cropper';
public $image;
public function image(string|\Closure|null $image) :static
{
$this->image = $image;
return $this;
}
public function getImageUrl(): ?string
{
if($result = $this->evaluate($this->image))
{
return $result;
}
return null;
}
}Blade:
<x-dynamic-component :component="$getFieldWrapperView()" :field="$field">
<div ax-load
ax-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('image-cropper-cropperjs') }}"
x-data="imageCropper({
state: $wire.{{ $applyStateBindingModifiers("\$entangle('{$getStatePath()}')") }},
})">
<!-- Interact with the `state` property in Alpine.js -->
<input x-ref="arrayState" class="text-black" x-model='state'/>
<img id="image" src="{{ $getImageUrl() }}" alt="Picture">
</div>
</x-dynamic-component><x-dynamic-component :component="$getFieldWrapperView()" :field="$field">
<div ax-load
ax-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('image-cropper-cropperjs') }}"
x-data="imageCropper({
state: $wire.{{ $applyStateBindingModifiers("\$entangle('{$getStatePath()}')") }},
})">
<!-- Interact with the `state` property in Alpine.js -->
<input x-ref="arrayState" class="text-black" x-model='state'/>
<img id="image" src="{{ $getImageUrl() }}" alt="Picture">
</div>
</x-dynamic-component>Script:
import Cropper from 'cropperjs';
export default function imageCropper({
state,
}) {
let component = null;
let cropper = null;
let image = null;
let canvas = null;
let selection = null;
return {
state,
init: function () {
component = this;
cropper = new Cropper('#image');
canvas = cropper.getCropperCanvas();
image = cropper.getCropperImage();
selection = cropper.getCropperSelection();
selection.zoomable = false;
image.scalable = false;
canvas.classList.add("aspect-square");
// Function to handle Cropper.js event
function handleSelectionChange(event) {
component.state = selection.x + ', ' + selection.y + ', ' + selection.width + ', ' + selection.height;
}
selection.addEventListener('change', handleSelectionChange);
console.log(state);
console.log(cropper);
console.log(canvas);
console.log(selection);
console.log('done!');
},
}
}import Cropper from 'cropperjs';
export default function imageCropper({
state,
}) {
let component = null;
let cropper = null;
let image = null;
let canvas = null;
let selection = null;
return {
state,
init: function () {
component = this;
cropper = new Cropper('#image');
canvas = cropper.getCropperCanvas();
image = cropper.getCropperImage();
selection = cropper.getCropperSelection();
selection.zoomable = false;
image.scalable = false;
canvas.classList.add("aspect-square");
// Function to handle Cropper.js event
function handleSelectionChange(event) {
component.state = selection.x + ', ' + selection.y + ', ' + selection.width + ', ' + selection.height;
}
selection.addEventListener('change', handleSelectionChange);
console.log(state);
console.log(cropper);
console.log(canvas);
console.log(selection);
console.log('done!');
},
}
}

Solution
Okay, adding to the x-dynamic-component seems to work in reinitializing the script! Now I just need to set it to the correct position 
wire:key="{{rand()}}"wire:key="{{rand()}}"