SVG的本机动画规范SMIL已受到高度重视,因为它为执行SVG动画渲染提供了许多技巧。 不幸的是,在WebKit中对SMIL的支持正在减弱,并且对于Microsoft的IE或Edge浏览器从未(也永远不会)存在。 没有恐惧! 我们已经覆盖了您。 本文探讨了某些特定于SMIL的功能,并深入研究了替代方法,以期获得更长的支持,从而达到相同的效果。

SMIL功能:沿路径运动

SMIL为SVG中逼真的运动提供的最引人注目的东西之一是沿着路径的运动。 现实生活中很少有事物沿直线运动,因此沿着路径运动可以使我们模仿日常生活中看到的事物。 以前,您需要使用path将SVG路径传递到animateMotion中,并定义路径数据。 通过使用xlink:href =”#thingtoanimate”指定要选择动画的元素。

<animateMotion xlink:href="#lil-guy" dur="3s" repeatCount="indefinite" fill="freeze" path="M 25,50 C 37.5,25 37.5,25 50,0 75,50 75,50 100,100 50,100 50,100 0,100 12.5,75 12.5,75 25,50 Z" />

见笔SMIL运动路径萨拉Drasner( @sdras )上CodePen 。

另类:CSS

对我们来说幸运的是,沿着路径模块的运动现在正在移入CSS 。 到目前为止,这种支持是微不足道的( 仅适用于Chrome,Opera和Android ):,但Sara Soueidan提议在Edge中采用,并且到目前为止,它已经得到了强有力的支持,在本文发表时,它获得了大约420票以上的支持。 请添加您的声音,以确保将提供此功能。 Firefox的投票在这里 。
据我所知,在Safari中投票寻求支持会更加个人化。 我注册以填写错误报告,并请求CSS中的运动路径模块作为一项功能。

为了在CSS中沿路径使用运动,您可以将路径数据传递给offset-path属性,如下所示:

.move-me {offset-path: path('M3.9,74.8c0,0,0-106.4,75.5-42.6S271.8,184,252.9,106.9s-47.4-130.9-58.2-92s59.8,111.2-32.9,126.1 S5.9,138.6,3.9,74.8z');
}

请参阅CodePen上CSS-Tricks( @ css-tricks )CSS中的“笔与运动路径模块一起 玩” 。

我从在Illustrator中制作的SVG获取路径数据,然后在SVGOMG中进行优化。

在这种情况下,我要确保它遵循从起点一直到路径终点的路径,并且您可以看到它是一条闭合路径,并由结尾处的小z表示。 这意味着这条路是一条环形路,所以这个怪异的小动物将最终到达他开始的那个地方。 我在关键帧值中设置这些参数,仅指定100%的值,因为默认值设置为零:

@keyframes motionpathguy {100% {motion-offset: 100%;}
}

然后在元素上调用动画:

.move-me {animation: motionpathguy 10s linear infinite both;
}

另一种选择:GreenSock的运动轨迹

如果您需要当前最广泛的支持和最灵活的实现,则应使用GreenSock。 GSAP的Bezier-Plugin(默认情况下与TweenMax打包在一起)为非SVG元素提供了对IE7的支持,对SVG提供了对IE9的支持(可用的最广泛的SVG动画支持)。 它就像手机上的大爆炸一样。 我之前在David Walsh博客上写过有关此内容的文章,但这里有一个简短的概述,以及此后出现的一些其他新功能:

最初,您将传递一个值数组:

bezier: {type: "soft",values:[{x:10, y:30}, {x:-30, y:20}, {x:-40, y:10}, {x:30, y:20}, {x:10, y:30}],autoRotate: true
}

但是正如您在此处看到的,您也可以选择自动旋转(或不自动旋转),就像SMIL的旋转一样。 如果您缺少SMIL为旋转的初始位置或旋转角度指定自动反转或auto:n参数的功能,则GSAP允许您使用rotation:90更改旋转角度的数量,或者在需要时使用更有限的控制:

autorotate: [first position property, like "x",second position property, like "y",rotation property, typically "rotation" but can be “rotationY”,integer for radians/degrees the rotation starts from like 10,boolean for radians or degrees- radians is true
]

在SMIL中,您可以变换路径或组以在对象移动时更改其方向。 在GSAP中,您可以使用autoRotate: false轻松实现此autoRotate: false ,并使用set初始化旋转。 您也可以像使用SMIL一样转换SVG属性本身上的元素,尽管这样做不太优雅,并且在工作时更难以跟踪。

TweenMax.set("#foo" {rotation: 90 // or whatever number
});

您还可以将类型设置为thrusoftquadraticcubic 。 有关这些工具的更多文档, 请参见GreenSock API文档 。 的nice值thru是能够影响的元件上弯曲度的量。 如果您将这些点视为要往返的坐标,则曲线将控制这些点之间的路径选择的直接程度。 0将是一条直接路径,1会稍微宽松一些,2会形成一条优美的曲线,3或更高的值会自动缠绕。

见笔演示的弯曲度在使用GreenSock贝塞尔萨拉Drasner( @sdras )上CodePen 。

最近,GreenSock还公开了传递路径数据(如CSS和SMIL模块)的功能,就像使用本地SMIL一样。 这是对他们的MorphSVG插件的扩展,因此您可以添加该插件,并按以下方式使用它:

TweenMax.to("#lil-guy", 3, {bezier: {MorphSVGPlugin.pathDataToBezier("#path", {align: "#lil-guy" }), type: "cubic"},ease: Linear.easeNone,repeat: -1
});
<path id="path" d="M 25,50 C 37.5,25 37.5,25 50,0 75,50 75,50 100,100 50,100 50,100 0,100 12.5,75 12.5,75 25,50 Z" fill="none" />

见笔SMIL运动路径萨拉Drasner( @sdras )上CodePen 。

默认设置是将我要设置动画的组的左上角(在本例中为#lil-guy )设置为路径轨迹。 这将使其在视觉上看起来未对齐。 所以我将#lil-guy设置为使用中心点,而不是使用TweenLite.set

TweenLite.set("#lil-guy", {xPercent:-50, yPercent:-50});

您还可以通过将对象作为第二个参数传递给该方法来偏移这些路径,并在pathDataToBezier定义offsetXoffsetY -请注意,您可能需要扩展viewBox以使要动画的组或属性不会被裁剪出来。 设置书呆子格式:出于可读性原因,我将对象放在新行上。

// offset the path coordinates by 125px on the x-axis, and 50px on the y-axis:
TweenMax.to("#lil-guy", 3, {bezier: {values: MorphSVGPlugin.pathDataToBezier("#path", {offsetX: 125, offsetY: 50, align: "#lil-guy"}),type: "cubic"},ease: Linear.easeNone,repeat: -1
});

见笔SMIL运动路径萨拉Drasner( @sdras )上CodePen 。

您甚至可以为此定位定义矩阵坐标。

// scale the path coordinates up by 1.25
// and shift it over 120px on the x-axis
// and up 30px on the y-axis:
TweenMax.to("#lil-guy", 3, {bezier: {values: MorphSVGPlugin.pathDataToBezier("#path", {matrix:[1.5,0,0,1.5,120,-30], align:"lil-guy"}),type: "cubic"},ease: Linear.easeNone,repeat: -1
});

见笔SMIL运动路径萨拉Drasner( @sdras )上CodePen 。

另一个选择是将align成员设置为"relative" 。 通过保持每个坐标相对于x:0y:0的位置,它可以防止跳跃。 在先前的笔中,我使用align将机芯与#lil-guy组本身配对。

有关GreenSocks的Bezier插件API中的这一新功能(如本篇文章当天的新内容一样)的更多信息,请查看其文档以及该精彩的解释性视频 。

SMIL功能:形状变形

以前,您可以将路径数据作为值传递到animate属性中,以使形状变形。 诺亚·布朗(Noah Blon)有一个很好的例子:

见笔Sitepoint挑战SVG和SMIL#1挪亚伦( @noahblon )上CodePen 。

替代方法:Snap.svg或SVG Morpheus

一些库提供了变形路径或形状值,例如Snap.svg和SVG Morpheus ,但要注意的是(即使在SMIL中)形状必须具有相同数量的点,或者变形看起来很糟糕或完全失败。 这在预处理方面令人失望,因为这意味着您必须很好地跟踪所做的工作,或者与设计人员进行良好的协作以确保获得此(有时是任意的)中点数据。 这些额外的点也不必要地膨胀了您的代码。

另一种选择:GreenSock MorphSVG

我强烈建议您使用GSAP的MorphSVG插件,因为它可以用不同数量的点精美地变形形状和路径。 请参阅此网站徽标上的切换按钮,以获取有关实际运行中的变体的演示。 这是另一个例子:

见笔可互换行家萨拉Drasner( @sdras )上CodePen 。

因为MorphSVG插件会补间路径数据,所以如果需要转换形状,则可以使用其convertToPath选项:

MorphSVGPlugin.convertToPath("ellipse");
// or circle, rect, etc

这使我们能够进行非常复杂的形状补间,并且可以改变网络上的所有运动。

该插件提供了一些额外的功能,真正使它脱离了公园。 第一个是实用程序插件findShapeIndex 。 假设您对形状的变形方式不满意(尽管9乘以10,自动预设就可以了)。 您加载了插件(不用担心,因为在生产中不需要它,所以不会增加额外的重量),并且传入两个值:第一个形状的补间ID和第二个形状的ID。 将会弹出一个GUI,您可以在其中切换值,并且它还将自动使用repeat: -1 ,以便在形状之间不断循环。

findShapeIndex("#hex", "#star");
// you can comment out above line to automatically disable findShapeIndex() UI

见笔SMIL运动路径萨拉Drasner( @sdras )上CodePen 。

一旦你的附加价值,你会通过shapeIndex的内morphSVG对象:

TweenLite.to("#hex", 1, {morphSVG: { shape: "#star", shapeIndex: 1 }});

这些额外功能中的第二个是插件解析切出路径的能力,这是其他库所没有的。 最后,您还可以重用第一个起始ID(而不是必须存储该路径数据以供重用)。 值得一提的是,当插件首次发布时,这些功能尚不可用,但是GreenSock意识到需要支持,因此将其包含在内。

既然我们不局限于特定数量的点,我们就扩大了产生不同种类效果的可能性。 下面,我抽了一些烟:

在 CodePen上查看 Sarah Drasner( @sdras ) 撰写的《 有烟的笔》 。

SMIL功能:DOM事件

诸如悬停和单击之类的东西很好地融入了SMIL中。 为了开始工作,可以指定begin="click"begin="hover"

<animate xlink:href="#rectblue"attributeName="x"from="0"to="300" dur="1s"begin="click"values="20; 50"keyTimes="0; 1"fill="freeze" />

见笔SMIL运动路径萨拉Drasner( @sdras )上CodePen 。

另一种选择:JavaScript

有一些本地DOM事件,例如onmouseenteronmouseleave用于悬停并click (例如,单击)。 您可以使用它们进行更改以触发基于JavaScript的动画。

另一种选择:JavaScript + CSS

您可以使用JavaScript更改类名或直接更改CSS样式。 这是可能的:更改animation-play-state以从事件触发器启动动画。

.st0 {animation: moveAcross 1s linear both;animation-play-state: paused;
}
@keyframes moveAcross {to {transform: translateX(100px);}
}
document.getElementById("rectblue").addEventListener("click", function() {event.target.style.animationPlayState = "running";
});

或在jQuery中:

$(".st0").on("click", function() {$(this).css("animation-play-state", "running");
});

见笔SMIL运动路径萨拉Drasner( @sdras )上CodePen 。

此实现不会像SMIL示例中那样立即将动画重新设置为开始。 如果您想做到这一点,那么上一篇有关CSS-Tricks的文章详细介绍了一些不错的方法。

另一种选择:Greensock

在GSAP中,重新启动更为简单。 我们可以将动画添加到时间轴,将其设置为暂停,然后单击重新启动它。 此实现与您对SMIL的期望有点接近,因为我们不必做任何麻烦的事情,例如克隆/重新插入DOM节点或更改元素上设置的任何属性。

// instantiate a TimelineLite
var tl = new TimelineLite();// add a tween to the timeline
tl.to(foo, 0.5, { left: 100 });$(".st0").on("click", function() {tl.restart();
});

SMIL功能:在“ Y”完成后运行“ X”

SMIL还允许进行更复杂的定时事件,例如begin="circ-anim.begin + 1s" 。 当链接动画时,这特别有用。

另类:CSS

在CSS中,我们可以通过在第二个值上设置延迟来链接动画:

.foo {animation: foo-move 2s ease both;
}
.bar {animation: bar-move 4s 2s ease both; /* the 2 second value corresponds with the length of the iteration of the first. */
}

这种工作方式有点令人讨厌,因为您必须确保记住要更改第一个间隔以及延迟。

另一种选择:CSS预处理

如果我们在(例如)Sass中使用变量,则维护和管理这些间隔会变得容易一些:

$secs: 2s;
.foo {animation: foo-move $secs ease both;
}
.bar {animation: bar-move 4s $secs ease both;
}

现在我们知道,如果我们更新一个值,它们将保持同步。

但是,如果我们想在动画完成时,总是发现,JavaScript的提供了这跟一些不错的本地功能animationEnd

$("#rectblue").on("animationend", function() {   $(this).closest("svg").find("#rectblue2").css("animation-play-state", "running");
});
#rectblue2 {animation: moveAcross 2s 1s ease both;animation-play-state: paused;
}

您可能需要单击重播才能看到以下动画:

见笔SMIL运动路径萨拉Drasner( @sdras )上CodePen 。

对于延迟,我们可以将其烘焙到元素本身CSS的animation-delay属性中,就像上面一样,或者我们可以使用setTimeout来表示:

setTimeout(function timeoutHandler() {// animation goes here, with any language
}, 1000); // wait for a second

另一种选择:Greensock

我最喜欢的选项是添加动画时间轴的有限控制。 我们可以为此使用GreenSock的TimelineLite,可以用几种不同的方式表示:
简单的时间轴:

// instantiate a TimelineLite
var tl = new TimelineLite();// add a tween at the beginning of the timeline
tl.to(foo, 0.5, { left: 100 });// use the position parameter "+=1" to schedule next tween 1 second after the previous tweens end
tl.to(foo, 0.5, { left: 200 }, "+=1");

具有相对标签的时间轴:

// add a label 0.5 seconds later to mark the placement of the next tween
tl.add("myRelativeLabel")
// use the label to specify an animation a second after the
tl.to(foo, 0.5, { scale: 0 }, "myRelativeLabel+=1");// or to use to this label for things like interaction
tl.play("myRelativeLabel");

我更喜欢相对标签,因为您可以选择一个时间点,很多东西会触发或延迟,即使该时间点调整了,您也不必像在CSS中那样进行任何重新计算。 。

时间轴的好处是,您可以在一个位置上很好地控制许多不同的对象,并且可以提供诸如repeatDelay (多次重复之间的延迟)之类的功能。

SMIL提供了repeatDur ,如果您不希望将其作为默认值(例如repeatDur="01:30" ,则可以让您说出重复迭代的时间。 在GreenSock中,您可以加快或减慢时间轴,从而通过timeScale(n)调整重复长度,或将repeat: -1次数设置为repeat: -1 ,否则将设置repeatDur="indefinite"

方便的Dandy更换参考表

既然我们已经深入研究了一些最有用的SMIL特定功能,那么值得注意的是,您可能已经了解了SMIL功能的许多替代品。 我们制作了下表,以便快速参考这些更简单的实现。

SMIL代码 代号 替代技术
关键时间 @keyframes CSS
keySplines 三次贝塞尔曲线 CSS
重新开始 重新开始(); GSAP
calcMode =“离散” 脚步() CSS
去掉 杀();
明确();
clearProps:“全部”
GSAP
冻结 动画播放状态:已暂停 CSS
冻结 暂停(); GSAP
动画填充模式 CSS
repeatCount =“不确定” animation-iteration-count:无限; CSS
repeatCount =“不确定” 重复:-1 GSAP
whenNotActive 在JS中检测动画播放状态 CSS,香草JavaScript或jQuery
animateMotion路径 运动路径 CSS
animateMotion路径 贝塞尔 GSAP
设置动画值(路径变形) 变形SVG GSAP
开始=“悬停” mouseover,mouseenter /
鼠标移开,鼠标离开
jQuery,香草JS
begin =“点击” 点击 jQuery,香草JS
begin =” circ-anim.begin + 1s” 动画延迟:$ vars; 萨斯
begin =” circ-anim.begin + 1s” 时间轴,位置参数ex“ + = 1” GSAP

翻译自: https://css-tricks.com/smil-is-dead-long-live-smil-a-guide-to-alternatives-to-smil-features/

SMIL已经死了! SMIL万岁! SMIL功能替代指南相关推荐

  1. 观点:API已死,APIs万岁 - 学习

    1.应用场景 主要用于学习目前客户端与服务端进行通讯交互的方式集合,以及为什么说,api已死,或将死. 2.学习/操作 1.文档阅读 观点:API已死,APIs万岁-极客时间 API Is Dead ...

  2. SEO 已死,LLMO 万岁

    "北风那个吹,雪花那个飘",我手捧一杯咖啡,听着白毛女.朋友坐在对面高谈阔论:"有了 ChatGPT,我再也不缺内容了,SEO 的春天就要来了!" 然而他没有看 ...

  3. SEO 已死,LLMO 万岁 1

    "北风那个吹,雪花那个飘",我手捧一杯咖啡,听着白毛女.朋友坐在对面高谈阔论:"有了 ChatGPT,我再也不缺内容了,SEO 的春天就要来了!" 然而他没有看 ...

  4. Spread for WinRT 7新功能使用指南

    您可以将Microsoft Excel 的强大功能嵌入到Windows 8 商店应用程序中,使用丰富的内嵌数据可视化功能展现核心数据和分析结果,按需定制富有创意的表格模版以及发挥更多便捷高效的作用.S ...

  5. Android P适配以太网功能开发指南

            Android P适配以太网功能开发指南 Android网络框架分析系列文章目录: Android P适配以太网功能开发指南 Android以太网框架情景分析之启动简介 Android ...

  6. 物联网已死,API 万岁!

    "物联网"的未来从来都不是关于更快.更好.更新和更多的硬件,它一直是聚焦于让设备协同工作,创造奇迹.作为用户,未来我们是否注定了要不断地在手机上搜索应用程序?或者绞尽脑汁试图让设备 ...

  7. TensorFlow已死,TensorFlow万岁!

    如果你是一名人工智能爱好者,却没有关注到一条重大新闻,就好比你在一场罕见的地震中打了个盹.等你醒来,会发现一切都将改变! TensorFlow 2.0来了! 革命就在这里!欢迎来到TensorFlow ...

  8. Spread for Windows Forms 7新功能使用指南

    2019独角兽企业重金招聘Python工程师标准>>> 表格控件 Spread for WinForms 表格控件兼容Excel的强大功能,并将其嵌入到您的应用系统中.完备的Exce ...

  9. java开发指南_Java 12新功能完整指南

    java开发指南 六个月飞得如此之快,是时候再次仔细研究一下即将发布的新JDK版本. 让我们满足Java 12及其向开发人员介绍的功能. 自Oracle推出加速六个月的发布节奏以来已经有一段时间了,要 ...

最新文章

  1. 3Blue1Brown:“线性代数的本质”完整笔记
  2. springmvc三十二:spring mvc的运行流程
  3. 多线程:同步和异步的优缺点比较
  4. Vue CLI3.0 中使用jQuery 和 Bootstrap
  5. python卷积神经网络cnn的训练算法_【深度学习系列】卷积神经网络CNN原理详解(一)——基本原理...
  6. 使用Spring Boot和DJL进行深度学习
  7. Winform开发框架中工作流模块的动态处理
  8. NSX控制平面和静态路由更新流程1
  9. 3.emWin5.26(ucGui)VS2008 2-D图形库-基本绘图【Worldsing笔记】
  10. 数据安全-整体解决方案
  11. 计算机应用基础 电子科技大学出版社,大学计算机基础课本答案(电子科技大学出版社)...
  12. 微信卡券新功能开放公告
  13. C语言从入门到精通——指针基础
  14. 达梦出席湖北银行业金融机构信息科技风险管理研讨会
  15. 夹角余弦 python_python 根据余弦定理计算两边的夹角
  16. ratingbar 的使用
  17. [转]gps中的广义和狭义相对论效应
  18. 怎样将语音文件转换成文字
  19. gmsh+fltk配置过程
  20. 是男人就坚持20秒—python版本

热门文章

  1. 在OpenCV里实现二维离散卷积1
  2. windows下的grep
  3. 统一依赖管理Composing builds
  4. 作为成员的结构体(作为结构体的成员的结构体)
  5. C语言Hello World
  6. java过滤器filter过滤相同url时的执行顺序
  7. 程序的编译(详解翻译环境)
  8. wchar to char转换
  9. 6n137光耦怎么测好坏_光电耦合器怎么测
  10. BLEMotion-Kit 支持蓝牙运动传感评估套件