如何根据鼠标位置偏移元素?

时间:2015-06-08 13:43:54

标签: jquery css svg jquery-animate offset

我在SVG中有一些包含<rect>个元素的网格。我试图根据鼠标的位置来偏移元素。因此,当我的鼠标位于元素的某个范围内时,元素就会远离我的鼠标。

靠近鼠标的物品应远离外部范围内的元素。

到目前为止,我已设法使用以下if / else语句在鼠标的某个范围内定位矩形:

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

这句话可能会有所改善。

下一步是根据我的鼠标位置改变<rect>元素的位置。影响最接近鼠标的元素最强。

else语句应该将元素恢复到原始位置。当鼠标离开目标范围时会触发此语句。

此时我被困在需要根据鼠标位置偏移<rect>元素的部分。

FIDDLE

1 个答案:

答案 0 :(得分:1)

您只需计算从指针到每个方块的距离,然后使用transform根据指针的距离将指针移离指针。

$('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>