在Firefox中使用变换原点时,SVG元素会移动 [英] SVG element shifts when using transform-origin in Firefox

查看:187
本文介绍了在Firefox中使用变换原点时,SVG元素会移动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有这个蓝图,我已经重新创建了SVG。



这是 codepen

在Chrome中一切正常,但在Firefox中,一次门上的旋转动画结束,门本身(旋转的元件)从其原始位置水平地向右或垂直地移动到底部。换句话说,将旋转应用于 transition (即 rotate(90deg) ...)的元素... wait ... rotate(0))看起来会导致元素从正确的位置移动。 水平门会垂直移动,垂直门会水平移动。超级怪异。



这个问题最重要的是刷新浏览器完成。



这是一个MVCE ,作为按要求。

MVCE已更新。这是尽可能最小,而仍然产生垂直和水平移动的问题。

  var fillElements = document.getElementsByClassName('f'); var fillElement; var fillElementId; for(i = 0; i< fillElements.length; i ++){fillElements [i] .addEventListener('mouseenter',emphasisizeRoom); fillElements [i] .addEventListener('mouseleave',deEmphasizeRoom);}函数putsizeRoom(){fillElement = this; fillElementId = fillElement.id; changeOpacity(); animateDoors();} function changeOpacity(){fillElement.style.opacity ='0.1';}函数animateDoors(){var dashedRoomName = fillElement.id.replace(fillElementId.substring(0,1)+'-f-', ''); var horDoor ='g-o-construction-shop-stage-one-door-right-top'; var verDoor ='g-o-construction-shop-paint-shop-door-bottom-right'; var doorElement;如果(horDoor.includes(dashedRoomName)){doorElement = document.getElementById(horDoor); } else if(verDoor.includes(dashedRoomName)){doorElement = document.getElementById(verDoor); } doorElement.style.transform ='rotate(90deg)'; setTimeout(function(){doorElement.style.transform ='rotate(0)';},750);} function deEmphasizeRoom(){this.style.opacity = 0;}  

svg {position:absolute; left:324px;顶部:300px; transform:scale(3);}。o-whole,.door {stroke:#000;填充:无; opacity:1;} .f {fill:#ff6600; opacity:0;} .o-door-right-top,.o-door-bottom-right {transition:transform 0.75s;}

 < body> <?xml version =1.0encoding =UTF-8standalone =no?> < svg width =320height =304viewBox =0 0 320 304id =svg> < g id =ground><! - 整体外观 - > < path id =go-wholeclass =o-wholed =M 108,266.5 H 98 m 55,-259 h 5 m -49,239 h 7 M 108.5,47 v -2 m 153,31 v 1.5 h 1 V 76 m -1.5,48.5 h 1.5 v 1 H 261 m 0.5,48.5 v -1.5 h 1 v 1.5 m 0,48 v -1.5 h -1 v 1.5 m -102,-31 v 1.5 h 1 V 191 m 0.5,-44.5 h -1.5 v -1 H 161 M 159.5,99 v 1.5 h 1 V 99 M 161,53.5 h -1.5 v 1 H 161 M 74.5,26 v 1.5 h 1 V 26 M 40,26.5 h 1.5 v 1 H 40 M 74.5,47 V 1.5 h 1 V 47 m -35,2 v -1.5 h 1 V 49 M 40.68.5 h 1.5 v 1 H 40 M 75.5,68 v 1.5 h -1 V 68 M 74,89.5 h 1.5 v 1 H 74 m -32,0 h -1.5 v -1 H 42 M 74.5,110 v 1.5 h 1 V 110 M 42,110.5 h -1.5 v 1 H 42 M 40.5,131 v 1.5 h 1 V 131 m 34.5 ,1.5 h -1.5 v -1 H 76 M 41.5,194 v -1.5 h -1 v 1.5 m 35,21 v 1.5 h -1 V 215 m -34,2 v -1.5 h 1 V 217 M 74,193.5 h 1.5 v -1 H 74 m -32,47 h -1.5 v -1 H 42 M 211.5,220 V 43 m -103,143 v -8 M 260,284.5 h 7 m -7,-2 h 7 m -7,-2 h 7 m -7,-2 h 7 m -7,-2 h 7 m -7,-2 h 7 m -7,-2 h 7 m -7,-2 h 7 m 0.5,10.5 V 269 M 2​​11,247.5 h 18 M 211.5,239 v 28 m 35.5,-8.5 h -17.5 v -11 h 18 v 2.5 m 0,19 v -13 m -2.5,13.5 h 5 m -54,13 h 7 m -7,-2 h 7 m -7,-2 h 6.98438 M 196,276.5 h 7 m 1,-1 h 7 m -7,2 h 7 m -7,2 h 7 m -7,2 h 7 m -7,2 h 7 m -15 1 h 7.5 V 275 m 8,20 v -27.5 h -16 V 287 M 209,238.5 h 2.5 V 232 m -13.5,6.5 h 5 m -41,0 h 20 m -41,0 h 5 m -20,20 h 6.5 v -20 h 2.5 m -6.5,34.5 v -14 m -18, 0 v 7 m 2,-7 v 7 m 2,-7 v 7 m 2,-7 v 7 m -8,-7 v 7.5 h 9.5 m -10,-8 H 97.5 V 287 m 11,-31 v 2.5 H 120 M 64.5,262 V -21.5 H 11 V 9.5 M 0,20 V 14 M 86,269.5 H 75.5 V 263 M 86,258.5 H 76 m -14,4 H 75.5 V 256 m -11,20 v -13 m 22, 15 v 6.5 h -22 V 282 m 22,-15 v 5 m 0,-16 v 5 m -44,2 v 10.5 H 53 M 31.5,284 v -21 m 22,19 v 2.5 h -22 v 2.5 m 22,-16 v 5 M 53,262.5 H 7 m 46.5,2.5 v -2.5 H 56 m 53,-40 h 7 m -7,2 h 7 m -7,2 h 7 m -7,2 h 7 m -7 ,2小时7分钟-7小时7分钟-7小时7分钟-7小时7分钟-7小时7分钟-7小时7分钟-7小时7分钟-7, 2小时7分钟-7小时-33小时7.5小时248分钟-8小时-1分钟-45分钟-22.48小时-2.5小时22分钟2.5小时0分钟-81小时8.5小时104分钟94.5分钟16.5小时16.5小时98 M 108.5,160 v 3 M 92,151.5 h 2.5 v 9 H 108 m -13,-11 h 13.5 V 14 7 M 108,138.5 H 94.5 V 151 m 14,-15 v 5 M 73,170.5 H 83.5 V 152 m -11,0 v 18.5 H 62 m 19,-19 h 5 m -16,0 h 5 M 50.5,163 v 7 m -2,-7v 7m -2,-7v 7m -2,-7v 7m -2,-7v 7m -2,-7v 7m -2,-7v 7m -2 ,-7 v 7 m -2,-7 v 7 m -2,-7 v 7 m -2,-7 v 7 m -2,-7 v 7 m -2,-7 v 7 m -2, - 7 v 7 m -2,-7 v 7 m -2,-7 v 7 m -2,-7 v 7 M 15,170.5 H 61.5 V 163 m -11,-9 v -2.5 H 61 M 50.5,160 v 2.5 h 11 v -11 H 64 M 28.5,151 V 140.5 H 26 m -19,11 h 10.5 v 11 H 28 m 12,0 H 50 M 39.5,160 v 2.5 h -11 v -11 h 11 v 2.5 m 69 ,-34 v 10 m 0,-51 v 25 m 0,-51 v 10 m 92,-55 V 20.5 H 211 m -110,13 h 7 m -7,-2 h 7 m -7,-2 h 7 m -7,-2 h 7 m -7,-2 h 7 m -7,-2 h 7 m -7,-2 h 7 m -7,-2 h 7 m 1,14 h 10.5 V 36 m 0,6 v 2.5 H 109 M 92.5,16 v 2.5 h 8 v 26 h 8 v -26 h 8 V 16 M 6.5,90 V 25 m 0.89 V 96 M 7,140.5 h 7 M 6.5,154 V 130 M 9,170.5 H 6.5 V 160 M 9,295.5 H 6.5 V 202 m 0,-16 v -15 m 25,122 v 2.5 H 15 m 92,-8 h -9.5 v 8 H 95 m -6,0 H 32 M 128.5,285 v 2.5 H 119 m 76.8 H 128.5 V 288 m 74.5,7.5 h -7.5 V 293 m 41,-5 v 7.5 H 209 m 33 ,-8小时-5.5小时-18小时239小时259.5287小时269.5小时256毫秒53小时,-240小时4.5小时266小时-25小时-14小时-21小时14小时-8小时-8小时254毫米40小时, -258小时5分钟-20.0小时5分钟-22.0小时7分钟-27.0小时4分钟-23.13小时10.5分钟30分钟231.29.5小时5分钟-16.0小时5分钟-11分钟0 h -2.5 v 13 h 11 V 30 M 209.7.5 h 2.5 V 29 M 198.7.5 h 5 m -20.0 h 5 m -20.0 h 5 m -35,0 h 5 m -25.98959, 0 H 122 m -15,0 h 9.5 V 10 m -24.0 V 7.5 h 8.5 m -32,0 H 92 M 6.5,19 V 7.5 H 47  - ><! -  FILL  - > <路径id =gf-construction-shopclass =fd =M 39,152 H 28 V 141 H 6 V 7 h 87 v 11 h 8 v 26 h 8 v 95 H 95 v 13 H 51 v 11 H 39 c 0,-3.36991 0,-7.34493 0,-11 z/> < path id =gf-paint-shopclass =fd =M 65,263 H 6 v -93 h 77 v -19 h 12 v 26 h 14 v 71 H 87 v 11 H 75 V 241 H 65 Z/> < path id =gf-stage-1class =fd =M 133,259 H 108 V 44 h 11 V 34 H 108 V 18 h 8 V 7 h 85 v 13 h 11 v 219 h -79 z /><! -  DOORS  - > <! - 横向 - > <路径id =g-o-construction-shop-stage-one-door-right-topclass =door o-door-right-topstyle =transform-origin:108.5px 130.5px; d =m 108,130.5 h 5.99996/> <! -  vertical  - > < path id =g-o-construction-shop-paint-shop-door-bottom-rightclass =door o-door-bottom-rightstyle =transform-origin:91.5px 151.5px; d =m 91.5,151 v 5.99996/> < / g取代; < / svg>< / body>< / html>  

h2_lin>解决方案

看起来像FF中的一个bug。 我已经在这里汇报



要解决这个bug,你不想在Firefox中使用不同的 transform-origin 坐标。因为当错误得到修复的时候,错误会再次出现。

这个错误似乎是转换过程中的一个舍入误差(门移动了0.5个SVG单位)。所以,显而易见的解决方案是缩小所有的坐标,以便0.5单位的移动不再显而易见。例如,如果乘以坐标10,它似乎工作(转变变得更不明显)。如果这个错误在将来得到解决,你将不需要改变任何东西。



  var room = document.getElementById('gf-construction-shop'); room.addEventListener('mouseenter',function animateDoors(){var doorElement = document.getElementById('go-construction-shop-stage-one ();}};;}};}}; / code> 

.o-whole,.door {stroke:#000;笔画宽度:10;填充:无; opacity:1;} .f {fill:#ff6600; opacity:0.1;} .o-door-right-top {transition:transform 0.75s;}

 < svg width =500height =500viewBox =1050 1250 200 200id =svg> < g id =ground> <! - 房间外观 - > < path class =o-wholed =M 1085,1200 v 100/> <! - 房间填充 - > < rect id =g-f-construction-shopclass =fwidth =1090height =2000/> <! - 门 - >> < path id =g-o-construction-shop-stage-one-door-right-topclass =door o-door-right-topstyle =transform-origin:1085px 1305px; d =m 1080,1305 h 60/> < circle cx =1085cy =1305r =2fill =limegreen/> < / g取代; < / svg>  


So I have this blueprint that I've recreated as an SVG.

Here is the codepen!

Everything works fine in Chrome, but in Firefox, once the rotation animation on the doors finishes, the doors themselves (the rotated elements) shift from their original positions either horizontally to the right or vertically to the bottom. In other words, applying rotation to an element with transition (i.e. rotate(90deg) ...wait... rotate(0)) seemingly causes the element to shift from its proper position. Horizontal doors will shift vertically and vertical doors will shift horizontally. Super bizarre.

The issue is most noticeable after refreshing the browser once the animation has completed.

Here is an MVCE, as per requested.

The MVCE has been updated. It is as minimal as possible, while still producing the issue of shifting vertically and horizontally.

var fillElements = document.getElementsByClassName('f');
var fillElement;
var fillElementId;
for (i = 0; i < fillElements.length; i++) {
  fillElements[i].addEventListener('mouseenter', emphasizeRoom);
  fillElements[i].addEventListener('mouseleave', deEmphasizeRoom);
}
function emphasizeRoom() {
  fillElement = this;
  fillElementId = fillElement.id;
  changeOpacity();
  animateDoors();
}
function changeOpacity() {
  fillElement.style.opacity = '0.1';
}

function animateDoors() {
  var dashedRoomName = fillElement.id.replace(fillElementId.substring(0, 1) + '-f-', '');
  var horDoor = 'g-o-construction-shop-stage-one-door-right-top';
  var verDoor = 'g-o-construction-shop-paint-shop-door-bottom-right';
  var doorElement;

  if (horDoor.includes(dashedRoomName)) {
    doorElement = document.getElementById(horDoor);
  } else if (verDoor.includes(dashedRoomName)) {
    doorElement = document.getElementById(verDoor);
  }
  
  doorElement.style.transform = 'rotate(90deg)';
    
  setTimeout(function () {
    doorElement.style.transform = 'rotate(0)';
  }, 750);
}
  
function deEmphasizeRoom() {
  this.style.opacity = 0;
}

svg {
  position: absolute;
  left: 324px;
  top: 300px;
  transform: scale(3);
}

.o-whole, .door {
  stroke: #000;
  fill: none;
  opacity: 1;
}
  
.f {
  fill: #ff6600;
  opacity: 0;
}
  
.o-door-right-top, .o-door-bottom-right {
  transition: transform 0.75s;
}

<body>
  <?xml version="1.0" encoding="UTF-8" standalone="no"?>
  <svg width="320" height="304" viewBox="0 0 320 304" id="svg">
    <g id="ground">
<!-- WHOLE OUTLINE -->
      <path
         id="g-o-whole"
         class="o-whole"
         d="M 108,266.5 H 98 m 55,-259 h 5 m -49,239 h 7 M 108.5,47 v -2 m 153,31 v 1.5 h 1 V 76 m -1.5,48.5 h 1.5 v 1 H 261 m 0.5,48.5 v -1.5 h 1 v 1.5 m 0,48 v -1.5 h -1 v 1.5 m -102,-31 v 1.5 h 1 V 191 m 0.5,-44.5 h -1.5 v -1 H 161 M 159.5,99 v 1.5 h 1 V 99 M 161,53.5 h -1.5 v 1 H 161 M 74.5,26 v 1.5 h 1 V 26 M 40,26.5 h 1.5 v 1 H 40 M 74.5,47 v 1.5 h 1 V 47 m -35,2 v -1.5 h 1 V 49 M 40,68.5 h 1.5 v 1 H 40 M 75.5,68 v 1.5 h -1 V 68 M 74,89.5 h 1.5 v 1 H 74 m -32,0 h -1.5 v -1 H 42 M 74.5,110 v 1.5 h 1 V 110 M 42,110.5 h -1.5 v 1 H 42 M 40.5,131 v 1.5 h 1 V 131 m 34.5,1.5 h -1.5 v -1 H 76 M 41.5,194 v -1.5 h -1 v 1.5 m 35,21 v 1.5 h -1 V 215 m -34,2 v -1.5 h 1 V 217 M 74,193.5 h 1.5 v -1 H 74 m -32,47 h -1.5 v -1 H 42 M 211.5,220 V 43 m -103,143 v -8 M 260,284.5 h 7 m -7,-2 h 7 m -7,-2 h 7 m -7,-2 h 7 m -7,-2 h 7 m -7,-2 h 7 m -7,-2 h 7 m -7,-2 h 7 m 0.5,10.5 V 269 M 211,247.5 h 18 M 211.5,239 v 28 m 35.5,-8.5 h -17.5 v -11 h 18 v 2.5 m 0,19 v -13 m -2.5,13.5 h 5 m -54,13 h 7 m -7,-2 h 7 m -7,-2 h 6.98438 M 196,276.5 h 7 m 1,-1 h 7 m -7,2 h 7 m -7,2 h 7 m -7,2 h 7 m -7,2 h 7 m -15,1 h 7.5 V 275 m 8,20 v -27.5 h -16 V 287 M 209,238.5 h 2.5 V 232 m -13.5,6.5 h 5 m -41,0 h 20 m -41,0 h 5 m -20,20 h 6.5 v -20 h 2.5 m -6.5,34.5 v -14 m -18,0 v 7 m 2,-7 v 7 m 2,-7 v 7 m 2,-7 v 7 m -8,-7 v 7.5 h 9.5 m -10,-8 H 97.5 V 287 m 11,-31 v 2.5 H 120 M 64.5,262 v -21.5 h 11 v 9.5 m 0,20 v 14 M 86,269.5 H 75.5 V 263 M 86,258.5 H 76 m -14,4 H 75.5 V 256 m -11,20 v -13 m 22,15 v 6.5 h -22 V 282 m 22,-15 v 5 m 0,-16 v 5 m -44,2 v 10.5 H 53 M 31.5,284 v -21 m 22,19 v 2.5 h -22 v 2.5 m 22,-16 v 5 M 53,262.5 H 7 m 46.5,2.5 v -2.5 H 56 m 53,-40 h 7 m -7,2 h 7 m -7,2 h 7 m -7,2 h 7 m -7,2 h 7 m -7,2 h 7 m -7,2 h 7 m -7,2 h 7 m -7,2 h 7 m -7,2 h 7 m -7,2 h 7 m -7,2 h 7 m -7,-33 h 7.5 V 248 m -8,-1 v -45 m -22,48 v -2.5 h 22 v 2.5 m 0,-81 v 8.5 H 104 M 94.5,161 v 16.5 H 98 M 108.5,160 v 3 M 92,151.5 h 2.5 v 9 H 108 m -13,-11 h 13.5 V 147 M 108,138.5 H 94.5 V 151 m 14,-15 v 5 M 73,170.5 H 83.5 V 152 m -11,0 v 18.5 H 62 m 19,-19 h 5 m -16,0 h 5 M 50.5,163 v 7 m -2,-7 v 7 m -2,-7 v 7 m -2,-7 v 7 m -2,-7 v 7 m -2,-7 v 7 m -2,-7 v 7 m -2,-7 v 7 m -2,-7 v 7 m -2,-7 v 7 m -2,-7 v 7 m -2,-7 v 7 m -2,-7 v 7 m -2,-7 v 7 m -2,-7 v 7 m -2,-7 v 7 m -2,-7 v 7 M 15,170.5 H 61.5 V 163 m -11,-9 v -2.5 H 61 M 50.5,160 v 2.5 h 11 v -11 H 64 M 28.5,151 V 140.5 H 26 m -19,11 h 10.5 v 11 H 28 m 12,0 H 50 M 39.5,160 v 2.5 h -11 v -11 h 11 v 2.5 m 69,-34 v 10 m 0,-51 v 25 m 0,-51 v 10 m 92,-55 V 20.5 H 211 m -110,13 h 7 m -7,-2 h 7 m -7,-2 h 7 m -7,-2 h 7 m -7,-2 h 7 m -7,-2 h 7 m -7,-2 h 7 m -7,-2 h 7 m 1,14 h 10.5 V 36 m 0,6 v 2.5 H 109 M 92.5,16 v 2.5 h 8 v 26 h 8 v -26 h 8 V 16 M 6.5,90 V 25 m 0,89 V 96 M 7,140.5 h 7 M 6.5,154 V 130 M 9,170.5 H 6.5 V 160 M 9,295.5 H 6.5 V 202 m 0,-16 v -15 m 25,122 v 2.5 H 15 m 92,-8 h -9.5 v 8 H 95 m -6,0 H 32 M 128.5,285 v 2.5 H 119 m 76,8 H 128.5 V 288 m 74.5,7.5 h -7.5 V 293 m 41,-5 v 7.5 H 209 m 33,-8 h -5.5 v -18 H 239 M 259.5,287 V 269.5 H 256 m 53,-240 h 4.5 v 266 h -25 v -14 h -21 v 14 h -8 v -8 H 254 m 40,-258 h 5 m -20,0 h 5 m -22,0 h 7 m -27,0 h 4 m -23,13 h 10.5 V 30 M 231,29.5 h 5 m -16,0 h 5 m -11,0 h -2.5 v 13 h 11 V 30 M 209,7.5 h 2.5 V 29 M 198,7.5 h 5 m -20,0 h 5 m -20,0 h 5 m -35,0 h 5 m -25.98959,0 H 122 m -15,0 h 9.5 V 10 m -24,0 V 7.5 h 8.5 m -32,0 H 92 M 6.5,19 V 7.5 H 47" />
<!-- FILL -->
      <path id="g-f-construction-shop" class="f"
         d="M 39,152 H 28 V 141 H 6 V 7 h 87 v 11 h 8 v 26 h 8 v 95 H 95 v 13 H 51 v 11 H 39 c 0,-3.36991 0,-7.34493 0,-11 z" />
      <path id="g-f-paint-shop" class="f"
         d="M 65,263 H 6 v -93 h 77 v -19 h 12 v 26 h 14 v 71 H 87 v 11 H 75 V 241 H 65 Z" />
      <path id="g-f-stage-one" class="f"
         d="M 133,259 H 108 V 44 h 11 V 34 H 108 V 18 h 8 V 7 h 85 v 13 h 11 v 219 h -79 z" />
<!-- DOORS -->
      <!-- horizontal -->
      <path
         id="g-o-construction-shop-stage-one-door-right-top"
         class="door o-door-right-top"
         style="transform-origin:108.5px 130.5px;"
         d="m 108,130.5 h 5.99996"
      />
      <!-- vertical -->
      <path
         id="g-o-construction-shop-paint-shop-door-bottom-right"
         class="door o-door-bottom-right"
         style="transform-origin:91.5px 151.5px;"
         d="m 91.5,151 v 5.99996"
      />
    </g>
  </svg>
</body>
</html>

解决方案

Looks like a bug in FF. I have reported it here.

To work around this bug, you wouldn't want to use different transform-origin coordinates in Firefox. Because when the bug gets fixed it'll be wrong again.

The fault seems to be a rounding error in the transformation (the door shifts by 0.5 SVG units). So the obvious solution is to scale all the coordinates up so that a shift of 0.5 units won't be noticeable any more.

For instance, if you multiply the coords by 10, it seems to work (shift becomes much less noticeable). And if the bug gets fixed in the future, you won't need to change anything.

var room = document.getElementById('g-f-construction-shop');

room.addEventListener('mouseenter', function animateDoors() {
  var doorElement = document.getElementById('g-o-construction-shop-stage-one-door-right-top');
  doorElement.style.transform = 'rotate(90deg)';
    
  setTimeout(function () {
    doorElement.style.transform = 'rotate(0)';
  }, 750);
});

.o-whole, .door {
  stroke: #000;
  stroke-width: 10;
  fill: none;
  opacity: 1;
}
  
.f {
  fill: #ff6600;
  opacity: 0.1;
}
  
.o-door-right-top {
  transition: transform 0.75s;
}

  <svg width="500" height="500" viewBox="1050 1250 200 200" id="svg">
    <g id="ground">
      <!-- ROOM OUTLINE -->
      <path class="o-whole" d="M 1085,1200 v 100" />
      <!-- ROOM FILL -->
      <rect id="g-f-construction-shop" class="f" width="1090" height="2000"/>
      <!-- DOOR -->
      <path
         id="g-o-construction-shop-stage-one-door-right-top"
         class="door o-door-right-top"
         style="transform-origin:1085px 1305px;"
         d="m 1080,1305 h 60"
      />
      <circle cx="1085" cy="1305" r="2" fill="limegreen"/>
    </g>
  </svg>

这篇关于在Firefox中使用变换原点时,SVG元素会移动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆