Kamil
Kamil

Reputation: 61

How to manipulate an svg depending on mouse position?

I have an SVG eye image. And I want to animate iris and the pupil to move around eyeball according to mouse position. I have already this:

SVG in html:

const leftPupil = document.getElementById("left-pupil");
document.addEventListener("mousemove", function(e){
    let x = e.clientX;
    let y = e.clientY;
    leftPupil.setAttribute('transform', `translate(-${x},-${y})`);
});
<svg id="face" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1152.31 1075.95">
                <defs><style>.cls-1,.cls-10,.cls-2,.cls-9{fill:none;stroke:#fff;}.cls-1,.cls-10,.cls-11,.cls-2,.cls-9{stroke-miterlimit:10;}.cls-1,.cls-11,.cls-12,.cls-3,.cls-4,.cls-5,.cls-6,.cls-7,.cls-8,.cls-9{fill-rule:evenodd;}.cls-3{fill:#1a52db;}.cls-4{fill:#223992;}.cls-5{fill:#fff;}.cls-6{fill:#fd5219;}.cls-8{fill:#d63319;}.cls-10,.cls-9{stroke-width:2px;}.cls-11{fill:#feae00;stroke:#feae00;}.cls-12{fill:#f15a24;}
                </style></defs>
<g id="left-eye">
<path id="left-white" class="cls-5" d="M626,288.2a4.6,4.6,0,0,0,1.4,3c5.73,6.09,26.18,28.7,46.41,34.32a228.21,228.21,0,0,0,48.8,8.12s32.21-2.36,49.31-8.5,34.19-12.28,39.36-15.45.4-13.29.4-13.29S788.13,270,765.4,261.78c-15.06-5.44-25-10.73-53.78-11.59-15-.45-38.06,4.59-56.21,13.28-11.35,5.44-20,13.24-25.94,19.18C626.71,285.4,626.08,286.72,626,288.2Z" transform="translate(-415.19 -6.14)"/>
<path id="left-iris" class="cls-3" d="M676.54,281.74s7.91-29.74,39.16-37.39,47.08,28.14,47.08,28.14,1.62,18.56-2.78,27.65S747.38,322.89,738.26,325c-3.87.89-16.62,2.76-27.28-.82-14.45-4.86-27.27-16.13-29.63-19.59C677.14,298.4,676,287.94,676.54,281.74Z" transform="translate(-415.19 -6.14)"/>
<path id="left-pupil" class="cls-7" d="M710.77,295.47c-3.51-5.52-5.1-13.7-3.19-16.35s7.64-9.7,13.15-9.54,17.26,3.21,18.82,14.89a2.11,2.11,0,0,1,0,.26c.1,1.13,1.14,9.85-2.22,12.44-5.64,4.35-13,3.22-13,3.22S713.2,299.3,710.77,295.47Z" transform="translate(-415.19 -6.14)"/>
</g>
</svg>

and the pupil is moving, but I don't know how to make it move only on the specific field (an eyeball).

Upvotes: 2

Views: 698

Answers (2)

Abdel Kader Glt
Abdel Kader Glt

Reputation: 66

you need to offset from the center https://codepen.io/NourimoS/pen/ZEBgXOY take a look at this pen

const Pupil = document.getElementById("pupil");
const Pupil2 = document.getElementById("pupil2");
const svg = document.querySelector("svg");
const { x, y, width, height } = svg.getBBox();
const cx = width / 2,
      cy = height / 2;
document.addEventListener("mousemove", function ({ clientX: x, clientY: y }) {
const tx = ((cx - x) / cx) * 200,
    ty = ((cy - y) / cy) * 100;
    pupil.setAttribute("transform", `translate(${tx},${ty})`);
    pupil2.setAttribute("transform", `translate(${tx * 0.8},${ty * 0.8})`);
});

Upvotes: 1

Yosef Tukachinsky
Yosef Tukachinsky

Reputation: 5895

  1. You already use transform on the path for the initial placement. suggest to wrap it in g and move the transform there.
  2. You can determine the angle from pointer to eyeball using atan2 and then use unit circle to set the right transform

const leftPupil = document.getElementById("left-pupil");
document.addEventListener("mousemove", function(e){
    let x = e.clientX;
    let y = e.clientY;
    const pupilRect = leftPupil.getBoundingClientRect();
    const radius = 8;
    const angle = Math.atan2(y-pupilRect.top,x-pupilRect.left)+Math.PI;
    leftPupil.setAttribute('transform', `translate(${-radius*Math.cos(angle)},${-radius*Math.sin(angle)})`);
});
<svg viewBox="0 0 500 500" width="200" height="200">
<g id="left-eye">
<path id="left-white" class="cls-5" fill="white" stroke="black" stroke-width="3" d="M626,288.2a4.6,4.6,0,0,0,1.4,3c5.73,6.09,26.18,28.7,46.41,34.32a228.21,228.21,0,0,0,48.8,8.12s32.21-2.36,49.31-8.5,34.19-12.28,39.36-15.45.4-13.29.4-13.29S788.13,270,765.4,261.78c-15.06-5.44-25-10.73-53.78-11.59-15-.45-38.06,4.59-56.21,13.28-11.35,5.44-20,13.24-25.94,19.18C626.71,285.4,626.08,286.72,626,288.2Z" transform="translate(-415.19 -6.14)"/>
<path id="left-iris" class="cls-3" d="M676.54,281.74s7.91-29.74,39.16-37.39,47.08,28.14,47.08,28.14,1.62,18.56-2.78,27.65S747.38,322.89,738.26,325c-3.87.89-16.62,2.76-27.28-.82-14.45-4.86-27.27-16.13-29.63-19.59C677.14,298.4,676,287.94,676.54,281.74Z"
fill="brown" stroke="black" stroke-width="3" 
transform="translate(-415.19 -6.14)"/>
<g transform="translate(-415.19 -6.14)">
<path id="left-pupil" class="cls-7" d="M710.77,295.47c-3.51-5.52-5.1-13.7-3.19-16.35s7.64-9.7,13.15-9.54,17.26,3.21,18.82,14.89a2.11,2.11,0,0,1,0,.26c.1,1.13,1.14,9.85-2.22,12.44-5.64,4.35-13,3.22-13,3.22S713.2,299.3,710.77,295.47Z" />
</g>
</g>
</svg>

Upvotes: 2

Related Questions