提问者:小点点

在SVG模式上转换原点在Firefox/Safari上不工作


我制作了一个带有SVG图案的六边形网格。

为了放大,我使用了Transform的缩放函数,并保持它从我设置的中心transform-origin到页面中心的缩放。

这在Chrome上很好用,但在Safari和Firefox上就不行了。 我怎样才能使它在所有浏览器上工作?

这是我目前所做的:

null

const pattern = document.getElementById('hexagons');
const center = {
  x: window.innerWidth / 2,
  y: window.innerHeight / 2
};
const transformOrigin = `${center.x}px ${center.y}px`;
let zoom = 1;

const formatPatternTransform = (zoom) => `rotate(90) scale(${zoom})`;

function animate() {
  if (zoom > 3)
    return;

  zoom += .005;
  pattern.setAttribute('patternTransform', formatPatternTransform(zoom));
  requestAnimationFrame(animate);
}

pattern.setAttribute('transform-origin', transformOrigin);
animate();
* {
  margin: 0;
  padding: 0;
}

svg {
  background: #0a0a0a;
  height: 100vh;
  width: 100vw;
}
<svg ref="svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%">
    <defs>
      <pattern
        id="hexagons"
        ref="pattern"
        width="50"
        height="43.4"
        patternUnits="userSpaceOnUse"
        patternTransform="rotate(90)"
        x="50%"
        y="50%"
      >
        <polygon
          id="hex"
          points="24.8,22 37.3,29.2 37.3,43.7 24.8,50.9 12.3,43.7 12.3,29.2"
          fill="#0a0a0a"
          stroke="#222"
        />
        <use xlink:href="#hex" x="25" />
        <use xlink:href="#hex" x="-25" />
        <use xlink:href="#hex" x="12.5" y="-21.7" />
        <use xlink:href="#hex" x="-12.5" y="-21.7" />
      </pattern>
    </defs>
    <rect id="mosaic" width="100%" height="100%" fill="url(#hexagons)" />
  </svg>

null


共2个答案

匿名用户

为什么不简单地扩展整个SVG:

null

* {
  margin: 0;
  padding: 0;
}

svg {
  position:fixed;
  top:0;
  left:0;
  width:100%;
  height:100%;
  background: #0a0a0a;
  animation:zoom 3s ease-out forwards
}

@keyframes zoom {
  to {
     transform:scale(3);
  }
}
<svg ref="svg" xmlns:xlink="http://www.w3.org/1999/xlink" >
    <defs>
      <pattern
        id="hexagons"
        ref="pattern"
        width="50"
        height="43.4"
        patternUnits="userSpaceOnUse"
        patternTransform="rotate(90)"
        x="50%"
        y="50%"
      >
        <polygon
          id="hex"
          points="24.8,22 37.3,29.2 37.3,43.7 24.8,50.9 12.3,43.7 12.3,29.2"
          fill="#0a0a0a"
          stroke="#222"
        />
        <use xlink:href="#hex" x="25" />
        <use xlink:href="#hex" x="-25" />
        <use xlink:href="#hex" x="12.5" y="-21.7" />
        <use xlink:href="#hex" x="-12.5" y="-21.7" />
      </pattern>
    </defs>
    <rect id="mosaic" width="100%" height="100%" fill="url(#hexagons)" />
  </svg>

匿名用户

这是一个可供选择的解决方案。 您可以将置于svg画布原点的中心,而不是使用transform-origin。 在这种情况下,您需要一个viewBox属性:viewBox=“-250-250 500 500”preserveaspectratio=“xmidymid slice”

"xMidYMid (the default) - Force uniform scaling.
Align the midpoint X value of the element's viewBox with the midpoint X value of the viewport.
Align the midpoint Y value of the element's viewBox with the midpoint Y value of the viewport."

"slice - Scale the graphic such that:
aspect ratio is preserved
the entire viewport is covered by the viewBox
the viewBox is scaled down as much as possible, while still meeting the other criteria"

这是填满图案的矩形:

<rect id="mosaic" x="-250" y="-250" width="500" height="500" fill="url(#hexagons)" />

接下来是一个工作示例:

null

const pattern = document.getElementById('hexagons');
const center = {
  x: window.innerWidth / 2,
  y: window.innerHeight / 2
};
//const transformOrigin = `${center.x}px ${center.y}px`;
let zoom = 1;

const formatPatternTransform = (zoom) => `rotate(90) scale(${zoom})`;

function animate() {
  if (zoom > 3)
    return;

  zoom += .005;
  pattern.setAttribute('patternTransform', formatPatternTransform(zoom));
  requestAnimationFrame(animate);
}

//pattern.setAttribute('transform-origin', transformOrigin);
animate();
* {
  margin: 0;
  padding: 0;
}

svg {
  background: #0a0a0a;
  height: 100vh;
  width: 100vw;
}
<svg ref="svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-250 -250 500 500" preserveAspectRatio="xMidYMid slice">
    <defs>
      <pattern
        id="hexagons"
        ref="pattern"
        width="50"
        height="43.4"
        patternUnits="userSpaceOnUse"
        patternTransform="rotate(90)"
        x="50%"
        y="50%"
      >
        <polygon
          id="hex"
          points="24.8,22 37.3,29.2 37.3,43.7 24.8,50.9 12.3,43.7 12.3,29.2"
          fill="#0a0a0a"
          stroke="#222"
        />
        <use xlink:href="#hex" x="25" />
        <use xlink:href="#hex" x="-25" />
        <use xlink:href="#hex" x="12.5" y="-21.7" />
        <use xlink:href="#hex" x="-12.5" y="-21.7" />
      </pattern>
    </defs>
    <rect id="mosaic" x="-250" y="-250" width="500" height="500" fill="url(#hexagons)" />
  </svg>