Beispiel:ViewBox-3-zoom.html

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche
<!DOCTYPE html>
<html lang="de">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    svg {
      display: block;
      width: 80%;
      max-width: 1500px;
      aspect-ratio: 3 / 2;
      border: thin dotted steelblue;
    }

    path {
      stroke: black;
      stroke-width: 1;
    }

    .wall {
      fill: none;
      stroke: #666;
      stroke-width: 20;
    }

    .roof {
      fill: url(#roofTiles);
      stroke: #666;
      stroke-width: 2;
    }

    .tile-bg {
      fill: #b02f21;
    }

    .tile-seam {
      fill: none;
      stroke: #9b1d13;
    }

    .tile-shadow {
      fill: #790d0b;
    }

    .tile-front {
      fill: #9b1d13;
      stroke: #9b1d13;
    }
  </style>
  <title>Room Tour mit ViewBox-Animation</title>
  <script>
    document.addEventListener('DOMContentLoaded', function () {
      const controls = document.getElementById("controls");
      const house = document.getElementById("house");

      controls.addEventListener("click", (event) => {
        const button = event.target.closest("button");
        if (!button) return;

        animateViewBox(house, button.dataset.view, 800);
      });

      function animateViewBox(svg, targetViewBox, duration = 1000) {
        const start = svg.viewBox.baseVal;

        const from = [
          start.x,
          start.y,
          start.width,
          start.height
        ];

        const to = targetViewBox.split(" ").map(Number);
        const startTime = performance.now();

        function frame(now) {
          const t = Math.min((now - startTime) / duration, 1);

          // ease-in-out
          const eased = 0.5 - Math.cos(t * Math.PI) / 2;

          const current = from.map((v, i) =>
            v + (to[i] - v) * eased
          );

          svg.setAttribute("viewBox", current.join(" "));

          if (t < 1) {
            requestAnimationFrame(frame);
          }
        }

        requestAnimationFrame(frame);
      }
    });
  </script>
</head>

<body>
  <div id="controls">
    <button data-view="125 375 1050 800">Schlafen</button>
    <button data-view="925 375 800 800">Bad</button>
    <button data-view="1875 375 1050 800">Büro</button>
    <button data-view="125 1150 800 800">Garage</button>
    <button data-view="840 1182 1050 800">Wohnen</button>
    <button data-view="1895 1181 1050 800">Küche</button>
    <button data-view="0 0 3000 2000">Unser Haus</button>
  </div>

  <svg id="house" viewBox="0 0 3000 2000" preserveAspectRatio="xMidYMid meet">
    <defs>
      <pattern id="roofTiles" width="78" height="126" patternUnits="userSpaceOnUse" patternTransform="translate(0 -10)">
        <rect width="192" height="128" class="tile-bg" />
        <line x1="38" y1="90" x2="38" y2="62" class="tile-seam" />
        <path d="M 38 90 C 38 110 20 126 0 126 C -20 126 -38 110 -38 90 C -38 90 -20 116 0 116 C 20 116 38 90 38 90 Z" class="tile-shadow" />
        <path d="M 38 88 C 38 104 20 120 0 120 C -20 120 -38 104 -38 88 C -38 88 -26 112 0 112 C 26 112 38 88 38 88 Z" class="tile-front" />
        <line x1="114" y1="90" x2="114" y2="62" class="tile-seam" />
        <path d="M 114 90 C 114 110 96 126 76 126 C 56 126 38 110 38 90 C 38 90 56 116 76 116 C 96 116 114 90 114 90 Z" class="tile-shadow" />
        <path d="M 114 88 C 114 104 96 120 76 120 C 56 120 38 104 38 88 C 38 88 50 112 76 112 C 102 112 114 88 114 88 Z" class="tile-front" />
        <line x1="76" y1="28" x2="76" y2="0" class="tile-seam" />
        <path d="M 76 28 C 76 48 58 64 38 64 C 18 64 0 48 0 28 C 0 28 18 54 38 54 C 58 54 76 28 76 28 Z" class="tile-shadow" />
        <path d="M 76 26 C 76 42 58 58 38 58 C 18 58 0 42 0 26 C 0 26 12 50 38 50 C 64 50 76 26 76 26 Z" class="tile-front" />
        <line x1="152" y1="28" x2="152" y2="0" class="tile-seam" />
        <path d="M 152 28 C 152 48 134 64 114 64 C 94 64 76 48 76 28 C 76 28 94 54 114 54 C 134 54 152 28 152 28 Z" class="tile-shadow" />
        <path d="M 152 26 C 152 42 134 58 114 58 C 94 58 76 42 76 26 C 76 26 88 50 114 50 C 140 50 152 26 152 26 Z" class="tile-front" />
      </pattern>
    </defs>

    <image x="925" y="355" width="1200" height="900" href="https://wiki.selfhtml.org/images/f/f8/Bathroom.svg" />
    <path class="wall" d="m125,375 h2800 v800 h-1050 v-800 m0,800 h-700 v-800 m0,800 h-1050 m0-800 v1570 h730 v-770 m0,770 h1020 v-800 m0,800 h1050 v-800 m0,800" />
    <path class="roof" d="m120,375 h2815 l-400,-350 h-2015 z" />
    <image x="150" y="400" width="1000" height="750" href="https://wiki.selfhtml.org/images/c/c9/Bedroom.svg" />
    <image x="1900" y="400" width="1000" height="750" href="https://wiki.selfhtml.org/images/3/37/Desk.svg" />
    <image x="120" y="1185" width="730" height="750" href="https://wiki.selfhtml.org/images/3/3e/Garage.svg" />
    <image x="865" y="1185" width="1000" height="750" href="https://wiki.selfhtml.org/images/7/79/Livingroom.svg" />
    <image x="2140" y="1536" width="150" height="150" href="https://upload.wikimedia.org/wikipedia/commons/a/ab/Kitchenaid-stir.svg" />
    <image x="1920" y="1236" width="1000" height="750" href="https://wiki.selfhtml.org/images/c/c2/Kitchen.svg" />
  </svg>
</body>
</html>