SVG. Анимация при нажатии на машинку

Рейтинг: 0Ответов: 1Опубликовано: 08.06.2023

Ссылка на SVG.
При нажатии на машинку она должна передвигаться к краю экрана;
При двойном нажатии на машинку она должна возвращаться обратно.
НО что бы при нажатии на колеса машинки , анимация передвижения НЕ срабатывала !

function changeRweel() {
    let rweel = document.querySelector("#rweel");
    rweel.style.fill = "#3f3f9f";
}
function changeLweel() {
    let lweel = document.querySelector("#lweel");
    lweel.style.fill = "#3f3f9f";
}

var el = document.getElementById("drop-lang");
document.getElementsByClassName("lang")[0].addEventListener('click',
    function() {
    el.classList.toggle("active");
})
svg {
    width: 70%;
    height: 70%;
    position: relative;
}
svg path {
    fill:inherit;
    stroke:inherit;
    stroke-width:inherit;
    }

#rweel, #lweel {
    fill: #464655;
    cursor: pointer;
}
#rweel:hover, #lweel:hover {
    fill: green;
    cursor: pointer;
}

#drop-lang {
    transform: translateX(0px);
    transition: transform 3s;
}

#drop-lang.active {
    transform: translateX(190px);
    transition: transform 3s;
}
<svg xmlns="http://www.w3.org/2000/svg" id="drop-lang" class="lang" viewBox="0 0 512 200">
  <g style="fill:#C7CFE2">
    <rect width="57" height="18" x="7" y="181" transform="rotate(-129 -2 112)"/>
    <path d="M207 58c-6-1-9-8-6-13l6-11c5-8 14-13 23-13h44c8 0 16 4 21 10l31 42-119-15Z"/>
    <path d="m324 15-2-2h-39l61 69 36-17s-42-39-56-50Z"/>
  </g>
  <path style="fill:#FF6464" d="M415 56h-36c-5 0-11 2-15 4l-12 9-5 2-33-44c-2-2 0-6 3-6h14l-7-6c-7-6-20-12-50-12h-44c-19 0-38 4-55 13l-62 31H35C21 47 9 59 9 74v79l62 18h432v-27c0-49-39-88-88-88Zm-208 2c-6-1-9-8-6-13l6-11c5-8 14-13 23-13h44c8 0 16 4 21 10l31 42-119-15Z"/>
  <path style="fill:#D2555A" d="M503 180H106c-5 0-9-4-9-9s4-9 9-9h397c5 0 9 4 9 9s-4 9-9 9Z"/>
  <circle style="fill:#D7DEED" cx="415" cy="144" r="44"/>
  <path id="rweel" d="M415 197c-29 0-53-24-53-53s24-53 53-53 53 24 53 53-24 53-53 53Zm0-88c-20 0-35 16-35 35 0 20 15 36 35 36a35 35 0 0 0 0-71Z"/>
  <circle style="fill:#B8BFD4" cx="415" cy="144" r="18"/>
  <g style="fill:#D2555A">
    <path d="m79 180-2-1-70-17c-5-2-8-6-7-11s6-8 11-6l71 17c4 1 7 6 6 11-1 4-5 7-9 7Z"/>
    <path d="m9 100 12 13c4 3 5 7 5 12v37l-17-9v-53Z"/>
    <path d="M294 144H141c-5 0-9-4-9-9 0-4 4-8 9-8h153c7 0 14-3 19-8l13-14c4-3 9-3 13 0 3 4 3 9 0 13l-13 13c-9 9-20 13-32 13Z"/>
  </g>
  <circle style="fill:#D7DEED" cx="97" cy="144" r="44"/>
  <path id="lweel" d="M97 197c-29 0-53-24-53-53s24-53 53-53 53 24 53 53-24 53-53 53Zm0-88a35 35 0 0 0 0 71c20 0 35-16 35-36 0-19-15-35-35-35Z"/>
  <circle style="fill:#B8BFD4" cx="97" cy="144" r="18"/>
  <path style="fill:#FF8B8B" d="m15 57 339 33c5 1 10 0 14-2 20-10 90-34 135 46-5-44-43-78-88-78h-36c-5 0-11 2-15 4l-12 9-5 2s-3 4-21 2l-71-9-142-17H35c-8 0-15 4-20 10Z"/>
  <path style="fill:#FF6464" d="M44 29H22c-8 0-15-4-17-12l-3-7C1 6 3 3 7 3h37c5 0 9 4 9 9v9c0 5-4 8-9 8Z"/>
</svg>

Ответы

▲ 0Принят

С группами вы через чур намудрили.

Во-первых, есть какие-то пустые, зачем? Не надо так делать, оформляйте вопрос красиво. Во-вторых, есть у вас две группы по цветам, например #C7CFE2, но вы эти цвета для каждой фигуры пропысываете, хотя можно прописать для группы, это более оптимально и отлично ложится в DRY принципы.

И, группы это ваш ключ для решения проблемы.
Создадим новую группу, в которую будут входить все фигуры кроме колёс, пусть у неё будет ID "chasis". Правильнее, конечно, английское слово body, но мне не нравится, что оно перекликается с синтаксисом html.

document.getElementsByClassName("lang")[0]

Это, конечно, изврат. Зачем искать все элементы и брать первый? Ставим вместо этого новый ID группы отвечающий за корпус, теперь 'click' будет работать только на корпусе, а на колёса реагировать не будет.
Можно, конечно, обойтись без ID и использовать onclick прямо на группе, но тогда придётся ещё стиль дописать, что получится более громоздко.

function changeTire(clicked_element) {
    clicked_element.style.stroke = "#3f3f9f";
}

document.getElementById("chasis").addEventListener('click',
    function() {
    document.getElementById("drop-lang").classList.toggle("active");
})
svg {
    width: 70%;
    height: 70%;
    position: relative
}

.rear { cx: 96 }
.front { cx: 415 }

.wheel, .tire {
    stroke-width: 18;
    cy: 144
}

.wheel {
    fill: #b8bfd4;
    stroke: #d7deed;
    r: 27
}

.tire {
    fill: none;
    stroke: #464655;
    r: 44
}

.tire:hover {
    stroke: green;
    cursor: pointer
}

#drop-lang {
    transform: translateX(0px);
    transition: transform 3s
}

#drop-lang.active {
    transform: translateX(190px);
    transition: transform 3s
}
<svg id="drop-lang" viewBox="0 0 512 200" xmlns="http://www.w3.org/2000/svg">
  <g id="chasis">
    <g fill="#C7CFE2">
      <rect width="57" height="18" x="7" y="181" transform="rotate(-129 -2 112)"/>
      <path d="M207 58c-6-1-9-8-6-13l6-11c5-8 14-13 23-13h44c8 0 16 4 21 10l31 42-119-15Z"/>
      <path d="m324 15-2-2h-39l61 69 36-17s-42-39-56-50Z"/>
    </g>
    <g fill="#FF6464">
      <path d="M415 56h-36c-5 0-11 2-15 4l-12 9-5 2-33-44c-2-2 0-6 3-6h14l-7-6c-7-6-20-12-50-12h-44c-19 0-38 4-55 13l-62 31H35C21 47 9 59 9 74v79l62 18h432v-27c0-49-39-88-88-88Zm-208 2c-6-1-9-8-6-13l6-11c5-8 14-13 23-13h44c8 0 16 4 21 10l31 42-119-15Z"/>
      <path d="M44 29H22c-8 0-15-4-17-12l-3-7C1 6 3 3 7 3h37c5 0 9 4 9 9v9c0 5-4 8-9 8Z"/>
    </g>
    <g fill="#D2555A">
      <path d="M503 180H106c-5 0-9-4-9-9s4-9 9-9h397c5 0 9 4 9 9s-4 9-9 9Z"/>
      <path d="m79 180-2-1-70-17c-5-2-8-6-7-11s6-8 11-6l71 17c4 1 7 6 6 11-1 4-5 7-9 7Z"/>
      <path d="m9 100 12 13c4 3 5 7 5 12v37l-17-9v-53Z"/>
      <path d="M294 144H141c-5 0-9-4-9-9 0-4 4-8 9-8h153c7 0 14-3 19-8l13-14c4-3 9-3 13 0 3 4 3 9 0 13l-13 13c-9 9-20 13-32 13Z"/>
    </g>
    <path fill="#FF8B8B" d="m15 57 339 33c5 1 10 0 14-2 20-10 90-34 135 46-5-44-43-78-88-78h-36c-5 0-11 2-15 4l-12 9-5 2s-3 4-21 2l-71-9-142-17H35c-8 0-15 4-20 10Z"/>
  </g>
  <circle class="rear wheel"/>
  <circle class="rear tire"/>
  <circle class="front wheel"/>
  <circle class="front tire"/>
</svg>

И ещё немного по оптимизации. Внутренняя часть колёс делается одним кругом, если задать fill и stroke. Для шин path не нужен, также можно обойтись кругом и обращаться к stroke.

Вообще колёса можно было бы в symbols запихнуть, но количество кода это не сократит, т.к. path убран.

Шинам можно задать класс, тогда изначальные цвета и hover менять через данный класс не указывая оба колеса.

Под нет необходимости городить две функции. Если обращаться к this.id, то можно получить в функции ID конкретного колеса и изменять его. Но в данном случае и ID не сильно нужен, можно напрямую обращаться к элементу через this. В общем, DRY в действии.