Adjust the size of a SVG group by hovering over a separate HTML element

I need some help with implementing a scale effect on group elements within an SVG. The goal is to have the group element scale up when hovering over a list item, but I am running into issues with the positioning because of the translate property.

Does anyone have any suggestions on how to solve this problem or can provide guidance on a different approach?

Here is the markup for the list:

li.active {
  color: red;
}

.round {
  transition: transform .3s ease;
}

.round.active {
  transform: scale(1.3);
}

<ul class="list">
  <li data-number="round1">round 1</li>
  <li data-number="round1-copy">round 2</li>
</ul>

And here is the jQuery code:

$('.list > li').on('mouseover', function() {
  var _this = $(this),
    dataNumber = _this.data('number');
  _this.addClass('active');
  $('#' + dataNumber).addClass('active');
});

$('.list > li').on('mouseleave', function() {
  $(this).removeClass('active');
  $('.round.active').removeClass('active');
});

You can view a working example on this JSFiddle link.

Any assistance would be greatly appreciated :)

Answer №1

One way to enhance your code is by adding another g element without altering the original code. You can make it more concise by utilizing the :hover selector instead of toggling a class for li.

$(function() {
  $('.list > li').on('mouseover', function() {
    var _this = $(this),
        dataNumber = _this.data('number');
    $('#'+dataNumber).addClass('active')
  });

  $('.list > li').on('mouseleave', function() {
    $('g.active').removeClass('active')
  });

});
li:hover {
  color: red;
}

g {
  transition: transform .3s ease;
  transform-origin:center;
  transform-box:fill-box;
}

g.active {
  transform: scale(1.3);
}
<ul class="list">
  <li data-number="round1">round 1</li>
  <li data-number="round1-copy">round 2</li>
</ul>
...

You can eliminate the need for the JS part in your HTML code with adjustments like below:

li:hover {
  color: red;
}

g {
  transition: transform .3s ease;
  transform-origin:center;
  transform-box:fill-box;
}

.list :last-child {
   list-style:none;
   margin:10px 0 0 -10px;
}
[data-number="round1"]:hover ~ li:last-child svg #round1,
[data-number="round2"]:hover ~ li:last-child svg #round2{
  transform: scale(1.3);
}
<ul class="list">
  <li data-number="round1">round 1</li>
  <li data-number="round2">round 2</li>
  <li>
<svg width="300px" height="300px" viewBox="0 0 300 300" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
...

Answer №2

Completing this task using an inline transform and a scale, as you are currently doing, is quite challenging.

However, after reading through this explanation regarding getComputedStyle() and trasnform, it's possible to eliminate the use of a CSS class by instead utilizing the computed style of the element. This involves retrieving the current transform value of the element (via getComputedStyle() followed by extracting each value of the matrix with regex).

Once the aforementioned value is obtained, adjust the scaleX and scaleY values (located at index 0 and 3 of the matrix array), and then apply the modified matrix back to the element. Here's an example:

$(function() {
  $('.list > li').on('mouseover', function() {
    var dataNumber = $(this).data('number');
    $(this).addClass('active');
    let roundElem = $('#' + dataNumber)[0];
    adjustTransform(roundElem, 1.3)
  });

  $('.list > li').on('mouseleave', function() {
    $(this).removeClass('active');
    var dataNumber = $(this).data('number');
    let roundElem = $('#' + dataNumber)[0];
    adjustTransform(roundElem, 1)

  });

  function adjustTransform(elem, scale) {
    let trans = getComputedStyle(elem).transform;
    numberPattern = /-?\d+\.?\d+|\d+/g;
    v = trans.match(numberPattern);
    let newMatrix = "matrix(" + scale + ", " + v[1] + "," + v[2] + "," + scale + "," + v[4] + "," + v[5] + ")"
    elem.style.transform = newMatrix
  }

});
li.active {
  color: red;
}

.round {
  transition: transform .3 ease;
}
<ul class="list">
  <li data-number="round1">round 1</li>
  <li data-number="round1-copy">round 2</li>
</ul>
<?xml version="1.0" encoding="UTF-8"?>
<svg width="300px" height="300px" viewBox="0 0 300 300" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <!-- Generator: Sketch 48.2 (47327) - http://www.bohemiancoding.com/sketch -->
    <title>square</title>
    <desc>Created with Sketch.</desc>
    <defs>
        <rect id="path-1" x="0" y="0" width="300" height="300"></rect>
    </defs>
    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="square">
            <g id="rectangle">
                <use fill="#D8D8D8" fill-rule="evenodd" xlink:href="#path-1"></use>
                <rect stroke="#979797" stroke-width="1" x="0.5" y="0.5" width="299" height="299"></rect>
            </g>
            <g id="round1" class="round" transform="translate(119.000000, 119.000000)">
                <g id="number">
                    <circle id="Oval" stroke="#979797" fill="#FFFFFF" cx="31" cy="31" r="31"></circle>
                    <text id="1" font-family="Helvetica-Bold, Helvetica" font-size="20" font-weight="bold" fill="#272A2F">
                        <tspan x="25" y="38">1</tspan>
                    </text>
                </g>
            </g>
            <g id="round1-copy" class="round" transform="translate(181.000000, 57.000000)">
                <g id="number2">
                    <circle id="Oval2" stroke="#979797" fill="#FFFFFF" cx="31" cy="31" r="31"></circle>
                    <text id="2" font-family="Helvetica-Bold, Helvetica" font-size="20" font-weight="bold" fill="#272A2F">
                        <tspan x="25" y="38">2</tspan>
                    </text>
                </g>
            </g>
        </g>
    </g>
</svg>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

Note that performance may be impacted if numerous elements utilize getComputedStyle during hover events.

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

How can I access the variable that evaluated as true in an if statement?

I'm facing a bit of a challenge with testing 2 variables for the same value. Is there a way to achieve this? var x = 'abc'; var y = 'def'; if (x=='abc' || y=='abc'){ z = 'result&a ...

Creating a Persistent Top Navigation Bar using Bootstrap and Angular

I am struggling to implement a fixed top navbar in Angular. The structure of my main app.component template is as follows: <page-header></page-header> <router-outlet></router-outlet> The bootstrap navbar is included within my ...

Refresh the copyright year by syncing with a time server

Not long ago, I found myself needing to update the copyright year on a website. Instead of using JavaScript to get the year from the system time, I began wondering if there was a way to utilize an internet time server for this purpose. I believe that util ...

A step-by-step guide to incorporating VeeValidate with vue-i18n

When a click event is triggered, I am able to change the language in vue-i18n. However, I am facing an issue with changing the vee-validate dictionary to match the same language. Main.js import VeeValidate from 'vee-validate' import validations ...

"Discover the steps to efficiently utilize the lookup feature with array objects in MongoDB

I am a beginner with MongoDB and I am trying to create a schema for my collection as shown below please note that all ObjectId values are placeholders and not real stockIn documents { serial:"stk0001", date:'2021-06-11', productInTra ...

What is the best way to position a static element next to a Vue draggable list?

I'm currently working on implementing a feature to display a list of draggable elements using vue-draggable. These elements are occasionally separated by a fixed element at specified position(s). My approach so far has involved creating a separate el ...

Choose from the dropdown menu, not from the text

I'm having trouble aligning a select element in Bootstrap without centering the text inside it. Can anyone provide a solution for this issue? I've attempted to center the containing div and then set the text-align property to left for the select ...

Autocomplete Dropdown failing to select default value when defaultValue option is set

stateNPAValue[formData.state.vale] = 0: "All",1: "959", 2: "203",3: "860", 4: "475" // API response for NPA data const [selectedNamesState, setSelectedNamesState] = useState([]); const transformedNpaData ...

Execute JavaScript function in NodeJS server background

I have developed a function that periodically monitors the battery statuses of connected android devices and returns an array. How can I execute this function on server startup and ensure it continues to run while sharing its information with other pages? ...

The straightforward onclick action only functioned once

Looking for assistance: Can someone explain why this code snippet isn't functioning properly? It seems that the increment is only happening once. var player = document.getElementById("player"); var button = document.getElementById("button"); functio ...

How can I retrieve the text input from a physical barcode scanner in a React Native screen?

Currently, I am developing a mobile application with React Native version 0.68.2. I am seeking a solution to detect barcode scanning events from a physical scanner hardware that is integrated into the mobile device as a handheld scanner. The key requirem ...

Discovering hospitals in the vicinity with the help of Google Maps API and JavaScript

var MapApiApplication = { myCurrentPosition : "", mapOptions : "", marker : "", initialize : function(){ MapApiApplication.myCurrentPosition = new google.maps.LatLng(10.112293000000000000, 76.352684500000010000); M ...

A guide to determining the dimensions (width, height, length) of a mesh using THREE.js

I've been scouring different sources in hopes of finding a way to obtain the width and height of a mesh, but I haven't had any luck. I have imported a collada model into my project, and all I need is to determine its dimensions in Webgl/Three.js ...

angular does not update dynamically created dropdowns with populated arrays

Upon loading the page, my initial dropdown functions correctly. However, the child dropdown is loaded from localstorage after the first dropdown. The issue arises when I load the second dropdown and set it to the default value - at this point, I am unabl ...

Try implementing transform translate with absolute coordinates when positioning elements on a webpage

If I wanted to create a box that moves along with the mouse cursor, I could achieve that using the code below. document.addEventListener('mousemove', (e) => { document.documentElement.style.setProperty('--mouse-x', e.clientX ...

Tips for obtaining images and displaying them using Node.js

Trying to obtain an image and display it on a URL using the request module. For instance, aiming to fetch the image https://www.google.com/images/srpr/logo11w.png, and show it on my URL http://example.com/google/logo. Alternatively, displaying it with &l ...

The functionality of Javascript is only accessible once you open the developer tools in Chrome

I am encountering a similar issue to the one discussed here: Why does JavaScript only work after opening developer tools in IE once? However, in my case, the problem arises in Chrome 44. The JavaScript code, particularly involving XHR and setInterval, f ...

Stylize the div within the hyperlink when hovering over it

I am trying to add a hover effect to a div inside a hyperlink using CSS, but I'm not sure how to do it. The divs in question have background images set in the CSS. <div class="header_menu"> <div class="foa_logo"><img src="images/FOA ...

Changing the height of tablerows in Material UI v5: A step-by-step guide

I am attempting to adjust the height of the rows in this material-ui code example. import * as React from "react"; import { styled } from "@mui/material/styles"; import Table from "@mui/material/Table"; import ...

Utilizing jQuery to eliminate spaces and prevent special characters: a comprehensive guide

For my website's signup form, I need to enforce certain rules for the username: The username cannot contain any spaces. The username can only include a dot (.) as special character, similar to how Gmail handles usernames in their signup form. I am ...