Настроить поведение SVG viewBox с помощью JavaScript - PullRequest
0 голосов
/ 07 мая 2019

Я использую ванильный JavaScript для навигации по страницам комиксов.Однако мне нужно установить условие, которое проверяет, пересекаются ли точки в текущем многоугольнике с точками в следующем многоугольнике.Если true, я хочу, чтобы viewBox анимировал от текущих точек к следующим точкам, если false, то ничего не происходит (используйте переход затухания по умолчанию).

Вот часть моего кода

var DELAY = 400;

function nextArea() {
    if (isFirstPage() || areaIndex >= areas.length - 1) {
      changePage(true);
      changeArea();
    } else {
      fade();
      areaIndex++;
      setTimeout(changeArea, DELAY);
    }
  }

  function prevArea() {
    if (isLastPage() || areaIndex <= 0) {
      changePage(false);
      changeArea();
    } else {
      fade();
      areaIndex--;
      setTimeout(changeArea, DELAY);
    }
  }

  function changeArea() {
    if (isFirstPage() || isLastPage()) {
      return;
    }

    var activeArea = areas[areaIndex];
    var points = activeArea.getAttribute('points').split(' ');
    var xy1 = points[0].split(',');
    var xy2 = points[1].split(',');
    var xy3 = points[2].split(',');
    var box = [xy1[0], xy1[1], xy2[0] - xy1[0], xy3[1] - xy2[1]];

    activePage.classList.remove('fade');
    activePage.setAttribute('viewBox', box.join(' '));
    activeRect = rects[pageIndex - 1];
    activeRect.setAttribute('x', xy1[0]);
    activeRect.setAttribute('y', xy1[1]);
  }

Мой репозиторий кода здесь: https://github.com/cnario/svg-carousel

Вот что у меня есть до сих пор: https://cnario.github.io/svg-carousel/

Вот как я ожидаю, что это будет действовать: https://read.marvel.com/#book/41323

1 Ответ

1 голос
/ 08 мая 2019

Полагаю, это то, что вам может понадобиться: способ перехода viewBox из одного значения в другое, чтобы каждый раз иметь только одну часть svg в viewBox.

let BB = {};
BB.tomato = tomato.getBBox();
BB.skyblue = skyblue.getBBox();
BB.gold = gold.getBBox();


let radios = document.querySelectorAll("#controls input");

radios.forEach(r =>{
  let color = r.dataset.color;
  let bb = BB[color];
  
  r.addEventListener("change",()=>{
    svg.setAttributeNS(null,"viewBox", `${bb.x} ${bb.y} ${bb.width} ${bb.height}`)
    svg.style.height = `${bb.height * 300 / bb.width}px`; 
  })
  
})
svg {
  width: 300px;
  border: 1px solid;
  height: 600px;
  transition: height 1s;
}
<p id="controls">
  <label>tomato: <input type="radio" name="selector" data-color="tomato" /></label>
  <label>skyblue: <input type="radio" name="selector" data-color="skyblue" /></label>
  <label>gold: <input type="radio" name="selector" data-color="gold" /></label>
</p>

<svg id="svg" viewBox="0 0 100 200">
  <g id="tomato">
    <circle cx="35" cy="70" r="25" fill="tomato" />
  </g>
  <g id="skyblue">
    <ellipse cx="75" cy="160" rx="15" ry="35" fill="skyblue" />
  </g>
  <g id="gold">
    <polygon fill="gold" points="75,15 60,30 90,30" />
  </g>
</svg>
...