为了账号安全,请及时绑定邮箱和手机立即绑定

svg 上的矩阵变换:意外行为

svg 上的矩阵变换:意外行为

潇湘沐 2021-12-02 16:55:37
我有一个 div,其中包含一个 300x300 像素的 SVG 图像和一个 1000x1000 的视图框。该图像描述了一个位于红色矩形之上的蓝色矩形。当我移动鼠标时,一个圆圈跟随图像内的鼠标位置:一切都很完美,除了当我应用变换改变透视和旋转时,鼠标指针和圆心不再匹配:代码在这里:$(function() {  $('#image').mousemove(function(event) {    var svg = document.querySelector('svg');    var pt = svg.createSVGPoint();    pt.x = event.clientX;    pt.y = event.clientY;    pt = pt.matrixTransform(svg.getScreenCTM().inverse());    overlay = document.getElementById('overlay');    $('#overlay').html(      "<circle cx='" + pt.x + "' cy='" + pt.y + "' r='50' stroke='#8f00ff' fill='transparent' stroke-width='10' /></svg>"    );    refresh = $("#overlay").html();    $("#overlay").html( refresh )  });});function Transform() {  $('#image').css({    transformOrigin: '500px 500px',    transform: 'perspective(100px) rotateX(5deg)'  });}<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><div id='image' tabindex='0' >  <svg id='svgmap' width='300' height='300' xmlns='http://www.w3.org/2000/svg' version='1.1' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 1000 1000'>    <rect x='0' y='0' width='1000' height='1000' fill='red' />    <rect x='250' y='250' width='500' height='500' stroke='yellow' fill='blue' stroke-width='10' />    <g id='overlay'></g>  </svg></div><button onclick='Transform()'>Transform</button>我的目标是保持紫色圆圈中心和鼠标指针之间的匹配,即使对对象应用了变换。有没有办法做到这一点?
查看完整描述

2 回答

?
牛魔王的故事

TA贡献1830条经验 获得超3个赞

在您的代码中#image是一个 div。为了使其工作,您需要将转换应用于 svg 元素 (#svgmap),并且转换必须是 svg 转换。


$(function() {

  $('#svgmap').mousemove(function(event) {

    var svg = document.querySelector('svg');

    var pt = svg.createSVGPoint();

    pt.x = event.clientX;

    pt.y = event.clientY;

    pt = pt.matrixTransform(svg.getScreenCTM().inverse());

    overlay = document.getElementById('overlay');

    $('#overlay').html(

      "<circle cx='" + pt.x + "' cy='" + pt.y + "' r='50' stroke='#8f00ff' fill='transparent' stroke-width='10' /></svg>"

    );

    refresh = $("#layer_wafer").html();

    $("#layer_wafer").html( refresh )

  });

});

function Transform() {

  svgmap.setAttributeNS(null,"transform", "skewX(-20) translate(100)");

}

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id='image' tabindex='0' >

  <svg id='svgmap' width='300' height='300' xmlns='http://www.w3.org/2000/svg' version='1.1' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 1000 1000' transform="">

    <rect x='0' y='0' width='1000' height='1000' fill='red' />

    

    <rect x='250' y='250' width='500' height='500' stroke='yellow' fill='blue' stroke-width='10' />

    <g id='overlay'></g>

  </svg>

</div>

<button onclick='Transform()'>Transform</button>

我知道您需要 3D css 转换,但这(至少现在)不起作用。

这是一篇文章,您可以在其中阅读有关 svg 中 3d 变换的更多信息:https : //oreillymedia.github.io/Using_SVG/extras/ch11-3d.html在文章中您可以阅读:本节中描述的所有 3D 变换函数应该被视为“未来”


查看完整回答
反对 回复 2021-12-02
?
凤凰求蛊

TA贡献1825条经验 获得超4个赞

我已经以最丑陋的方式解决了这个问题。只需将鼠标光标隐藏在 div 上即可。丑陋的。但有效。


$(function() {

  $('#image').mousemove(function(event) {

    var svg = document.querySelector('svg');

    var pt = svg.createSVGPoint();

    pt.x = event.clientX;

    pt.y = event.clientY;

    pt = pt.matrixTransform(svg.getScreenCTM().inverse());

    overlay = document.getElementById('overlay');

    $('#overlay').html(

      "<circle cx='" + pt.x + "' cy='" + pt.y + "' r='50' stroke='#8f00ff' fill='transparent' stroke-width='10' /></svg>"

    );

    refresh = $("#overlay").html();

    $("#overlay").html( refresh )

  });

});

function Transform() {

  $('#image').css({

    transformOrigin: '500px 500px',

    transform: 'perspective(100px) rotateX(5deg)'

  });

}

div#image {

  cursor: none;

}

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id='image' tabindex='0' >

  <svg id='svgmap' width='300' height='300' xmlns='http://www.w3.org/2000/svg' version='1.1' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 1000 1000'>

    <rect x='0' y='0' width='1000' height='1000' fill='red' />

    <rect x='250' y='250' width='500' height='500' stroke='yellow' fill='blue' stroke-width='10' />

    <g id='overlay'></g>

  </svg>

</div>

<button onclick='Transform()'>Transform</button>


我必须做一些优化以减少 DIV 上方和任何其他页面元素之间的鼠标光标位置差距,但这对我来说是可以接受的。


查看完整回答
反对 回复 2021-12-02
  • 2 回答
  • 0 关注
  • 259 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信