0

Say I have a single SVG element that serves as the background. Using the following working code to get the x & y coordinates of the mouse on the move and the viewport width and height, I want to dynamically compute for the coordinates of a certain portion of the SVG element given any viewport width and height since I want to assign an onclick() to that portion.

var eventDoc, doc, bodyDoc;
e = e || window.e;
var x = e.originalEvent.touches ? e.originalEvent.touches[0].pageY : e.pageY;
var y = e.originalEvent.touches ? e.originalEvent.touches[0].pageX : e.pageX;

if (x == null && event.clientX != null) {
    eventDoc = (event.target && event.target.ownerDocument) || document;
    doc = eventDoc.documentElement;
    bodyDoc = eventDoc.bodyDoc;

    x = e.clientX +
        (doc && doc.scrollLeft || bodyDoc && bodyDoc.scrollLeft || 0) -
        (doc && doc.clientLeft || bodyDoc && bobodyDocdy.clientLeft || 0);
    y = e.clientY +
        (doc && doc.scrollTop || bodyDoc && bodyDoc.scrollTop || 0) -
        (doc && doc.clientTop || bodyDoc && bodyDoc.clientTop || 0);
}
var vw = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
var vh = Math.max(document.documentElement.clientHeight, window.innerHeight || 0)

A hardcoded solution I've thought of would be to have a lot of if statements for each different device vw/vh and different desktop vw/vh's, but I don't think that's very sustainable. Any suggestions?

Sandeep Kumar
  • 2,397
  • 5
  • 30
  • 37
Atenean1
  • 82
  • 11

1 Answers1

0

The solution was to use an object tag and access the SVG DOM from there by using contentDocument and getBoundingClientRect().

HTML:

<object id="svg-el" type="image/svg+xml" data="./resources/images/wallpaper2.svg"
    style="width: 100%; height: 100%; object-position: center; background-size: cover; opacity: 0; display: block;"
    alt="svg-el"></object>

SVG Element:

<svg width="1920" height="1080" viewBox="0 0 1920 1080" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid slice">

...

<rect id="Position 1" x="997" y="525.925" width="100.364" height="120" transform="rotate(-13.1588 997 525.925)" fill="url(#pattern10)"/>
<rect id="Position 2" x="792.675" y="639" width="94.2857" height="110" transform="rotate(12.4289 792.675 639)" fill="url(#pattern11)"/>
<rect id="Position 3" x="845.252" y="414" width="91.35" height="105" transform="rotate(11.6772 845.252 414)" fill="url(#pattern12)"/>

...

</svg>

JavaScript:

var mySVG = document.getElementById("svg-el");
var svgDoc;
var position1;
var position2;
var position3;

mySVG.addEventListener("load", function () {
    svgDoc = mySVG.contentDocument;

    position1 = svgDoc.getElementById('Position 1').getBoundingClientRect();
    postion2 = svgDoc.getElementById('Position 2').getBoundingClientRect();
    position3 = svgDoc.getElementById('Position 3').getBoundingClientRect();

    // gets the coordinates of each element's surrounding square for any screen size
    position1L = position1.left;
    position2T = position1.top;
    position1R = position1.right;
    position1B = position1.bottom;

    position2L = position2.left;
    position2T = position2.top;
    position2R = position2.right;
    position2B = position2.bottom;

    position3L = position3.left;
    position3T = position3.top;
    position3R = position3.right;
    position3B = position3.bottom;

}, false);

Other useful links:

https://benfrain.com/selecting-svg-inside-tags-with-javascript/

getting the X and Y coordinates for a div element https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect

https://vecta.io/blog/best-way-to-embed-svg JavaScript accessing inner DOM of SVG

How to make SVG "fill" act in a similar way to CSS "background-size: cover"

JavaScript accessing inner DOM of SVG

Atenean1
  • 82
  • 11