Image placeholder

弹性摇摆效果幻灯片插件

Image placeholder
F2EX 2014-10-27

幻灯片中的图片在移动时弹性摆动。使用 Snap.svg 和 SVG 动画制作。

为了使幻灯片以摇摆的方式移动,我们使用了 Snap.svg 和幻灯片背景动画来模拟弹性效果。基本原理是将一个 SVG 路径从一个矩形变成一个弯曲的形状,根据我们正在导航的地方,你可以选择右曲线或左曲线。

Wobbly Slideshow Effect

效果中这些精致的图标来自 Pixel Buddha 创建的免费 Ballicons 2 图标。

幻灯片的标记是一个无序列表:

<div id="slideshow" class="slideshow">
<ul>
<li>
<div class="slide">
<!-- ... -->
</div>
</li>
<li><!-- ... --></li>
<li><!-- ... --></li>
<!-- ... -->
</ul>
</div>

重点是在幻灯片前插入一个 SVG, 该路径是一个矩形。插入后的 SVG 如下:

<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 80 60" preserveAspectRatio="none">
<path d="M33,0C33,0,74,0,74,0C74,0,69,9.871,69,29.871C69,49.871,74,60,74,60C74,60,32.666,60,32.666,60C32.666,60,32.541,60,32.541,60C32.541,60,6,60,6,60C6,60,1,50,1,30C1,10,6,0,6,0C6,0,33,0,33,0" />
</svg>

三个不同的 SVG 路径组成了下列形状:

你可以在下载的文件的 “img” 文件夹中找到这些 SVGs 。

根据我们导航到的位置, 我们会将形状向左或向右弯曲。这一动画将使它看起来好像是拉或推一个弹性物体。

这些路径是在幻灯片播放选项中定义的:

SliderFx.prototype.options = {

	// 默认速度 (ms)
	speed : 500,

	// 默认缓动
	easing : 'ease',

	// 定义路径
	paths : {
		rect : 'M33,0h41c0,0,0,9.871,0,29.871C74,49.871,74,60,74,60H32.666h-0.125H6c0,0,0-10,0-30S6,0,6,0H33',
		curve : { 
			right : 'M33,0h41c0,0,5,9.871,5,29.871C79,49.871,74,60,74,60H32.666h-0.125H6c0,0,5-10,5-30S6,0,6,0H33', 
			left : 'M33,0h41c0,0-5,9.871-5,29.871C69,49.871,74,60,74,60H32.666h-0.125H6c0,0-5-10-5-30S6,0,6,0H33'
		}
	}

}

下面是我们在导航时如何实际控制路径的变形:

SliderFx.prototype._morphSVGs = function( callback ) {

	var self = this,
		speed = this.options.speed,
		pathCurvedLeft = this.options.paths.curve.left,
		pathCurvedRight = this.options.paths.curve.right,
		pathRectangle = this.options.paths.rect,
		dir = this.old < this.curr ? 'right' : 'left';

	// 在退出幻灯片时 svg 路径 "curved"
	this.items[ this.old ].path.stop().animate( { 'path' : dir === 'right' ? pathCurvedLeft : pathCurvedRight }, speed * .5, mina.easeout );

	// 滑块稍晚一会开始
	setTimeout(function() { callback.call(); }, speed * .2 );
	
	// 在进入幻灯片时更改 svg 路径 "curved"
	var currItem = this.items[ this.curr ];
	currItem.querySelector('path').setAttribute( 'd', dir === 'right' ? pathCurvedLeft : pathCurvedRight );
	
	// 进入幻灯片 "rectangle" 时变形 svg 路径
	setTimeout(function() { currItem.path.stop().animate( { 'path' : pathRectangle }, speed * 3, mina.elastic ); }, speed * .5 );

}	

时间是这里最重要的一个因素。例如,当将 SVG 路径变形到右曲线时,我们要确保变形的时长是幻灯片移动的一半(即速度 * .5)。这样可以确保在幻灯片消失之前,我们仍然可以看到它变得弯曲。我们也延迟了滑块移动的开始时间。首先将幻灯片的路径设置为弯曲, 然后将其变形为矩形形状。你可以更改曲线的方向, 以便更改效果, 使其看起来像元素正在被拉或推。将 dir == "right" 改为 “left”, 进入幻灯片以查看差异。在最后一个变形中, 我们设置进入路径为一个矩形, 我们可以改变两个地方: 变形的速度和延迟。如果希望变形要花更长的时间, 那么就能看到类似果冻的效果。但这影响性能。

如果你有时间去研究下变形的速度和延迟,你会让它变形成其他任何看起来很酷炫的效果。

例如:

// morph svg path on exiting slide to "curved"
this.items[ this.old ].path.stop().animate( { 'path' : dir === 'right' ? pathCurvedLeft : pathCurvedRight }, speed * .7, mina.easeout );

// 滑块稍晚开始..
setTimeout(function() { callback.call(); }, speed * .3 );

// 在进入幻灯片时更改 svg 路径 "curved"
var currItem = this.items[ this.curr ];
currItem.querySelector('path').setAttribute( 'd', dir === 'left' ? pathCurvedLeft : pathCurvedRight );

// 进入幻灯片 "rectangle" 时变形 svg 路径
setTimeout(function() { currItem.path.stop().animate( { 'path' : pathRectangle }, speed * 5, mina.elastic ); }, speed * .8 );