23

Ниже изображение автомобиля в формате PNG.
Я хочу сделать анимацию движения автомобиля вдоль какой-нибудь траектории. Желательно, чтобы колёса автомобиля вращались. Я понимаю, что для этого необходимо перевести картинку в формат SVG.

Как это сделать?

С помощью векторного редактора или вручную, используя формулы SVG, или, как-то по другому, например, применяя трансформации CSS3.

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

0xdb
  • 51,614
Alexandr_TT
  • 110,146
  • 23
  • 114
  • 384

4 Answers4

25

Анимация движения автомобиля по заданной траектории

Cначала нам нужно нарисовать траекторию. Для этого открываем в векторном редакторе файл svg автомобиля

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

  • Рисуем путь

  • Сохраняем файл

  • Чтобы убрать из файла SVG лишнюю информацию, которую сохраняет векторный редактор необходимо оптимизировать файл с помощью любого оптимизатора, например - SVGOMG

  • Копируем из файла Path траектории

Для анимации движения вдоль заданного пути используем команду:

<animateMotion xlink:href="#car-dodger" begin="0s" dur="12s" rotate="auto" repeatCount="1" fill="freeze" > <mpath xlink:href="#carPath" /> </animateMotion> ,где

#car-dodger" - уникальный идентификатор автомобиля

#carPath" - идентификатор пути, по которому движется автомобиль

Внизу полный код:

<svg width="580" height="400" viewBox="0 0 580 400"
     xmlns="http://www.w3.org/2000/svg"     xmlns:xlink="http://www.w3.org/1999/xlink" >
<defs>

</defs>

<g id="car-dodger" transform="scale(0.25) translate(0 -180)"> <!-- Top --> <rect x="70" y="10" width="220" height="130" fill="transparent" rx="150" stroke="dodgerblue" stroke-width="10" /> <!-- Tail Lights red --> <circle r="10px" fill="crimson" cx="15" cy="90" />

&lt;!-- Body --&gt;
  &lt;rect x="10" y="70" width="340" height="80" fill="dodgerblue" rx="30" /&gt;

&lt;g&gt;
&lt;!-- Left line --&gt;
  &lt;line x1="145" y1="10" x2="145" y2="80" stroke="dodgerblue" stroke-width="10"/&gt;

&lt;!-- Right line --&gt;
  &lt;line x1="215" y1="10" x2="215" y2="80" stroke="dodgerblue" stroke-width="10"/&gt;
&lt;/g&gt;

&lt;g&gt;
&lt;!-- Left bumper --&gt;
  &lt;rect x="0" y="110" width="40" height="20" fill="#999" rx="10" /&gt;

&lt;!-- Right bumper --&gt;
  &lt;rect x="325" y="110" width="40" height="20" fill="#999" rx="10" /&gt;
&lt;/g&gt;  

&lt;!-- Left wheel  --&gt;
&lt;g stroke-dasharray="6.28 6.28"&gt;
  &lt;circle r="40px" fill="#222" stroke="white" stroke-width="4" cx="90" cy="140"/&gt;    
  &lt;circle r="22px" fill="#5C5C5C" cx="90" cy="140"/&gt; 
   &lt;polyline points="90,140 97.5 147.5" stroke="white" stroke-width="6" stroke-linecap="round" /&gt;
  &lt;animateTransform attributeName="transform" type="rotate" values="0 90 140;360 90 140"  dur="2s" repeatCount="indefinite" /&gt;
&lt;/g&gt;

&lt;!-- Right wheel --&gt;
&lt;g stroke-dasharray="6.28 6.28"&gt;
  &lt;circle r="40px" fill="#222" stroke="white" stroke-width="4" cx="270" cy="140"/&gt;
  &lt;circle r="22px" fill="#5C5C5C" cx="270" cy="140"/&gt; 
  &lt;polyline points="270,140 277.5 147.5" stroke="white" stroke-width="6" stroke-linecap="round" /&gt;
  &lt;animateTransform 
  attributeName="transform"
  type="rotate"
  values="0 270 140;360 270 140"
  dur="2s"
  repeatCount="indefinite" /&gt;
&lt;/g&gt;  

&lt;g&gt;
&lt;!-- Gold light --&gt;
  &lt;circle r="15px" fill="gold" cx="340" cy="90"/&gt;

   &lt;/g&gt;  
&lt;/g&gt;

<path id="carPath" style="fill:none;stroke:grey;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;" d="m 7.00611,78.668024 c 135.65342,-0.380598 152.27447,-3.422932 228.39919,-5.604887 28.49512,-0.816753 57.35177,-7.465997 85.47454,-2.802445 80.78801,13.39694 153.5049,57.123848 229.8004,86.875768 23.91885,9.32731 71.46232,28.72505 71.46232,28.72505" /> <animateMotion xlink:href="#car-dodger" begin="0s" dur="12s" rotate="auto" repeatCount="1" fill="freeze" > <mpath xlink:href="#carPath" /> </animateMotion> </svg>

Alexandr_TT
  • 110,146
  • 23
  • 114
  • 384
21

Движение автобуса по заданной траектории:

* {
  margin: 0;
  padding: 0;
}

line { stroke-width: 3px; stroke: #bf0208; }

<svg width="550" height="149" viewBox="0 0 550 149" style="background-color: #000" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <filter id="blur-filter-light" x="-1" y="-1" width="10" height="10">
      <feGaussianBlur in="SourceGraphic" stdDeviation="18" />
    </filter>
    <g transform="scale(0.90) translate(0 -120)" id="myCar">
      <rect x="50" y="40" width="210" height="35" fill="rgba(255, 0, 0, 0.3)" stroke-width="5" stroke="#bf0208" rx="3" />
      <g>
        <rect x="50" y="70" width="210" height="35" fill="#bf0208" stroke-width="5" stroke="#bf0208" rx="3" />
        <rect x="259" y="70" width="5" height="15" fill="yellow" rx="5" />
        <polygon points="450,90 267,80 450,60" fill="yellow" filter="url(#blur-filter-light)" />
        <text x="125" y="82" fill="white" font-size="1.2em" font-family="Monospace">Lorem Bus</text>
      </g>
      <g>
        <line x1="80" x2="80" y1="40" y2="70" />
        <line x1="110" x2="110" y1="40" y2="70" />
        <line x1="140" x2="140" y1="40" y2="70" />
        <line x1="170" x2="170" y1="40" y2="70" />
        <line x1="200" x2="200" y1="40" y2="70" />
        <line x1="230" x2="230" y1="40" y2="70" />
      </g>
      <g>
        <circle cx="75" cy="105" r="15" fill="gray" stroke="black" stroke-width="3" />
        <rect width="10" height="4" x="70" y="104" rx="3" fill="white" />
        <animateTransform attributeName="transform" type="rotate" values="0 75 105;360 75 105" dur="1s" repeatCount="7" />
      </g>
      <g>
        <circle cx="110" cy="105" r="15" fill="gray" stroke="black" stroke-width="3" />
        <rect width="10" height="4" x="105" y="104" rx="3" fill="white" />
        <animateTransform attributeName="transform" type="rotate" values="0 110 105;360 110 105" dur="1s" repeatCount="7" />
      </g>
      <g>
        <circle cx="225" cy="105" r="15" fill="gray" stroke="black" stroke-width="3" />
        <rect width="10" height="4" x="220" y="104" rx="3" fill="white" />
        <animateTransform attributeName="transform" type="rotate" values="0 225 105;360 225 105" dur="1s" repeatCount="7" />
      </g>
    </g>
    <path id="carPath" style="fill:none; stroke:white; stroke-width:1px;" d="m 0,147.8636 612.74654,0.53454" />
    <animateMotion xlink:href="#myCar" begin="0.3s" dur="7s" repeatCount="none">
      <mpath xlink:href="#carPath" />
    </animateMotion>
    <svg width="550" height="149" viewBox="0 0 550 149" style="border: 1px solid; background-color: #000" xmlns="http://www.w3.org/2000/svg"
      xmlns:xlink="http://www.w3.org/1999/xlink">
      <filter id="blur-filter-light" x="-1" y="-1" width="10" height="10">
        <feGaussianBlur in="SourceGraphic" stdDeviation="18" />
      </filter>
      <g transform="scale(0.90) translate(0 -120)" id="myCar">
        <rect x="50" y="40" width="210" height="35" fill="rgba(255, 0, 0, 0.3)" stroke-width="5" stroke="#bf0208" rx="3" />
        <g>
          <rect x="50" y="70" width="210" height="35" fill="#bf0208" stroke-width="5" stroke="#bf0208" rx="3" />
          <rect x="259" y="70" width="5" height="15" fill="yellow" rx="5" />
          <polygon points="450,90 267,80 450,60" fill="yellow" filter="url(#blur-filter-light)" />
          <text x="125" y="82" fill="white" font-size="1.2em" font-family="Monospace">Lorem Bus</text>
        </g>
        <g>
          <line x1="80" x2="80" y1="40" y2="70" />
          <line x1="110" x2="110" y1="40" y2="70" />
          <line x1="140" x2="140" y1="40" y2="70" />
          <line x1="170" x2="170" y1="40" y2="70" />
          <line x1="200" x2="200" y1="40" y2="70" />
          <line x1="230" x2="230" y1="40" y2="70" />
        </g>
        <g>
          <circle cx="75" cy="105" r="15" fill="gray" stroke="black" stroke-width="3" />
          <rect width="12" height="4" x="70" y="104" rx="3" fill="white" />
          <animateTransform attributeName="transform" type="rotate" values="0 75 105;360 75 105" dur="1s" repeatCount="7" />
        </g>
        <g>
          <circle cx="110" cy="105" r="15" fill="gray" stroke="black" stroke-width="3" />
          <rect width="12" height="4" x="105" y="104" rx="3" fill="white" />
          <animateTransform attributeName="transform" type="rotate" values="0 110 105;360 110 105" dur="1s" repeatCount="7" />
        </g>
        <g>
          <circle cx="225" cy="105" r="15" fill="gray" stroke="black" stroke-width="3" />
          <rect width="12" height="4" x="220" y="104" rx="3" fill="white" />
          <animateTransform attributeName="transform" type="rotate" values="0 225 105;360 225 105" dur="1s" repeatCount="7" />
        </g>
      </g>
      <path id="carPath" style="fill:none; stroke:white; stroke-width:1px;" d="m 0,147.8636 612.74654,0.53454" />
      <animateMotion xlink:href="#myCar" begin="0.3s" dur="7s" repeatCount="none">
        <mpath xlink:href="#carPath" />
      </animateMotion>
    </svg>
Arthur
  • 4,572
19

Это учебный пример. Шаг за шагом будут прорисовываться детали автомобиля и по мере продвижения легко будет понять, как применяются на практике основные команды svg: line, rect, circle, path

Код svg автомобиля был взят с сайта Юлии Бухваловой (Yulya Buhvalova)

  • Рисуем контур крыши и кузова автомобиля,- всего одна команда <rect>

<svg width="580" height="200" viewBox="0 0 580 200"
      xmlns="http://www.w3.org/2000/svg"     xmlns:xlink="http://www.w3.org/1999/xlink" >
<g id="car-dodger" transform="scale(1.0)">
    <!-- Top -->
      <rect x="70" y="10" width="220" height="130" fill="transparent" rx="150" stroke="dodgerblue" stroke-width="10" />
 </g>  
</svg>    
  • Рисуем основную часть кузова:

<svg width="580" height="200" viewBox="0 0 580 200"
      xmlns="http://www.w3.org/2000/svg"     xmlns:xlink="http://www.w3.org/1999/xlink" >

<g id="car-dodger" transform="scale(1.0)"> <!-- Top --> <rect x="70" y="10" width="220" height="130" fill="transparent" rx="150" stroke="dodgerblue" stroke-width="10" /> <!-- Body --> <rect x="10" y="70" width="340" height="80" fill="dodgerblue" rx="30" /> </g>
</svg>

  • Добавляем оконные стойки

<svg width="580" height="200" viewBox="0 0 580 200"
      xmlns="http://www.w3.org/2000/svg"     xmlns:xlink="http://www.w3.org/1999/xlink" >

<g id="car-dodger" transform="scale(1.0)"> <!-- Top --> <rect x="70" y="10" width="220" height="130" fill="transparent" rx="150" stroke="dodgerblue" stroke-width="10" /> <!-- Body --> <rect x="10" y="70" width="340" height="80" fill="dodgerblue" rx="30" />

&lt;g&gt;
&lt;!-- Left line --&gt;
  &lt;line x1="145" y1="10" x2="145" y2="80" stroke="dodgerblue" stroke-width="10"/&gt;

&lt;!-- Right line --&gt;
  &lt;line x1="215" y1="10" x2="215" y2="80" stroke="dodgerblue" stroke-width="10"/&gt;
&lt;/g&gt;

</g>
</svg>

  • Добавляем передний и задний бампер:

<svg width="580" height="200" viewBox="0 0 580 200"
      xmlns="http://www.w3.org/2000/svg"     xmlns:xlink="http://www.w3.org/1999/xlink" >

<g id="car-dodger" transform="scale(1.0)"> <!-- Top --> <rect x="70" y="10" width="220" height="130" fill="transparent" rx="150" stroke="dodgerblue" stroke-width="10" /> <!-- Body --> <rect x="10" y="70" width="340" height="80" fill="dodgerblue" rx="30" />

&lt;g&gt;
&lt;!-- Left line --&gt;
  &lt;line x1="145" y1="10" x2="145" y2="80" stroke="dodgerblue" stroke-width="10"/&gt;

&lt;!-- Right line --&gt;
  &lt;line x1="215" y1="10" x2="215" y2="80" stroke="dodgerblue" stroke-width="10"/&gt;
&lt;/g&gt;

<g> <!-- Left bumper --> <rect x="0" y="110" width="40" height="20" fill="#999" rx="10" />

&lt;!-- Right bumper --&gt;
  &lt;rect x="325" y="110" width="40" height="20" fill="#999" rx="10" /&gt;
&lt;/g&gt;  

</g>
</svg>

  • Добавляем колёса:

<svg width="580" height="200" viewBox="0 0 580 200"
      xmlns="http://www.w3.org/2000/svg"     xmlns:xlink="http://www.w3.org/1999/xlink">

<g id="car-dodger" transform="scale(1.1)"> <!-- Top --> <rect x="70" y="10" width="220" height="130" fill="transparent" rx="150" stroke="dodgerblue" stroke-width="10" />

&lt;!-- Body --&gt;
  &lt;rect x="10" y="70" width="340" height="80" fill="dodgerblue" rx="30" /&gt;

&lt;g&gt;
&lt;!-- Left line --&gt;
  &lt;line x1="145" y1="10" x2="145" y2="80" stroke="dodgerblue" stroke-width="10"/&gt;

&lt;!-- Right line --&gt;
  &lt;line x1="215" y1="10" x2="215" y2="80" stroke="dodgerblue" stroke-width="10"/&gt;
&lt;/g&gt;

&lt;g&gt;
&lt;!-- Left bumper --&gt;
  &lt;rect x="0" y="110" width="40" height="20" fill="#999" rx="10" /&gt;

&lt;!-- Right bumper --&gt;
  &lt;rect x="325" y="110" width="40" height="20" fill="#999" rx="10" /&gt;
&lt;/g&gt;  

&lt;!-- Left wheel  --&gt;
&lt;g&gt;
  &lt;circle r="40px" fill="#222" stroke="white" stroke-width="4" cx="90" cy="140"/&gt;    
  &lt;circle r="15px" fill="#555" cx="90" cy="140"/&gt;

</g>

&lt;!-- Right wheel --&gt;
&lt;g&gt;
  &lt;circle r="40px" fill="#222" stroke="white" stroke-width="7" cx="270" cy="140"/&gt;
  &lt;circle r="15px" fill="#555" cx="270" cy="140"/&gt;
&lt;/g&gt;  


</g> </svg>

  • Добавляем фары:

<svg width="580" height="200" viewBox="0 0 580 200"
      xmlns="http://www.w3.org/2000/svg"     xmlns:xlink="http://www.w3.org/1999/xlink" >

<g id="car-dodger" transform="scale(1.0)"> <!-- Top --> <rect x="70" y="10" width="220" height="130" fill="transparent" rx="150" stroke="dodgerblue" stroke-width="10" /> <!-- Tail Lights red --> <circle r="10px" fill="crimson" cx="15" cy="90" />

 &lt;!-- Body --&gt;
  &lt;rect x="10" y="70" width="340" height="80" fill="dodgerblue" rx="30" /&gt; 

&lt;g&gt;
&lt;!-- Left line --&gt;
  &lt;line x1="145" y1="10" x2="145" y2="80" stroke="dodgerblue" stroke-width="10"/&gt;

&lt;!-- Right line --&gt;
  &lt;line x1="215" y1="10" x2="215" y2="80" stroke="dodgerblue" stroke-width="10"/&gt;
&lt;/g&gt;

<g> <!-- Left bumper --> <rect x="0" y="110" width="40" height="20" fill="#999" rx="10" />

&lt;!-- Right bumper --&gt;
  &lt;rect x="325" y="110" width="40" height="20" fill="#999" rx="10" /&gt;
&lt;/g&gt;  

<!-- Left wheel --> <g> <circle r="40px" fill="#222" stroke="white" stroke-width="7" cx="90" cy="140"/>
<circle r="15px" fill="#555" cx="90" cy="140"/> </g>

&lt;!-- Right wheel --&gt;
&lt;g&gt;
  &lt;circle r="40px" fill="#222" stroke="white" stroke-width="7" cx="270" cy="140"/&gt;
  &lt;circle r="15px" fill="#555" cx="270" cy="140"/&gt;
&lt;/g&gt;  
   &lt;g&gt;
&lt;!-- Gold light --&gt;
  &lt;circle r="15px" fill="gold" cx="340" cy="90"/&gt;

   &lt;/g&gt;  

</g>
</svg>

Автомобиль готов. Конечно можно продолжать дальше,- украшать, добавлять новые детали, но в принципе достаточно, потому-что в анимации будет использоваться малый размер автомобиля и деталей особо не будет видно.
А вот шины лысые, добавим протектор с помощью stroke-dasharray и добавим вращение колёс:

<animateTransform attributeName="transform" type="rotate" values="0 90 140;360 90 140"  dur="2s" repeatCount="3" />

<svg width="580" height="200" viewBox="0 0 580 200"
      xmlns="http://www.w3.org/2000/svg"     xmlns:xlink="http://www.w3.org/1999/xlink" >

<g id="car-dodger" transform="scale(1)"> <!-- Top --> <rect x="70" y="10" width="220" height="130" fill="transparent" rx="150" stroke="dodgerblue" stroke-width="10" /> <!-- Tail Lights red --> <circle r="10px" fill="crimson" cx="15" cy="90" />

&lt;!-- Body --&gt;
  &lt;rect x="10" y="70" width="340" height="80" fill="dodgerblue" rx="30" /&gt;

&lt;g&gt;
&lt;!-- Left line --&gt;
  &lt;line x1="145" y1="10" x2="145" y2="80" stroke="dodgerblue" stroke-width="10"/&gt;

&lt;!-- Right line --&gt;
  &lt;line x1="215" y1="10" x2="215" y2="80" stroke="dodgerblue" stroke-width="10"/&gt;
&lt;/g&gt;

&lt;g&gt;
&lt;!-- Left bumper --&gt;
  &lt;rect x="0" y="110" width="40" height="20" fill="#999" rx="10" /&gt;

&lt;!-- Right bumper --&gt;
  &lt;rect x="325" y="110" width="40" height="20" fill="#999" rx="10" /&gt;
&lt;/g&gt;  

&lt;!-- Left wheel  --&gt;
&lt;g stroke-dasharray="6.28 6.28"&gt;
  &lt;circle r="40px" fill="#222" stroke="white" stroke-width="4" cx="90" cy="140"/&gt;    
  &lt;circle r="22px" fill="#5C5C5C" cx="90" cy="140"/&gt; 
&lt;polyline points="90,140 97.5 147.5" stroke="white" stroke-width="6" stroke-linecap="round" /&gt; 
&lt;animateTransform
   attributeName="transform" 
   type="rotate"
   values="0 90 140;360 90 140"
   dur="2s" repeatCount="3" /&gt;
 &lt;/g&gt;
 &lt;!-- Right wheel --&gt;
&lt;g stroke-dasharray="6.28 6.28"&gt;
  &lt;circle r="40px" fill="#222" stroke="white" stroke-width="4" cx="270" cy="140"/&gt;
  &lt;circle r="22px" fill="#5C5C5C" cx="270" cy="140"/&gt; 

<polyline points="270,140 277.5 147.5" stroke="white" stroke-width="6" stroke-linecap="round" /> <animateTransform attributeName="transform" type="rotate" values="0 270 140;360 270 140" dur="2s" repeatCount="3" /> </g>

&lt;g&gt;
&lt;!-- Gold light --&gt;
  &lt;circle r="15px" fill="gold" cx="340" cy="90"/&gt;

   &lt;/g&gt;  

</g> </svg>

Связанный вопрос: Движение поезда с помощью SVG

Alexandr_TT
  • 110,146
  • 23
  • 114
  • 384
  • 3
    Александр ты как всегда безупречен ... –  Feb 19 '18 at 14:05
  • 1
    @МаксимЛенский Спасибо Максим Это всего лишь учебный пример, делал по предложению ребят, которые очень хотят научиться SVG Заглядывай к нам на огонёк в чатик https://chat.stackexchange.com/rooms/70612/svg-chat бывает весело – Alexandr_TT Feb 19 '18 at 14:09
12

Пример на css

*,
:before,
:after {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

.car { position: relative; height: 200px; overflow: hidden; border-bottom: 7px solid #ccc; }

.car__inner { padding-bottom: 30px; animation: goToCar 5s linear infinite; }

@keyframes goToCar { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } }

.car__contour { height: 130px; width: 220px; margin: 25px auto -70px auto; border: 10px solid #1E90FF; border-radius: 220px / 130px; position: relative; }

.car__contour:before { content: ''; position: absolute; top: 0; left: 50%; margin-left: -40px; height: 100%; width: 80px; border: 10px solid #1E90FF; border-top: none; }

.car__body { width: 340px; height: 80px; background: #1E90FF; border-radius: 30px; margin: 0 auto; position: relative; }

.car__headlight { position: absolute; top: 10px; left: -5px; background: #DC143C; width: 20px; height: 20px; border-radius: 50%; z-index: -1; }

.car__headlight--front { top: 5px; left: auto; right: -10px; background: #FFD700; width: 30px; height: 30px; z-index: 1; }

.car__bumper { position: absolute; bottom: 20px; left: -5px; width: 40px; height: 20px; background: #999; border-radius: 10px; }

.car__bumper--front { left: auto; right: -20px; }

.car__wheel { position: absolute; bottom: -35px; left: 45px; width: 90px; height: 90px; background: #fff; border-radius: 50%; }

.car__wheel:before { content: ''; position: absolute; top: 50%; left: 50%; width: 76px; height: 76px; background: #222; border-radius: 50%; z-index: 1; margin: -38px 0 0 -38px; animation: rotateWheel 2s linear infinite; border: 2px dashed #fff; }

@keyframes rotateWheel { 0% { transform: rotate(0); } 100% { transform: rotate(360deg); } }

.car__wheel:after { content: ''; position: absolute; top: 50%; left: 50%; width: 30px; height: 30px; background: #555; border-radius: 50%; z-index: 1; margin: -15px 0 0 -15px }

.car__wheel--front { left: auto; right: 45px; }

<div class="car">
  <div class="car__inner">
    <div class="car__contour"></div>
    <div class="car__body">
      <div class="car__headlight"></div>
      <div class="car__headlight car__headlight--front"></div>

      <div class="car__bumper"></div>
      <div class="car__bumper car__bumper--front"></div>

      <div class="car__wheel"></div>
      <div class="car__wheel car__wheel--front"></div>
    </div>
  </div>
</div>
soledar10
  • 27,573
  • 2
    классно и так быстро сделал - всего за 40 минут! Настоящий мастер CSS. Жаль, что на css невозможно сделать движение по гладкой, криволинейной траектории – Alexandr_TT Jul 02 '18 at 13:36
  • 2
    крассавчик ... 100% хардкор –  Jul 02 '18 at 13:59