svgdotjs / svg.js

The lightweight library for manipulating and animating SVG
https://svgjs.dev
Other
11.01k stars 1.07k forks source link

click event does not fire when a animation is running #1190

Closed mStirner closed 11 months ago

mStirner commented 3 years ago

I have trouble with fireing events when a animation is running on a element. For example, a simple click() callback get not invoked when the element spinns.

Demonstation:

<!doctype html>
<html lang="de">

<head>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <title>Schematic</title>

    <script src="https://cdn.jsdelivr.net/npm/@svgdotjs/svg.js@3.0/dist/svg.min.js"></script>
    <!--<script src="assets/js/vue.min.js"></script>-->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.12/vue.common.dev.min.js"></script>

    <script>

        const color = {
            blue: "#007bff",
            indigo: "#6610f2",
            purple: "#6f42c1",
            pink: "#e83e8c",
            red: "#dc3545",
            orange: "#fd7e14",
            yellow: "#ffc107",
            green: "#28a745",
            teal: "#20c997",
            cyan: "#17a2b8",
            white: "#fff",
            gray: "#6c757d",
            "gray-dark": "#343a40",
            primary: "#007bff",
            secondary: "#6c757d",
            success: "#28a745",
            info: "#17a2b8",
            warning: "#ffc107",
            danger: "#dc3545",
            light: "#f8f9fa",
            dark: "#343a40"
        };

        let baseColor = {
            background: "#000",
            "fill-opacity": 0.5,
            stroke: color.white,
            "stroke-width": 1,
            "stroke-opacity": 0.5
        };

        let pipeColor = {
            fill: color.blue,
            opacity: 1
        };

        let pumpColor = {
            fill: color.gray,
            "fill-opacity": 0.8
        }

        document.addEventListener("DOMContentLoaded", () => {

            // parent drawing
            let draw = SVG().addTo('#schematic').size("100%", 500);

            let pumpGroup = draw.symbol();

            pumpGroup.click(function () {
                alert("Pump clicked!");
            });

            let height = 50;
            let radius = 30;

            let chase = pumpGroup.rect(80, height).attr(baseColor).move(0, 0);  // 520, 370

            let motor1 = pumpGroup.circle(radius).attr(pumpColor).move(45, (height / 2) - radius / 2);   // 525, 380
            let motor2 = pumpGroup.circle(radius).attr(pumpColor).move(5, (height / 2) - radius / 2);   // 565, 380

            let fan1 = pumpGroup.image("https://cdn0.iconfinder.com/data/icons/screw/512/fan-ventilator-propeller-rotor-motion-512.png").scale(0.05).move(940, 240); //.animate().rotate(360, 256 + 940, 256 + 240).loop();
            let fan2 = pumpGroup.image("https://cdn0.iconfinder.com/data/icons/screw/512/fan-ventilator-propeller-rotor-motion-512.png").scale(0.05).move(140, 240);
            // 

            // 1 = slave, 2 = master
            let fant1Runner = fan1.animate(1500).ease("-").rotate(360, 256 + 940, 256 + 240).loop().timeline().pause();
            let fant2Runner = fan2.animate(1500).ease("-").rotate(360, 256 + 140, 256 + 240).loop().timeline().pause();

            setInterval(() => {

                fant2Runner.play();
                fant1Runner.play();

                setTimeout(() => {
                    fant2Runner.pause();
                    fant1Runner.pause();
                }, 2500)

            }, 5000);

            draw.use(pumpGroup).move(10, 10).click(() => {
                alert("Clicked on pump!");
            });

        });

    </script>

</head>

<body>
    <div id="app">
        <div id="schematic"></div>
    </div>
</body>

</html>

The fans of the pump stat spinning after 5sec, when the animation is running/played you can click like a manic on the pump and nothing happens. Is the animation finished/stopped/paused, the alert shows, like it should be.

Can any one explain why this happen and how to fix it ? I created a stackoverflow, question, but answers so far.

I dont think the behaviour should be like this.

Fuzzyma commented 3 years ago

Please create a minimal example that shows the issue

mStirner commented 3 years ago

The code i posted is a minimal example that shows the issue. Tested on Ubuntu 18.04 LTS, Firefox & Chromium.

If you run the example, an the pump fans spinning (and then click on the pump) no alert is triggerd. When the fans stop/pause, the and you click again, the alert is displayed with "Clicked on pump"

You can run the example directly from the SO page.

EDIT: Created a more minimalist example, with just one element.

<!doctype html>
<html lang="de">

<head>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <title>Schematic</title>

    <script src="https://cdn.jsdelivr.net/npm/@svgdotjs/svg.js@3.0/dist/svg.min.js"></script>

    <script>

        document.addEventListener("DOMContentLoaded", function () {

            let draw = SVG().addTo('#schematic').size("100%", 500);

            let symbol = draw.symbol();

            let rect = symbol.rect(100, 100).fill('#f09');

/*

            // THIS WORKS FINE!!!
            // EVEN WHEN THE ANIMATION IS RUNNING!
            let rect = draw.rect(100, 100).fill('#f09');

            rect.click(() => {
                console.log(`${Date.now()} - ` + "Clicked! -----");
            });

*/

            // .animate() returns svg.runner
            rect.animate(500).ease("-").rotate(10, 10).loop();
            let animation = rect.timeline().pause();

            setInterval(() => {

                animation.play();

                setTimeout(() => {
                    animation.pause();
                }, 2500);

            }, 5000)

            draw.use(symbol).click(() => {
                alert("Clicked!");
            });

        });

    </script>

</head>

<body>
    <div id="schematic"></div>
</body>

</html>

I think the problem is the event handling on the .use element in combination with .symbol The click handler on the .rect element works fine.

Fuzzyma commented 11 months ago

This seems to be indeed a bug in the browser implementation. The element is not targetable while being animated. Please create a bug ticket on the vendor site