Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

javascript - Having issue with Livewire and an inline js script for zooming image

been stuck here for 2 days now, please advise.

I have this Livewire ProductDetail modal that shows when Livewire public $show = true and I have a listener listening for a viewProduct event and when the event is received the viewProduct public method is called and the product is assigned to public $product then $this->show = !this->show and the modal is displayed as expected.

The problem is that I have a js script in the blade file that implements a zoom function on the product image when you hover with the mouse and this gets all messed up.

I have tried different approaches using Livewire events and also Alpine js but still no luck.

Livewire ProductDetail Component

<?php

namespace AppHttpLivewire;

use AppModelsProduct;
use AppUpdatable;
use LivewireComponent;

class ProductDetail extends Component
{
    use Updatable;

    public $show = false;

    // public $product;

    protected $listeners = ['viewProduct', 'cartUpdated' => '$refresh'];

    public function viewProduct(Product $product)
    {
        $this->product = $product;

        $this->show = !$this->show;
    }

    public function render()
    {
        return view('livewire.product-detail');
    }
}

product-detail.blade.php

@php
    $cartContent = Cart::content();
@endphp
<div wire:igone x-data="{
    
    show: @entangle('show'),

}" x-show="show" x-cloak class="bg-black bg-opacity-50 fixed inset-0 lg:flex lg:items-center overflow-scroll z-10">
    @if (isset($product))
        <div class="bg-white lg:max-w-screen-md lg:min-h-0 min-h-screen mx-auto relative w-full xl:max-w-screen-lg rounded-md overflow-hidden">
            <div class="lg:flex lg:gap-6 py-6 px-4">
                

                <div class="w-1/2 flex items-center justify-center">
                   
                    <x-image-zoom :image="$product->image" />
                   
                </div>

                <div class="flex-1 mt-2">
                    <div class="flex flex-col justify-between">
                        <h1 class="flex-1 text-2xl mt-1 max-w-xs leading-none">
                            {{ $product->name }}
                        </h1>

                        <div class="flex justify-start my-4">
                            <x-badge class="text-xl" :product="$product" />
                        </div>

                        <div>
                            <p>{{ $product->unit_size }}</p>

                            <div class="flex items-center justify-start space-x-2 mt-3 leading-none">
                                <div class="font-semibold inline-flex items-baseline text-gray-700">
                                    <span class="text-gray-500 pr-1">Ks</span>
                                    <span class="text-2xl" x-text="getFormattedPrice('{{ $product->discount_available }}', '{{ $product->discount }}', '{{ $product->price }}')" />
                                </div>

                                <div x-show="ifDiscountAvailable('{{ $product->discount_available }}')">
                                    <span class="line-through tracking-tight text-gray-500 font-semibold">{{ $product->formatted_price }}</span>
                                </div>
                            </div>
                        </div>

                        <p class="text-sm text-gray-600 my-8">
                            {{  $product->description  }}
                        </p>
                    </div>
                </div>
            </div>

            <div class="bg-gray-200 h-32 px-3 py-3">
                Footer
            </div>
        </div>
    @endif
</div>

The problem component please have a look at this and advise

<x-image-zoom :image="$product->image" /> passing the path to the image

<div>
    <div
        x-data="initiate()"
        x-on:mouseenter="zoomImage('myimage', 'myresult')"
        x-on:mouseleave="removeCreatedElements()"
        class="img-zoom-container w-full h-full relative">
        <img id="myimage" src="{{ asset('storage/'.$image) }}">
        <div id="myresult" class="img-zoom-result"></div>
    </div>
</div>
<script>
    function initiate() {
        return {
            zoomImage(imgID, resultID) {
                var img, lens, result, cx, cy;
                img = document.getElementById(imgID);
                result = document.getElementById(resultID);
                result.setAttribute('class', 'absolute inset-0');
                
                lens = document.createElement("DIV");
                lens.setAttribute("class", "absolute border-2 border-accent w-52 h-52");
                lens.setAttribute('id', 'zoomLense');
                
                img.parentElement.insertBefore(lens, img);
                
                cx = result.offsetWidth / lens.offsetWidth;
                cy = result.offsetHeight / lens.offsetHeight;
                
                result.style.backgroundImage = "url('" + img.src + "')";
                result.style.backgroundSize = (img.width * cx) + "px " + (img.height * cy) + "px";
                
                lens.addEventListener("mousemove", moveLens);
                img.addEventListener("mousemove", moveLens);
                result.addEventListener("mousemove", moveLens);
                
                lens.addEventListener("touchmove", moveLens);
                img.addEventListener("touchmove", moveLens);
                result.addEventListener("touchmove", moveLens);
                
        function moveLens(e) {
                    var pos, x, y;
                    
                    e.preventDefault();
                    
                    pos = getCursorPos(e);
                    
                    x = pos.x - (lens.offsetWidth / 2);
                    y = pos.y - (lens.offsetHeight / 2);
                    
        
                    if (x > img.width - lens.offsetWidth) { x = img.width - lens.offsetWidth; }
                    if (x < 0) { x = 0; }
                    if (y > img.height - lens.offsetHeight) { y = img.height - lens.offsetHeight; }
                    if (y < 0) { y = 0; }
                
            /*set the position of the lens:*/
                    lens.style.left = x + "px";
                    lens.style.top = y + "px";
                    
            /*display what the lens "sees":*/
                    result.style.backgroundPosition = "-" + (x * cx) + "px -" + (y * cy) + "px";
                }

                function getCursorPos(e) {
                    var a, x = 0, y = 0;
                    e = e || window.event;

                    /*get the x and y positions of the image:*/
                    a = img.getBoundingClientRect();

                    /*calculate the cursor's x and y coordinates, relative to the image:*/
                    x = e.pageX - a.left;
                    y = e.pageY - a.top;

                    /*consider any page scrolling:*/
                    x = x - window.pageXOffset;
                    y = y - window.pageYOffset;
                    return { x: x, y: y };
                }
            },

            removeCreatedElements() {
                document.getElementById('zoomLense').remove();
                document.getElementById('myresult').style.backgroundImage = 'none';
            }
        }
    }
</script>

The above script works if I do the following in ProductDetail.php but when products change the js gets messed up

<?php

namespace AppHttpLivewire;

use AppModelsProduct;
use AppUpdatable;
use LivewireComponent;

class ProductDetail extends Component
{
    use Updatable;

    public $show = false;

    // public $product;

    protected $listeners = ['viewProduct', 'cartUpdated' => '$refresh'];

    public function viewProduct(Product $product)
    {
        // $this->product = $product;

        $this->show = !$this->show;
    }
    public function render()
    {
        // return view('livewire.product-detail');
        return view('livewire.product-detail', ['product' => Product::find(1)]);
    }
}
question from:https://stackoverflow.com/questions/65895857/having-issue-with-livewire-and-an-inline-js-script-for-zooming-image

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...