我有一张用以下内容绘制的汽车图像SVG:
<svg id="svg" viewBox="0 0 1500 1000">
<!--Автомобиль-->
<g id="car">
<!--Зеркала-->
<path d="M371 88l-31-77c-3-6-9-11-17-11h-23l35 88zm0 142h-36l-35 88h23c8 0 14-5 17-11z" fill="red" />
<!--Кузов-->
<path d="M492 224l13-30c9-22 9-48 0-70l-13-30a88 88 0 0 0-88-53L256 53 104 40c-36-3-70 17-86 49l-3 7c-20 40-20 86 0 126l3 7a88 88 0 0 0 86 49l152-13 148 12c38 3 73-18 88-53z" fill="orangered" />
<!--Тень кузова-->
<path d="M396 277c66-50 95-134 74-214 9 9 17 19 22 31l13 30c9 22 9 48 0 70l-13 30a88 88 0 0 1-88 53z" fill="red" />
<!--Переднее стекло-->
<path d="M369 91l-2-3c-3-5-10-8-16-7l-77 7v142l77 7c6 1 13-2 16-7l2-3c27-41 27-95 0-136z" fill="white" />
<!--Тень переднего стекла-->
<path d="M370 92c26 41 26 94-1 135l-2 3c-3 5-10 8-16 7l-59-6c44-33 72-84 78-139z" fill="lightgray" />
<!--Заднее стекло-->
<path d="M150 88v142l-41 6c-7 2-14-2-18-8l-9-18c-18-32-18-70 0-102l9-18c4-6 11-10 18-8z" fill="white" />
<!--Тень заднего стекла-->
<path d="M91 228l-5-9c31-35 53-76 64-121v132l-41 6c-7 2-14-2-18-8z" fill="lightgray" />
<!--Фары-->
<path d="M411 72l53 36-10 15-53-36zm43 124l10 15-54 35-10-15z" fill="yellow" />
</g>
</svg>
还有一张城市地图的图像,我想在其道路上重现汽车运动的动画:
我设法将SVG城市地图和汽车图像合二为一。此外,使用动画命令<animateTransform>和属性,translate(x,y)我能够重现汽车沿道路行驶的动画。
点击地图后动画开始
<svg id="svg" viewBox="0 0 1600 900">
<g id="map" x="0" y="0">
<image href="https://i.imgur.com/kb3KgeW.jpg">
</image>
</g>
<!--Автомобиль-->
<g transform="translate(10,456)">
<g transform="scale(0.08)">
<!--Зеркала-->
<path d="M371 88l-31-77c-3-6-9-11-17-11h-23l35 88zm0 142h-36l-35 88h23c8 0 14-5 17-11z" fill="red" />
<!--Кузов-->
<path d="M492 224l13-30c9-22 9-48 0-70l-13-30a88 88 0 0 0-88-53L256 53 104 40c-36-3-70 17-86 49l-3 7c-20 40-20 86 0 126l3 7a88 88 0 0 0 86 49l152-13 148 12c38 3 73-18 88-53z" fill="orangered" />
<!--Тень кузова-->
<path d="M396 277c66-50 95-134 74-214 9 9 17 19 22 31l13 30c9 22 9 48 0 70l-13 30a88 88 0 0 1-88 53z" fill="red" />
<!--Переднее стекло-->
<path d="M369 91l-2-3c-3-5-10-8-16-7l-77 7v142l77 7c6 1 13-2 16-7l2-3c27-41 27-95 0-136z" fill="white" />
<!--Тень переднего стекла-->
<path d="M370 92c26 41 26 94-1 135l-2 3c-3 5-10 8-16 7l-59-6c44-33 72-84 78-139z" fill="lightgray" />
<!--Заднее стекло-->
<path d="M150 88v142l-41 6c-7 2-14-2-18-8l-9-18c-18-32-18-70 0-102l9-18c4-6 11-10 18-8z" fill="white" />
<!--Тень заднего стекла-->
<path d="M91 228l-5-9c31-35 53-76 64-121v132l-41 6c-7 2-14-2-18-8z" fill="lightgray" />
<!--Фары-->
<path d="M411 72l53 36-10 15-53-36zm43 124l10 15-54 35-10-15z" fill="yellow" />
</g>
<animateTransform attributeName="transform" type="translate"
begin="svg.click" dur="15s" values="10,456; 1510,456; 10,456" additive="replace" calcMode="linear" repeatCount="indefinite" fill="freeze" restart="whenNotActive" />
</g>
</svg>
然而,这样的动画只会让汽车直线移动一段路,这根本不是我想要的结果。
问题:如何播放城市地图上显示的汽车沿整条道路移动的动画?如果可能的话,最好考虑以下几点。城市地图图像的大小为 1600x900。如果用户的屏幕尺寸较小,则相应地,在我的示例中,整个 SVG 元素的尺寸会减小,以适应浏览器窗口的尺寸。那么,如何为 SVG 元素设置固定尺寸(例如,600x300),使其所有内部元素(地图和汽车)的尺寸不会减小,并且当汽车移动时,地图会在 SVG 元素内跟随它移动?


滚动时汽车运动的动画
基于@Sevastopol'代码(略微调整滚动)。
添加了实现汽车运动的脚本。
更新
根据@Sevastopol 的评论:
Решение:
Чтобы устранить этот эффект обрезания изображения, необходимо уменьшить картинку на 15% и немного поднять её вверх. Это решается с помощью изменения параметров
viewBox, как известно из теории SVG, при увеличении viewBox изображение уменьшается.Было -
viewBox="0 0 1600 900"(1600 * 1.15 = 1840)Стало -
viewBox="0 80 1840 1035"У меня широкоформатный дисплей. Проверял в Firefox, Chrome
Разрешения дисплея, при которых проводилась проверка:
1920 x 1080
1600 x 900
1600 x 1050
1680 x 1050
1600 x 1200
1440 x 700
1400 x 1050
1366 x 768
1280 x 1024
1280 x 960
1280 x 800
1280 x 720
1152 x 864
800 x 600
Если у кого-то при других разрешениях дисплея будет всё-таки наблюдаться обрезка изображения снизу, то просьба присылать не скриншоты, а технические характеристики ваших гаджетов и какой используется браузер, так как FF и webkit (blink) браузеры работают с масштабированием немного по разному
回答问题的第一部分:
<animateMotion>可以使用元素和属性再现元素(汽车)沿任意轨迹(道路)移动的动画path。<animateMotion>- 一个动画元素,可以让我们沿着给定的轨迹移动汽车;path- 用于设置运动轨迹的属性;要获得汽车所需的轨迹(路径),您需要将地图图像加载到任何矢量编辑器中并绘制曲线。
选择工具
кривые Безье和模式BSpline。此模式将使拐角(道路转弯)自动平滑。将文件保存在 中
SVG,在任何文本编辑器中打开它,然后复制它path。现在我们只需要使用动画元素启动汽车运动的动画
<animateMotion>:begin="btn.click"- 点击按钮后动画开始;dur="100s"- 动画持续时间;rotate="auto"— 元素相对于运动路径的方向。该值auto表示车辆将按照运动路径的方向角(沿切线方向矢量)随时间转动。<mpath xlink:href="#mPath"/>- 我们指的是外部路径,其中#mPath有从矢量编辑器(path)获得的运动轨迹。结果:
Анимация светофора, пешеходов
Добавлен пешеходный переход к школе, с работающим светофором.
При загорании зелёного на светофоре, начинается обычная суета на пешеходном переходе.
Анимация рассчитана, таким образом, чтобы пересечение дороги пешеходами было возможно, только на зелёный цвет.
Функция скроллинга анимации машины осталась. Крутите колесико.
Отвечая на вторую часть вопроса:
Содержимое SVG элемента отрисовывается на холсте, который может быть абсолютно любого размера. Видимая часть холста всегда соответствует размерам SVG элемента, и эта область называется — вьюпорт
viewport. SVG позволяет управлять размерами вьюпорта и поведением содержимого элемента, которое может показываться полностью, обрезаться или растягиваться. Таким поведением можно управлять с помощью атрибутовwidthиheight— это привычные нам стандартные свойства ширины и высоты элемента.Для кадрирования содержимого SVG элемента (изображения карты), чтобы показывать только какую-то ее часть, можно использовать атрибут
viewBox, у которого первые два значения — это координатыXиYот верхнего левого угла отображаемой области элемента, а последние два — его ширина и высота.<animate>您可以简单地使用动画元素和属性播放地图的动画attributeName:attributeName="viewBox"- 作为值,指定属性的名称viewBox,其中的前两个值将被动画化,从而移动SVG元素内部的地图。begin="svg.click"- 单击整个 SVG 元素的任意位置后开始动画;结果: