SVG интерактивная карта плана помещения с маршрутом

Есть два svg плана здания: 1й этаж и 2й этаж. На каждом этаже некоторое кол-во офисов и точка "вы находитесь тут" (как на плане эвакуации).

Задача - на сайте при клике по названию / номеру офиса проложить маршрут из точки "вы находитесь тут" до выбранного офиса.

Как это можно реализовать, при условии что маршрут может быть с первого этажа на второй и обратно (то есть когда маршрут дошел до лестницы, то первый план должен исчезнуть и появится второй). ???

Пошерстив гугл я понял, что можно в редакторе нарисовать линии безье (маршруты до офисов) и вставить их в path svg, а далее анимировать, но я не могу понять как отловить анимацию при переходе между этажами ну и собственно сам переход.

Буду рад подсказке по реализации или маленькому примеру.


Ответы (3 шт):

Автор решения: Sergei Kirjanov

svg -- это представление. Программу поиска я бы писал по упрощенным отдельным данным (варианты):

  • 3-мерный массив
  • граф А уже потом превращал данные ответа в svg

Это имеет смысл, если прокладывать путь между двумя произвольными точками из многих.

Если стартовых/конечных точек всего 2, а соответственно и возможнух путей-решений не много -- можно нарисовать пути заранее вручную.

→ Ссылка
Автор решения: Alexandr_TT

Решение для одного этажа

Допустим у нас есть растровая картинка плана этажа.
Для того, чтобы нарисовать маршруты, загрузим её в векторный редактор и с помощью инструмента Рисовать кривые Безье (на рисунке обозначена красной стрелкой 1)

создадим path (указаны стрелками 2) маршруты движения.

введите сюда описание изображения

Сохраним файл и скопируем path`

Далее вычисляем длину траекторий движения с помощью метода JS getTotalLength() В моем примере она получилась 761px

Пишем команду анимации path для каждой трассы движения

<animate id="an1" attributeName="stroke-dasharray" 
  begin="start1.click" dur="1.5s" values="0,761; 761,0" fill="freeze" restart="whenNotActive" /> 

где start1 это id красного эллипса, обозначающего место нахождения

Анимация начнется после клика по красным эллипсам

#trace1 {
fill:none;
stroke:crimson;
stroke-width:2;
stroke-dasharray:0,761;
}
#trace2 {
fill:none;
stroke:#0000ef;
stroke-width:2;
stroke-dasharray:0,761;
}
#trace3 {
fill:none;
stroke:#19a61b;
stroke-width:2;
stroke-dasharray:0,761;
}
.s0{
    fill:#f00800;
    stroke-width:2;
    stroke:#19a6eb;
}
    
<svg id="svg1" xmlns="http://www.w3.org/2000/svg"  xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" 
  width="900" height="900" viewBox="0 135 770 770" preserveAspectRatio="xMinYMin meet">

      <!-- Растровая картика плана помещения -->
 <image xlink:href="https://i.stack.imgur.com/dinW1.png" width="100%" height="100%"/>
  <path id="trace1" d="m508.8 276.2c0 0 98.2-15.1 105.9 20 11.1 50.6-45.5 96.1-75.9 130.2-26.8 30.1-83.9-13-120.9 2.9-53.3 22.8-65.9 113.4-123.1 123.1-29.2 5-50.5-38-80.1-38.6-30.9-0.7-85.2 36.5-85.2 36.5"> 
      <!-- Анимация красной трассы движения -->
   <animate id="an1" attributeName="stroke-dasharray" begin="start1.click" dur="4s" values="0,761; 761,0" fill="freeze" restart="whenNotActive" />
 </path>
  <path id="trace2" d="m388.6 218.3c0 0 40.4 14 42.2 31.5 1.3 12.6-24.9 15.9-25 28.6-0.2 18.1 31.1 23.8 35.1 41.5 6.5 28.9-9.2 59.6-22.9 85.9-21 40.4-51.6 77.2-88 104.5-26.1 19.5-57.2 43.7-89.5 39.4-21.3-2.9-28.6-39.9-50.1-40.8-24.5-1-60.8 41.5-60.8 41.5v0" >
          <!-- Анимация синей трассы движения -->    
    <animate id="an2" attributeName="stroke-dasharray" begin="start2.click" dur="4s" values="0,761; 761,0" fill="freeze" restart="whenNotActive" />
 </path>
  <path id="trace3" d="m617.6 503.1c0 0 11.1-54.2-5.7-70.8-44.7-44.3-101.8-6.5-188.2-13.6-52.9-4.4-48.6 102.9-96.6 123.8-28.3 12.4-63.5 3.2-92.3-7.9-18.4-7.1-27.5-36.6-47.2-35.8-25.8 1-58 51.5-58 51.5" >
      <!-- Анимация зелёной трассы движения -->
    <animate id="an3" attributeName="stroke-dasharray" begin="start3.click" dur="3s" values="0,761; 761,0" fill="freeze" restart="whenNotActive" />
 </path> 
              
            <!-- Место старта красной трассы -->
  <ellipse id="start1" cx="513.8" cy="277.7" rx="6.4" ry="5.7" class="s0"/>
          <!-- Место старта синей трассы -->
    <ellipse id="start2"  ry="5.7" rx="6.4" cy="218.3" cx="390.7" class="s0"/>
            <!-- Место старта зелёной трассы -->
        <ellipse id="start3" ry="5.7" rx="6.4" cy="500.2" cx="618.3" class="s0"/>
</svg>

→ Ссылка
Автор решения: Alexandr_TT

Вариант с анимированными фигурками

Смотрите комментарии в коде, надеюсь они помогут понять основные моменты

Анимация каждого маршрута начинается после клика по красным кругам местонахождения

#trace1 {
fill:none;
stroke:crimson;
stroke-width:2;
stroke-dasharray:0,761;
}
#trace2 {
fill:none;
stroke:#0000ef;
stroke-width:2;
stroke-dasharray:0,761;
}
#trace3 {
fill:none;
stroke:#19a61b;
stroke-width:2;
stroke-dasharray:0,761;
}
.s0{
    fill:#f00800;
    stroke-width:2;
    stroke:#19a6eb;
}
<svg id="svg1" xmlns="http://www.w3.org/2000/svg"  xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" 
  width="900" height="900" viewBox="0 135 770 770" preserveAspectRatio="xMinYMin meet">
<defs> 
  <!-- Фигурка человека с анимацией ног и рук -->
<g id="Man" transform="translate(0,0) scale(1,-1)">
    <path   fill="none">
         <animate
          attributeName="d"
          begin="0.1s"
          dur="0.3s"
          repeatCount="indefinite"
          values="M-3,0 0,10 3,0 M0,10 0,16 l 4,-5 M0,16 l-4,-5 M0,16 c4,4 -4,4 0,0;
                  M 0,0 0,10 0,0 M0,10 0,16 l 0,-5 M0,16 l 0,-5 M0,16 c4,4 -4,4 0,0;
                  M-3,0 0,10 3,0 M0,10 0,16 l 4,-5 M0,16 l-4,-5 M0,16 c4,4 -4,4 0,0"/>
    </path> 
      </g>
  </defs>  
      <!-- Растровая картика плана помещения -->
 <image xlink:href="https://i.stack.imgur.com/dinW1.png" width="100%" height="100%"/>
  <path id="trace1" d="m508.8 276.2c0 0 98.2-15.1 105.9 20 11.1 50.6-45.5 96.1-75.9 130.2-26.8 30.1-83.9-13-120.9 2.9-53.3 22.8-65.9 113.4-123.1 123.1-29.2 5-50.5-38-80.1-38.6-30.9-0.7-85.2 36.5-85.2 36.5"> 
      <!-- Анимация красной трассы движения -->
   <animate id="an1" attributeName="stroke-dasharray" begin="start1.click" dur="1.5s" values="0,761; 761,0" fill="freeze" restart="whenNotActive" />
 </path>
  <path id="trace2" d="m388.6 218.3c0 0 40.4 14 42.2 31.5 1.3 12.6-24.9 15.9-25 28.6-0.2 18.1 31.1 23.8 35.1 41.5 6.5 28.9-9.2 59.6-22.9 85.9-21 40.4-51.6 77.2-88 104.5-26.1 19.5-57.2 43.7-89.5 39.4-21.3-2.9-28.6-39.9-50.1-40.8-24.5-1-60.8 41.5-60.8 41.5v0" >
          <!-- Анимация синей трассы движения -->    
    <animate id="an2" attributeName="stroke-dasharray" begin="start2.click" dur="1.5s" values="0,761; 761,0" fill="freeze" restart="whenNotActive" />
 </path>
  <path id="trace3" d="m617.6 503.1c0 0 11.1-54.2-5.7-70.8-44.7-44.3-101.8-6.5-188.2-13.6-52.9-4.4-48.6 102.9-96.6 123.8-28.3 12.4-63.5 3.2-92.3-7.9-18.4-7.1-27.5-36.6-47.2-35.8-25.8 1-58 51.5-58 51.5" >
      <!-- Анимация зелёной трассы движения -->
    <animate id="an3" attributeName="stroke-dasharray" begin="start3.click" dur="1.5s" values="0,761; 761,0" fill="freeze" restart="whenNotActive" />
 </path> 
         <!-- Анимация движения человечка по красной трассе -->
  <use xlink:href="#Man" transform="translate(0,0) scale(1.4)" style="stroke:black; fill:black;"> 
     <animateMotion id="Man_an1"
       begin="an1.end"
       dur="9s"
       repeatCount="1"
       restart="whenNotActive"  >
          <mpath xlink:href="#trace1"/>
     </animateMotion>    
          </use>      
           <!-- Анимация движения человечка по синей трассе -->
  <use xlink:href="#Man" transform="translate(0,0) scale(1.4)" style="stroke:black; fill:black;"> 
     <animateMotion id="Man_an2"
       begin="an2.end"
       dur="9s"
       repeatCount="1"
       restart="whenNotActive"  >
          <mpath xlink:href="#trace2"/>
     </animateMotion>    
          </use>            
 <!-- Анимация движения человечка по зелёной трассе -->
  <use xlink:href="#Man" transform="translate(0,0) scale(1.4)" style="stroke:black; fill:black;"> 
     <animateMotion id="Man_an3"
       begin="an3.end"
       dur="9s"
       repeatCount="1"
       restart="whenNotActive"  >
          <mpath xlink:href="#trace3"/>
     </animateMotion>    
          </use>                  
            <!-- Место старта красной трассы -->
  <ellipse id="start1" cx="513.8" cy="277.7" rx="6.4" ry="5.7" class="s0"/>
          <!-- Место старта синей трассы -->
    <ellipse id="start2"  ry="5.7" rx="6.4" cy="218.3" cx="390.7" class="s0"/>
            <!-- Место старта зелёной трассы -->
        <ellipse id="start3" ry="5.7" rx="6.4" cy="500.2" cx="618.3" class="s0"/>
</svg>

→ Ссылка