简体   繁体   中英

How do I offset an element based on my mouse position?

I've got a grid of several <rect> elements inside an SVG. I'm trying to offset the elements based on the position of my mouse. So when my mouse is within a certain range of the element, the element moves away from my mouse.

Items closer to the mouse should move further away than the elements in the outer range.

So far I've managed to target the rectangles within a certain range of my mouse with the following if/else statement:

if((mouseX > coordX && mouseX < (coordX + 50) || mouseX < coordX && mouseX > (coordX - 50)) 
    && (mouseY > coordY && mouseY < (coordY + 50) || mouseY < coordY && mouseY > (coordY - 50)))

This statement could probably use some improvement.

The next step is altering to position of the <rect> elements based on my mouses position. Affecting the elements closest to the mouse the strongest.

The else statement should revert the elements back to their original position. This statement is triggered when the mouse leaves the target range.

At this moment I'm stuck at the part where I need to offset the <rect> elements based on the position of the mouse.

FIDDLE

You just need to calculate the distance from the pointer to each square and then use a transform to move the square away from the pointer based on how far away it is.

$('rect').each(function(){
    var position = $(this).position();
    var widthMod = $(this).attr('width')/2;
    var heightMod = $(this).attr('height')/2;
    //console.log(widthMod);
    var coordX = position.left+widthMod;
    var coordY = position.top+heightMod;
    // dx and dy are the vextor from the mouse to the rect
    var dx = coordX - mouseX;
    var dy = coordY - mouseY;
    // distance from the mouse
    var distanceSquared = (dx * dx + dy * dy);
    var tx = 0, ty = 0;
    // if the rect is within range...
    // Note that we are comparing the squared values to avoid unnecessary sqrt() calls
    if (distanceSquared < theRangeSquared && distanceSquared != 0)
    {
        $(this).attr('fill','#000000');
        // Calculate shift scale (inverse of distance)
        var shift = maxOffset * (theRangeSquared - distanceSquared) / theRangeSquared;
        // Now calculate the translation vector.
        // We normalise the dx,dy vector by dividing by its length (distance),
        // then we multiply it by the shift scale
        var distance = Math.sqrt(distanceSquared);
        tx = shift * dx / distance;
        ty = shift * dy / distance;
    }else{
        $(this).attr('fill','#A4131C');
    }
    // Set a transform on the rect to translate it by our vector tx,ty
    $(this).attr('transform', "translate(" + tx + " " + ty + ")");
});

 $( "svg" ).mousemove(function( event ) { var mouseX = event.pageX; var mouseY = event.pageY; var theRangeSquared = 75 * 75; var maxOffset = 20; $('rect').each(function(){ var position = $(this).position(); var widthMod = $(this).attr('width')/2; var heightMod = $(this).attr('height')/2; //console.log(widthMod); var coordX = position.left+widthMod; var coordY = position.top+heightMod; // distance from mouse var dx = coordX - mouseX; var dy = coordY - mouseY; var distanceSquared = (dx * dx + dy * dy); var tx = 0, ty = 0; if (distanceSquared < theRangeSquared && distanceSquared != 0) { $(this).attr('fill','#000000'); // Calculate shift scale (inverse of distance) var shift = maxOffset * (theRangeSquared - distanceSquared) / theRangeSquared; var distance = Math.sqrt(distanceSquared); tx = shift * dx / distance; ty = shift * dy / distance; }else{ $(this).attr('fill','#A4131C'); } $(this).attr('transform', "translate(" + tx + " " + ty + ")"); }); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <svg version="1.1" baseProfile="tiny" id="Laag_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="380.098px" height="369.383px" viewBox="0 0 380.098 369.383" xml:space="preserve"> <rect x="14.172" y="14.177" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="60.004" y="14.177" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.929" height="30.93"/> <rect x="105.836" y="14.177" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="151.668" y="14.177" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="197.5" y="14.177" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="243.331" y="14.177" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="289.163" y="14.177" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="334.995" y="14.177" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="14.172" y="58.477" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="60.004" y="58.477" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.929" height="30.93"/> <rect x="105.836" y="58.477" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="151.668" y="58.477" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="197.5" y="58.477" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="243.331" y="58.477" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="289.163" y="58.477" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="334.995" y="58.477" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="14.172" y="102.777" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="60.004" y="102.777" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.929" height="30.93"/> <rect x="105.836" y="102.777" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="151.668" y="102.777" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="197.5" y="102.777" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="243.331" y="102.777" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="289.163" y="102.777" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="334.995" y="102.777" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="14.172" y="147.077" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="60.004" y="147.077" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.929" height="30.93"/> <rect x="105.836" y="147.077" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="151.668" y="147.077" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="197.5" y="147.077" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="243.331" y="147.077" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="289.163" y="147.077" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="334.995" y="147.077" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="14.172" y="191.376" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.929"/> <rect x="60.004" y="191.376" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.929" height="30.929"/> <rect x="105.836" y="191.376" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.929"/> <rect x="151.668" y="191.376" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.929"/> <rect x="197.5" y="191.376" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.929"/> <rect x="243.331" y="191.376" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.929"/> <rect x="289.163" y="191.376" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.929"/> <rect x="334.995" y="191.376" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.929"/> <rect x="14.172" y="235.676" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="60.004" y="235.676" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.929" height="30.93"/> <rect x="105.836" y="235.676" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="151.668" y="235.676" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="197.5" y="235.676" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="243.331" y="235.676" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="289.163" y="235.676" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="334.995" y="235.676" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="14.172" y="279.976" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="60.004" y="279.976" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.929" height="30.93"/> <rect x="105.836" y="279.976" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="151.668" y="279.976" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="197.5" y="279.976" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="243.331" y="279.976" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="289.163" y="279.976" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="334.995" y="279.976" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="14.172" y="324.276" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="60.004" y="324.276" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.929" height="30.93"/> <rect x="105.836" y="324.276" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="151.668" y="324.276" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="197.5" y="324.276" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="243.331" y="324.276" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="289.163" y="324.276" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> <rect x="334.995" y="324.276" fill="#A4131C" stroke="#000000" stroke-width="0.2182" stroke-miterlimit="10" width="30.93" height="30.93"/> </svg> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM