【问题标题】:How do I offset an element based on my mouse position?如何根据鼠标位置偏移元素?
【发布时间】:2015-06-08 13:43:54
【问题描述】:

我在一个 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)))

这句话可能需要一些改进。

下一步是根据我的鼠标位置更改&lt;rect&gt; 元素的位置。影响最接近鼠标的元素最强。

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

此时我被困在需要根据鼠标位置偏移&lt;rect&gt; 元素的部分。

FIDDLE

【问题讨论】:

    标签: jquery css svg jquery-animate offset


    【解决方案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>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-21
      • 1970-01-01
      • 2013-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多