Beispiel:SVG-pulley-1.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">
<link rel="stylesheet" media="screen" href="./Beispiel:Grundlayout.css">
<title>Seilzug</title>

<style>
    svg {
      --hub: 80px;
      --dauer: 4s;
      --drehwinkel: 90deg;
      --seil_dicke: 8;
      --seil_farbe: #bb6f27;
      --seil_hell: #dfa873;
      --rolle: steelblue;
      --beschriftung: red;
      --muster_strich: 12;
      --muster_luecke: 10;
      --phase_oben_fest: 5px;
      --phase_bogen_unten: 10px;
      --phase_mitte: 1px;
      --phase_bogen_oben: 14px;
      --phase_ende: 8px;
      width: 600px;
      max-width: 100%;
    }

    .kreuz {
      stroke: white;
      stroke-width: 20px;
      opacity: 0.7;
    }

    .nabe-fuellung {
      fill: var(--rolle);
    }

    .linie {
      fill: none;
      stroke: var(--beschriftung);
    }

    text {
      fill: var(--beschriftung);
      font-family: sans-serif;
      font-size: 40px;
    }

    /* Strichbreite beim Skalieren fixieren */
    #seil line, #seil path, #seil_muster line, #seil_muster path {
      vector-effect: non-scaling-stroke;
    }

    #seil line,
    #seil path {
      fill: none;
      stroke: var(--seil_farbe);
      stroke-width: var(--seil_dicke);
    }

    #pfeil_am_ende {
      fill: var(--seil_farbe);
      stroke: none;
      animation: pfeil_bewegen var(--dauer) ease-in-out infinite alternate;
      transform-box: fill-box;
      transform-origin: 50% 50%;
    }

    /* Gemeinsame Bewegung */
    #rolle_mit_gewicht, #bogen_unten_bewegt, #bogen_unten_bewegt_muster {
      animation: heben var(--dauer) ease-in-out infinite alternate;
      transform-box: fill-box;
      transform-origin: 50% 50%;
    }

    /* Seilsegmente: Transform-Ursprung und Längenänderung */
    #oben_verkuerzt_sich,
    #mittleres_verkuerzt_sich,
    #ende_verlaengert_sich_doppelt,
    #m_oben_fest,
    #m_mittleres_bewegt,
    #m_ende_bewegt {
      transform-box: fill-box;
      transform-origin: 50% 0%;
    }

    #oben_verkuerzt_sich, #m_oben_fest {
      animation: oben_kuerzen var(--dauer) ease-in-out infinite alternate;
    }

    #mittleres_verkuerzt_sich {
      animation: mitte_kuerzen var(--dauer) ease-in-out infinite alternate;
    }

    #ende_verlaengert_sich_doppelt {
      animation: ende_verlaengern var(--dauer) ease-in-out infinite alternate;
    }

    #oberes_rollenkreuz {
      animation: drehen_2x var(--dauer) ease-in-out infinite alternate;
      transform-box: fill-box;
      transform-origin: 50% 50%;
    }

    #unteres_rollenkreuz {
      animation: drehen_1x var(--dauer) ease-in-out infinite alternate;
      transform-box: fill-box;
      transform-origin: 50% 50%;
    }

    /* Seilmuster */
    #seil_muster {
      pointer-events: none;
    }

    #seil_muster line, #seil_muster path {
      fill: none;
      stroke: var(--seil_hell);
      stroke-width: var(--seil_dicke);
      stroke-dasharray: var(--muster_strich) var(--muster_luecke);
      opacity: .9;
    }

    /* Startpunkt der Muster */
    #m_oben_fest { stroke-dashoffset: var(--phase_oben_fest); }
    #m_mittleres_bewegt { stroke-dashoffset: var(--phase_mitte); }
    #m_bogen_oben { stroke-dashoffset: var(--phase_bogen_oben); }
    #m_bogen_unten { stroke-dashoffset: var(--phase_bogen_unten); }
    #m_ende_bewegt { stroke-dashoffset: var(--phase_ende); }
    
    /* Musterfluss animieren */
    #m_mittleres_bewegt {
      animation-name: mitte_kuerzen, muster_schieben_mitte;
      animation-duration: var(--dauer), var(--dauer);
      animation-timing-function: ease-in-out, ease-in-out;
      animation-iteration-count: infinite, infinite;
      animation-direction: alternate, alternate;
    }
    #m_ende_bewegt {
      animation-name: ende_verlaengern, muster_schieben_links;
      animation-duration: var(--dauer), var(--dauer);
      animation-timing-function: ease-in-out, ease-in-out;
      animation-iteration-count: infinite, infinite;
      animation-direction: alternate, alternate;
    }
    #m_bogen_oben {
      animation: muster_schieben_oben var(--dauer) ease-in-out infinite alternate;
    }
    #m_bogen_unten {
      animation: muster_schieben_unten var(--dauer) ease-in-out infinite alternate;
    }

    /* Keyframes */
    @keyframes drehen_1x {
      0% { transform: rotate(0deg); }
      100% { transform: rotate(var(--drehwinkel)); }
    }

    @keyframes drehen_2x {
      0% { transform: rotate(calc(2 * var(--drehwinkel))); }
      100% { transform: rotate(0deg); }
    }

    @keyframes heben {
      from { transform: translateY(0px); }
      to { transform: translateY(calc(-1 * var(--hub))); }
    }

    @keyframes oben_kuerzen {
      from { transform: scaleY(1); }
      to { transform: scaleY(0.836734694); }
    }

    @keyframes mitte_kuerzen {
      from { transform: scaleY(1); }
      to { transform: scaleY(0.789473684); }
    }

    @keyframes ende_verlaengern  {
      from { transform: scaleY(1); }
      to { transform: scaleY(1.842105263); }
    }

    @keyframes pfeil_bewegen  {
      from { transform: translateY(0px); }
      to { transform: translateY(calc(2 * var(--hub))); }
    }

    /* Dash-Animationen + Basisphase (über calc mit den Variablen) */
    @keyframes muster_schieben_unten {
      from { stroke-dashoffset: calc(var(--phase_bogen_unten) + 0px); }
      to   { stroke-dashoffset: calc(var(--phase_bogen_unten) + 126px); }
    }

    @keyframes muster_schieben_mitte {
      from { stroke-dashoffset: calc(var(--phase_mitte) + 0px); }
      to   { stroke-dashoffset: calc(var(--phase_mitte) + 252px); }
    }

    @keyframes muster_schieben_oben {
      from { stroke-dashoffset: calc(var(--phase_bogen_oben) - 252px); }
      to   { stroke-dashoffset: calc(var(--phase_bogen_oben) + 0px); }
    }

    @keyframes muster_schieben_links {
      from { stroke-dashoffset: calc(var(--phase_ende) + 0px); }
      to   { stroke-dashoffset: calc(var(--phase_ende) - 252px); }
    }

</style>
</head>
<body>

<h1>Seilzug animiert</h1>

<svg viewBox="0 0 600 800">

  <g id="seil">
    <line id="oben_verkuerzt_sich" x1="400" y1="30" x2="400" y2="520" />
    <line id="mittleres_verkuerzt_sich" x1="300" y1="140" x2="300" y2="520" />
    <path id="bogen_ueber_obere_rolle" d="m 200,140 c 0,-31 26,-50 50,-50 24,0 50,19 50,50" />

    <g id="bogen_unten_bewegt">
      <path id="bogen_um_untere_rolle" d="m 300,520 c 0,31 26,50 50,50 24,0 50,-19 50,-50" />
    </g>

    <line id="ende_verlaengert_sich_doppelt" x1="200" y1="140" x2="200" y2="330" />
  </g>

  <g id="seil_muster">
    <line id="m_oben_fest" x1="400" y1="30" x2="400" y2="520" />
    <line id="m_mittleres_bewegt" x1="300" y1="140" x2="300" y2="520" />
    <path id="m_bogen_oben" d="m 200,140 c 0,-31 26,-50 50,-50 24,0 50,19 50,50" />
    <g id="bogen_unten_bewegt_muster">
      <path id="m_bogen_unten" d="m 300,520 c 0,31 26,50 50,50 24,0 50,-19 50,-50" />
    </g>

    <line id="m_ende_bewegt" x1="200" y1="140" x2="200" y2="330" />
  </g>

  <path id="pfeil_am_ende" d="m 215,316 -15,5 -15,-5 15,33 z" />

  <g id="rolle_oben">
    <circle class="nabe-fuellung" cx="250" cy="140" r="48"/>
    <g id="oberes_rollenkreuz">
      <line class="kreuz" x1="250" y1="102" x2="250" y2="178"/>
      <line class="kreuz" x1="212" y1="140" x2="288" y2="140"/>
    </g>
    <circle cx="250" cy="140" r="20"/>
    <line style="stroke: black; stroke-width: 8px;" x1="250" y1="35" x2="250" y2="140"/>
  </g>

  <g id="rolle_mit_gewicht">
    <circle class="nabe-fuellung" cx="350" cy="520" r="48"/>
    <g id="unteres_rollenkreuz">
      <line class="kreuz" x1="350" y1="482" x2="350" y2="558"/>
      <line class="kreuz" x1="312" y1="520" x2="388" y2="520"/>
    </g>
    <circle cx="350" cy="520" r="20"/>
    <path style="fill: black; stroke: none;" d="m 322,670 h 56 l 32,100 H 290 Z"/>
    <line style="fill: none; stroke: black; stroke-width: 8px;" x1="350" y1="518" x2="350" y2="670"/>
  </g>

  <g id="oben_befestigung">
    <circle cx="250" cy="30" r="20"/>
    <circle cx="400" cy="30" r="20"/>
    <rect width="600" height="30" style="stroke: none; fill: #999;"/>
  </g>

  <rect id="boden" width="600" height="30" style="stroke: none; fill: #999;" y="770" />

  <text x="486" y="739">1x</text>
  <text x="80" y="441">2x</text>
  <path class="linie" d="m 130,349 v 160 m 0,-160 h 50 m -50,160 h 50"/>
  <path class="linie" d="m 478,770 v -80 m 0,80 h -50 m 50,-80 h -50"/>
</svg>

</body>
</html>