Manipulate SVG elements using svg.js and svg-pan-zoom, allowing for double-click interactions

Using Ariutta's svg-pan-zoom with svg.js, I've disabled the native doubleclick functionality and implemented my own custom doubleclick behavior involving pan adjustment and animation.

While this setup usually works fine, occasionally the doubleclick function behaves strangely upon loading the page. Upon debugging, it appears that the function I wrote is sometimes triggered twice for each doubleclick, leading to erratic animation behavior with no clear pattern of occurrence. Restarting the server sometimes resolves the issue, but not consistently, requiring multiple page reloads to correct.

I suspect a possible issue with file load order or conflicts with svg.js animation library or the replacement of the native double-click function in Ariutta's plugin. Any insights on this?

myApp.service('AnimatorService', function(){
   this.dblClickBehavior = function(svgCanvas, zoom){   
        $('.node').dblclick(function(){

            // get pan
            pan = zoom.getPan();

            // get screen width and height
            var sizes = zoom.getSizes();
            var centerX = (sizes.width)/2;
            var centerY = (sizes.height)/2;

            // get center position of svg object double clicked 
            var x0 = this.instance.first().attr('cx');
            var y0 = this.instance.first().attr('cy');

            //determine the correct pan value necessary to center the svg
            panAdjustX = centerX - x0*sizes.realZoom;
            panAdjustY = centerY - y0*sizes.realZoom;

            //center the svg object by adjust pan
            zoom.pan({'x' :centerX - x0*sizes.realZoom, 'y' : centerY - y0*sizes.realZoom});

            //simple animation on the object
            this.instance.first().animate().radius(centerX);

        }); 
       }
});

When functioning correctly, the svg image centers and grows, but when malfunctioning, it centers and shrinks to nothingness.

Answer №1

If you're working with svg.js, you're in luck because there's now a plugin called svg.panZoom.js that can help you achieve the functionality you're looking for easily:

var canvas = SVG('container').viewbox(0,0,1000,1000)

canvas.image('https://www.zooroyal.de/magazin/wp-content/uploads/2017/05/cat-2783601_1920.jpg', 1000, 1000)
  .attr('preserveAspectRatio', 'none')

canvas.on('dblclick', function(e) {
  var p = this.point(e.pageX, e.pageY)
  var zoomLvl = 3

  // zoom into point p to zoomLvl
  canvas.animate().zoom(zoomLvl, p)
})

Check out this fiddle for a working example: https://jsfiddle.net/Fuzzy/95t6oL8y/5/

If you also want to be able to panZoom your svg, simply add a call to canvas.panZoom()

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to capture videos using Safari?

Hey there! I've set up the browser camera on my website for users to record live tests. It's been working great on Chrome and Firefox using MediaRecorder, but unfortunately, Safari isn't cooperating. Does anyone know of an alternative to Me ...

Replace all occurrences of a specific string throughout a extensive document in Node.js

I'm facing a challenge with handling large files in memory. I need to go through each line, replace any double quotes found, and update the file itself. Currently, I am reading the file line by line, storing it in an array, and then overwriting the sa ...

The showdown between JSON and a hefty JavaScript array

Currently, I am developing a jQuery autocomplete feature that will need to handle between 10 to 20k records. The dataset is static, and I have the option to either retrieve it from a JSON file or embed it directly into the page using a single line of code ...

Here is a helpful guide on updating dropdown values in real time by retrieving data from an SQL database

This feature allows users to select a package category from a dropdown menu. For example, selecting "Unifi" will display only Unifi packages, while selecting "Streamyx" will show only Streamyx packages. However, if I first select Unifi and then change to S ...

What is the method to modify the background color of el-pagination?

I am using el-pagination on a dark page and I want to make its background color transparent. When I do not use the 'background' prop, the background color of el-pagination is white. Here is how it looks: (sorry I can't add an image) htt ...

Can Selenium successfully scrape data from this website?

I am currently attempting to extract Hate Symbol data (including the name, symbol type, description, ideology, location, and images) from the GPAHE website using Selenium. As one of my initial steps, I am trying to set the input_element to the XPATH of the ...

Else statement malfunctioning with Alert() function

I have noticed an issue with my user input field. Even when I enter a valid genre name, the alert prompt still appears saying it is not a valid genre. This occurs after entering both valid and invalid inputs. For example, if the user enters "horror," whic ...

Unable to attach eventName and callback to addEventListener due to the error message stating 'No overload matches this call'

I am attempting to attach an event listener to the input element stored within a class method. This method takes a props object containing eventName and callback. public setTextFieldInputListener({ eventName, callback }: TextFieldListenerProps): void { ...

Is there a way to retrieve the controller instance linked to a directive within the link function?

Is there a way to retrieve the controller instance connected with a directive within the link function? return { template: template, controller: controller, controllerAs: 'myCtrl', // What is the method for ac ...

Utilizing nested grouping in mongoose schemas

I am facing a challenge while attempting to execute a nested group query in MongoDB. Is there a way to group data by both date and campaign ID, ensuring that each campaign ID contains a nested array of creatives with their respective data (views and clicks ...

Is it possible to compare every element in an array with one another using an asynchronous process in NodeJS?

I am currently utilizing Resemble.js for image comparison within my web application. I have an array of image URLs that I need to compare with each other in order to calculate a unique score for each image. For example: [url1, url2, url3, url4] The minimu ...

failed to establish WebSocket connection: Server responded with an unexpected HTTP status code 404

Has anyone else encountered the error message "Firefox can't establish a connection to the server at ws://localhost:8082/FetchNotification/NewFile.htmlatpendpoint" during websocket handshake? I came across this issue and found some helpful informatio ...

There was an error trying to read properties of undefined, specifically the 'prototype', in a code using Next.Js and Express

While attempting to incorporate express into my next.js project, I encountered errors when trying to initialize express: const express = require('express'); The errors that appeared were: Module not found: Can't resolve 'async_hooks ...

Develop a Vue.js component embedded within another component to manipulate data stored in the parent

After reviewing a few answers that partially address my question, I realized there is more to explain. In our Laravel project website layout, we utilize a global #app div. This means all pages share the same main Vue instance, prompting me to segregate ke ...

Debug errors occur when binding to computed getters in Angular 2

Currently, I am integrating Angular 2 with lodash in my project. Within my model, I have Relations and a specific getter implemented as follows: get relationsPerType() { return _(this.Relations) .groupBy(p => p.Type) .toPairs() ...

Issue encountered while configuring input in ReactJS: the label is conflicting with the input value, causing it to be overwritten when using material.ui components

Hello fellow developers! I am currently facing an issue in my reactJS project. I am using the react-form-hook along with Material-UI's TextField. The problem arises when I input data into a field named cep, triggering a function that fetches content ...

Unable to receive FCM Push Notifications for web when testing on local server

I am currently working on implementing web push notifications in our web app. I have successfully set up Firebase Cloud Messaging in my app by following the documentation. I am able to prompt the user for permission to receive notifications and obtain the ...

Refreshing AngularJS: How to reload Ngtable with previous data

Currently, I am utilizing NGTable to exhibit data on my webpage. The data is stored in an array and passed through the dataset parameter. However, when I dynamically modify a value in the array, the changes are accurately reflected in the table BUT if I na ...

An issue has occurred with NPM CI where the bindings are not available from watchpack-chokidar2:fsevents

After executing npm ci on GitHub Actions, I encountered the following error: Run npm ci npm ERR! bindings not accessible from watchpack-chokidar2:fsevents npm ERR! A complete log of this run can be found in: npm ERR! /home/runner/.npm/_logs/2021-09-17 ...

Convert the dynamic table and save it as a JSON file

Looking for the most effective method to save dynamic table data into JSON format. I have two tables that need to be saved into a single JSON file. While I can easily access and console log the regular table data, I'm having trouble retrieving the td ...