我最近在CodePen上发表了一个DEMO来庆祝新的一年,然后得到了很多积极的反馈,关于我如何使用viewBox
来作为我的场景中的camera的。
所以我决定来写一篇文章来介绍一下这个动画是如何创作的~
Happy New Year !
打开礼物之后,点击小场景来放大
什么是viewBox
?
我不会讲得很详细,网上有很多关于viewBox
的文章都讲得很好。
简单来说,viewBox
是SVG中可见的内容区域。任何超出viewBox
的内容都是不可见的,依赖于你的SVG的尺寸和比例。
你可以在<svg>
标签中定义这样四个值:
<svg viewBox="min-x min-y width height">
好了开始吧!
首先我创建一个简单的HTML文档,包含一个SVG。
Freepik设计的图(我进行了简化)
SVG中定义的viewBox
是实际上显示在我们屏幕上的尺寸。也就是说我们的SVG的元素都是的viewBox
中显示的。
试着调整窗口的大小(或编辑面板的大小),你会看到SVG是如何缩放的~
更新viewBox
在这个DEMO中,我绘制了一个红色的半透明矩形来展示我们将要给viewBox
应用的新值。将鼠标移动到矩形上,来更新viewBox
,看看SVG如何重新绘制。
很神奇,对吧?
我们的SVG没有变,所有在viewBox
外面的元素依旧在页面上,但是依旧看不到。
因为SVG的尺寸和比例,你可能只看到场景水平轴上的一些部分(至少在这支嵌入的pen中)
如果你不理解我是如何给viewBox
应用新值的,点击javascript面板
通过viewBox
添加动画
现在我们知道要如何更新viewBox
的值了,但是还完全算不上动画。
遗憾的是我们目前还不能通过CSS来给viewBox
添加动画,我们需要一些javascript。
我经常使用[TweenMax](https://greensock.com/来创建动画,因为这是我目前自己觉得最好用的这方面的javascript插件。
这是一个简单的动画实例,viewBox
从原始尺寸变为矩形。
我们来看看如何在TweenMax中设置动画:
TweenMax.to( svg, //我们的SVG 2, //动画的持续时间 { attr:{//在新的frame中更新属性的值 viewBox: "220 110 370 350" //指定动画的最终值 }, repeat: -1, //不断重复我们的动画 yoyo: true, //动画会像悠悠球一样来回播放 } );
你可以看到,让viewBox
从一帧到另一帧的补间其实非常容易。只需要这几行代码,你就可以创建很多很多的可能性。
使用viewBox
作为camera
我们来看看我的那个Happy New Year pen,这是我如何使用viewBox
来作为camera来对场景进行缩放。
我在SVG创建了可点击的区域,但是只有在hover的时候可见。我们使用它来触发点击小场景的事件。
//Select all my areas var overlays = svg.querySelectorAll("#overlays > g"); //在每个区域添加事件监听 for (var i = 0; i < overlays.length; i++) { overlays[i].addEventListener("click", zoomViewBox); } //这个变量用来检查viewBox是否已经放大了 var zoom = false; //我创建了包含每个区域的值的对象 //每个key都对应一个区域的id var viewBoxes = { "overHouses": { x: 43, y: 290, width: 130, height: 67 }, "overSnowmen": { x: 250, [...] };
当用户点击了任何区域,我们可以调用zoomViewBox()
函数:
function zoomViewBox(e) { //如果用户在viewBox已经放大的时候点击区域 //或者,最初的动画还没有结束,先暂停函数的调用 if (zoom || !animationOn) { return; } //To prevent other unwanted events e.stopPropagation(); //Each area has a unique ID which var id = this.getAttribute("id"); //这块代码和前面的实例是一样的,但是现在值不是静态的 //我把它们从viewBox对象拿出来,赋一块包含id的可点击区域 TweenMax.to(svg, 2, { attr:{ viewBox: viewBoxes[id].x + " " + viewBoxes[id].y + " " + viewBoxes[id].width + " " + viewBoxes[id].height }, ease: Power3.easeOut }); //现在SVG已经放大了 zoom = true; }
允许用户放大,我检查了SVG上的每一次点击,如果SVG是放大状态的,那我们就调用unZoom()
函数。
//监听SVG上的每一次点击 svg.addEventListener("click", unZoom); function unZoom() { zoom = false;//将值设置为false //这还是同一个动画,只是现在不是初始值 TweenMax.to(svg, 2, {attr:{viewBox:"0 0 1600 900"}, ease: Power3.easeOut}); }
以上是整个JavaScript的一个大概。如果你对这块感兴趣的话,我鼓励你去看看完整的代码。
案例
这里的这个实例,默认的viewBox
后面隐藏了三个场景,在用户做出选择时候是可见的。
(点击RERUN来重置pen)
另一个来自David Bachmann Johannesson的实例你可能已经在Codepen上看过了。
网友评论文明上网理性发言 已有0人参与
发表评论: