Преобразование происхождения по шаблону SVG не работает в Firefox / Safari - PullRequest
0 голосов
/ 16 июня 2020
• 1000 1004 *

Это отлично работает с Chrome, но не с Safari и Firefox. Как мне заставить его работать во всех браузерах?

Вот что я сделал на данный момент:

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>

Ответы [ 2 ]

2 голосов
/ 16 июня 2020

Это альтернативное решение. Вместо использования transform-origin вы можете центрировать <rect id="mosaic" вокруг исходной точки холста svg. В этом случае вам понадобится атрибут 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)" />

Далее идет рабочий пример :

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>
2 голосов
/ 16 июня 2020

почему бы просто не масштабировать весь SVG:

* {
  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>

Чтобы избежать лагов, вы можете оставить JS код:

let s = document.querySelector('svg');
let zoom = 1;

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

  zoom += .005;
  s.style.transform = "scale(" + zoom + ")";
  requestAnimationFrame(animate);
}

animate();
* {
  margin: 0;
  padding: 0;
}

svg {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: #0a0a0a;
}
<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>

Вы также можете легко уменьшить масштаб:

let s = document.querySelector('svg');
let zoom = 1;

function animate() {
  if (zoom < 0.2)
    return;

  zoom -= .005;
  s.style.transform = "scale(" + zoom + ")";
  requestAnimationFrame(animate);
}

animate();
* {
  margin: 0;
  padding: 0;
}

svg {
  position:fixed;
  top:-300%;
  left:-300%;
  width:700%;
  height:700%;
  background: #0a0a0a;
}
<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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...