SVG/HTML5动画图标 可用作图标菜单导航

2018-02-05 10:31:34来源:http://www.html5tricks.com/svg-css3-animated-icon-menu.html作者:HTML5资源教程人点击

分享

本文作者html5tricks,转载请注明出处


今天我们要给大家分享一款简易实用的SVG动画图标应用,这种动画图标现在越来越多地用于网页菜单导航,因为它使用起来简单,而且支持大部分浏览器。这款SVG/HTML5动画图标可以在鼠标滑过图标时产生简单的循环播放的动画特效。



在线演示 源码下载


下面我们一起来简单解说一下实现这款SVG动画图标的过程。


HTML代码

毋庸置疑,SVG是这款图标的核心代码,图标的外观均是采用SVG路径绘制而成,这里我们挑选第一个图标作为例子,SVG代码如下:


<svg version="1.1" id="web-skill" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="160px" height="108px" viewBox="0 0 160 108" enable-background="new 0 0 160 108" xml:space="preserve">
<g id="mobile" style="transform: matrix(1, 0, 0, 1, 0, 0);">
<path fill="#FFFFFF" d="M49.1,102.4c0,1.2-1,2.1-2.1,2.1H20.6c-1.2,0-2.1-1-2.1-2.1v-56c0-1.2,1-2.1,2.1-2.1h26.3
c1.2,0,2.1,1,2.1,2.1v56H49.1z"></path>
<path fill="#00D9B3" d="M46.9,106H20.6c-2,0-3.6-1.6-3.6-3.6v-56c0-2,1.6-3.6,3.6-3.6h26.3c2,0,3.6,1.6,3.6,3.6v56
C50.6,104.4,48.9,106,46.9,106z M20.6,45.7c-0.3,0-0.6,0.3-0.6,0.6v56c0,0.4,0.3,0.6,0.6,0.6h26.3c0.4,0,0.6-0.3,0.6-0.6v-56
c0-0.4-0.3-0.6-0.6-0.6H20.6z"></path>
<path fill="#00D9B3" d="M35.9,97.2c0,1.2-1,2.1-2.1,2.1c-1.2,0-2.1-1-2.1-2.1c0-1.2,1-2.1,2.1-2.1C35,95,35.9,96,35.9,97.2"></path><path fill="#00D9B3" d="M35.4,76.5c2.3-0.8,3.9-2.9,3.9-5.4c0-3.2-2.6-5.7-5.7-5.7c-3.2,0-5.7,2.6-5.7,5.7v10.1
c0,0.5,0.4,0.9,0.9,0.9h10.1c0.4,0,0.7-0.2,0.8-0.5c0.1-0.3,0.1-0.7-0.2-1L35.4,76.5z M33.6,67.1c2.2,0,4,1.8,4,4
c0,2.1-1.6,3.8-3.6,4l-4.3-4.3C29.8,68.7,31.5,67.1,33.6,67.1 M29.6,80.3v-7.1l7.1,7.1H29.6z"></path>
</g>
<g id="desktop" style="transform: matrix(1, 0, 0, 1, 0, 0);">
<path fill="#FFFFFF" d="M128.6,77.6c0,1.7-1.3,3-3,3H46.5c-1.7,0-3-1.3-3-3V21.1c0-1.7,1.3-3,3-3h79.1c1.7,0,3,1.3,3,3V77.6z"></path>
<path fill="#00D9B3" d="M125.6,82.1H46.5c-2.5,0-4.5-2-4.5-4.5V21.1c0-2.5,2-4.5,4.5-4.5h79.1c2.5,0,4.5,2,4.5,4.5v56.5
C130.1,80.1,128.1,82.1,125.6,82.1z M46.5,19.6c-0.8,0-1.5,0.7-1.5,1.5v56.5c0,0.8,0.7,1.5,1.5,1.5h79.1c0.8,0,1.5-0.7,1.5-1.5
V21.1c0-0.8-0.7-1.5-1.5-1.5H46.5z"></path>
<path fill="#00D9B3" d="M101.8,106c-7.3,0-13.2-5.9-13.2-13.2V80.6c0-0.8,0.7-1.5,1.5-1.5c0.8,0,1.5,0.7,1.5,1.5v12.2
c0,5.6,4.6,10.2,10.2,10.2c0.8,0,1.5,0.7,1.5,1.5S102.7,106,101.8,106z"></path>
<path fill="#00D9B3" d="M70.2,106c-0.8,0-1.5-0.7-1.5-1.5s0.7-1.5,1.5-1.5c5.6,0,10.2-4.6,10.2-10.2V80.6c0-0.8,0.7-1.5,1.5-1.5
c0.8,0,1.5,0.7,1.5,1.5v12.2C83.4,100.1,77.5,106,70.2,106z"></path>
<path fill="#00D9B3" d="M88.6,53.8c3.6-1.2,6.2-4.6,6.2-8.6c0-5-4.1-9-9-9c-4.9,0-9,4.1-9,9v15.9c0,0.8,0.6,1.4,1.4,1.4H94
c0.6,0,1.1-0.3,1.3-0.8s0.1-1.1-0.3-1.5L88.6,53.8z M85.7,38.9c3.5,0,6.3,2.8,6.3,6.3c0,3.3-2.5,6-5.7,6.3l-6.8-6.8
C79.8,41.5,82.5,38.9,85.7,38.9 M79.5,59.7V48.5l11.2,11.2H79.5z"></path>
</g>
<g id="mobile2" opacity="0" style="transform: matrix(1, 0, 0, 1, 0, 0); opacity: 0;">
<path fill="#FFFFFF" d="M49.1,102.4c0,1.2-1,2.1-2.1,2.1H20.6c-1.2,0-2.1-1-2.1-2.1v-56c0-1.2,1-2.1,2.1-2.1h26.3
c1.2,0,2.1,1,2.1,2.1L49.1,102.4L49.1,102.4z"></path>
<path fill="#00D9B3" d="M46.9,106H20.6c-2,0-3.6-1.6-3.6-3.6v-56c0-2,1.6-3.6,3.6-3.6h26.3c2,0,3.6,1.6,3.6,3.6v56
C50.6,104.4,48.9,106,46.9,106z M20.6,45.7c-0.3,0-0.6,0.3-0.6,0.6v56c0,0.4,0.3,0.6,0.6,0.6h26.3c0.4,0,0.6-0.3,0.6-0.6v-56
c0-0.4-0.3-0.6-0.6-0.6H20.6z"></path>
<path fill="#00D9B3" d="M35.9,97.2c0,1.2-1,2.1-2.1,2.1c-1.2,0-2.1-1-2.1-2.1c0-1.2,1-2.1,2.1-2.1C35,95,35.9,96,35.9,97.2"></path><path fill="#00D9B3" d="M35.4,76.5c2.3-0.8,3.9-2.9,3.9-5.4c0-3.2-2.6-5.7-5.7-5.7c-3.2,0-5.7,2.6-5.7,5.7v10.1
c0,0.5,0.4,0.9,0.9,0.9h10.1c0.4,0,0.7-0.2,0.8-0.5c0.1-0.3,0.1-0.7-0.2-1L35.4,76.5z M33.6,67.1c2.2,0,4,1.8,4,4
c0,2.1-1.6,3.8-3.6,4l-4.3-4.3C29.8,68.7,31.5,67.1,33.6,67.1 M29.6,80.3v-7.1l7.1,7.1H29.6z"></path>
</g>
</svg>

不要看这么长的代码,其实如果你了解SVG语法的话,你会觉得很简单,这仅仅利用的path画点画线而已。


CSS代码

这里的CSS代码对图标而言并没有什么太大的用途,主要是用来控制图标的大小以及间距而已。


ul {
width: 100%;
list-style: none;
padding: 0;
text-align: justify;
}
ul::after {
width: 100%;
display: inline-block;
content: ".";
visibility: hidden;
}
li {
text-align: left;
width: 220px;
display: inline-block;
margin-right: 0;
padding-bottom: 30px;
}
li .image {
display: table;
vertical-align: bottom;
width: 100%;
min-height: 108px;
max-height: 108px;
height: 108px;
margin-bottom: 25px;
}
li .image .row {
display: table-cell;
vertical-align: bottom;
width: 100%;
}
svg {
vertical-align: bottom;
width: auto !important;
}
JavaScript代码

这里主要使用了jQuery框架和TweenMax动画框架,通过调用TweenMax框架的动画方法,让小图标进行循环播放动画,首先引用jQuery框架和TweenMax框架:


<script src='js/jquery.min.js'></script>
<script src='js/TweenMax.min.js'></script>

完整的JS代码如下:


var AnimateInteractive = function($main) {
this.svgContainer = $main.find("#interactive-skill");
if (this.svgContainer.length === 0) {
return;
}
this.finger = this.svgContainer.find('#finger');
this.buttonbg = this.svgContainer.find('#button_bg');
this.timeLine = new TimelineMax({
yoyo: true,
paused: true,
onComplete: function() {
//this.restart();
}
})
.to(this.finger, 0.4, {
x: -21,
y: 20,
delay: 0.7
})
.to({
fake: 0
}, 0.3, {
fake: 30
})
.to(this.buttonbg, 0.01, {
opacity: 1
}, 1)
.to(this.finger, 0.7, {
x: 0,
y: 0
})
.to(this.buttonbg, 0.2, {
opacity: 0
}, 1.3);
this.svgContainer.off('runAnimation').on('runAnimation', function() {
this.timeLine.play();
}.bind(this));
this.svgContainer.off('stopAnimation').on('stopAnimation', function() {
this.timeLine.reverse();
}.bind(this));
};
var AnimateHTML = function($main) {
this.svgContainer = $main.find("#html5-skill");
if (this.svgContainer.length === 0) {
return;
}
this.star = this.svgContainer.find('#star');
this.status = false;
this.star.css('transform-origin', '56.5px 44.5px 0');
var self = this;
this.timeLine = new TimelineMax({
yoyo: true,
paused: true,
onComplete: function() {
//this.restart();
},
onReverseComplete: function() {
//if(self.status) this.restart();
}
})
.to(this.star, 0.50, {
y: -19
})
.to(this.star, 0.14, {
rotationY: 90,
ease: Linear.easeNone
}, 0.10)
.to(this.star, 0.14, {
rotationY: 0,
ease: Linear.easeNone
}, 0.24)
.to(this.star, 0.14, {
rotationY: 90,
ease: Linear.easeNone
}, 0.38)
.to(this.star, 0.14, {
rotationY: 0,
ease: Linear.easeNone
}, 0.52)
.to(this.star, 0.14, {
rotationY: 90,
ease: Linear.easeNone
}, 0.66)
.to(this.star, 1.00, {
y: 0,
ease: Bounce.easeOut
}, 0.80)
.to(this.star, 0.14, {
rotationY: 0,
ease: Linear.easeNone
}, 0.85);
this.svgContainer.off('runAnimation').on('runAnimation', function() {
this.timeLine.restart();
}.bind(this));
};
var AnimateEvents = function($main) {
this.svgContainer = $main.find("#event-skill");
if (this.svgContainer.length === 0) {
return;
}
this.flag = this.svgContainer.find('#flag');
this.stick = this.svgContainer.find('#stick');
this.stickPath = this.stick.find('path');
this.flag.css({
'transform-origin': '80px 0 0'
});
this.timeLine = new TimelineMax({
yoyo: true,
paused: true
})
.set(this.flag, {
rotationY: 90
})
.set(this.stick, {
y: 35
})
.set(this.stickPath, {
'fill-opacity': 0
})
.to(this.stick, 0.7, {
y: 0
})
.to(this.stickPath, 0.7, {
'fill-opacity': 1
}, 0)
.to(this.flag, 2.5, {
rotationY: 360
})
.to(this.flag, 2.5, {
rotationY: 0
});
this.svgContainer.off('runAnimation').on('runAnimation', function() {
this.timeLine.restart();
}.bind(this));
};
var AnimateSDK = function($main) {
this.svgContainer = $main.find("#sdk-skill");
if (this.svgContainer.length === 0) {
return;
}
this.bolt = this.svgContainer.find('#bolt');
this.key = this.svgContainer.find('#key');
this.bolt.css('transform-origin', '33px 82px 0');
this.key.css('transform-origin', '43px 70px');
this.timeLine = new TimelineMax({
yoyo: true,
paused: true,
onComplete: function() {
this.restart();
}
})
.to(this.key, 0.7, {
x: -11,
y: 11
})
.to([this.key, this.bolt], 0.6, {
rotation: 20,
ease: RoughEase.ease.config({
strength: 3.6,
points: 4,
template: Bounce.easeOut,
randomize: false,
taper: "out",
clamp: true
})
})
.to([this.key, this.bolt], 0.4, {
rotation: 0
})
.to(this.key, 0.7, {
x: 0,
y: 0
});
this.svgContainer.off('runAnimation').on('runAnimation', function() {
this.timeLine.play();
}.bind(this));
this.svgContainer.off('stopAnimation').on('stopAnimation', function() {
this.timeLine.reverse();
}.bind(this));
};
var AnimateSocial = function($main) {
this.svgContainer = $main.find("#social-skill");
if (this.svgContainer.length === 0) {
return;
}
this.person_a = this.svgContainer.find('#person_a');
this.person_b = this.svgContainer.find('#person_b');
this.person_a.css('transform-origin', 'center bottom');
this.person_b.css('transform-origin', 'center bottom');
this.timeLine = new TimelineMax({
yoyo: true,
paused: true,
onComplete: function() {
this.restart();
}
})
.to(this.person_a, 0.2, {
y: -10
})
.to(this.person_a, 0.2, {
y: 0
})
.to(this.person_a, 0.2, {
y: -8
})
.to(this.person_a, 0.2, {
y: 0
})
.to(this.person_b, 0.2, {
y: -10
})
.to(this.person_b, 0.2, {
y: 0
})
.to(this.person_b, 0.2, {
y: -8
})
.to(this.person_b, 0.2, {
y: 0
});
this.svgContainer.off('runAnimation').on('runAnimation', function() {
this.timeLine.play();
}.bind(this));
this.svgContainer.off('stopAnimation').on('stopAnimation', function() {
this.timeLine.reverse();
}.bind(this));
};
var AnimateUX = function($main) {
this.svgContainer = $main.find("#ux-skill");
if (this.svgContainer.length === 0) {
return;
}
this.blink = this.svgContainer.find('#blink');
this.pupil = this.svgContainer.find('#pupil');
this.pupil.css('transform-origin', '27px -40px');
this.timeLine = new TimelineMax({
yoyo: true,
paused: true,
onComplete: function() {
this.restart();
}
})
.to(this.blink, 0.001, {
opacity: 1,
delay: 0.2
})
.to(this.blink, 0.1, {
opacity: 0,
delay: 0.2
})
.to(this.pupil, 0.3, {
x: 1,
y: 0
})
.to(this.pupil, 0.3, {
x: -1,
y: 0
})
.to(this.pupil, 0.3, {
x: 0,
y: 0
})
.to(this.blink, 0.001, {
opacity: 1,
delay: 0.2
})
.to(this.blink, 0.001, {
opacity: 0,
delay: 0.2
})
.to(this.blink, 0.001, {
opacity: 1,
delay: 0.2
})
.to(this.blink, 0.001, {
opacity: 0,
delay: 0.2
})
.to(this.pupil, 0.3, {
x: 0,
y: 0
});
this.svgContainer.off('runAnimation').on('runAnimation', function() {
this.timeLine.play();
}.bind(this));
this.svgContainer.off('stopAnimation').on('stopAnimation', function() {
this.timeLine.reverse();
}.bind(this));
};
var AnimateWeb = function($main) {
this.svgContainer = $main.find("#web-skill");
if (this.svgContainer.length === 0) {
return;
}
this.mobile = this.svgContainer.find('#mobile');
this.mobile2 = this.svgContainer.find('#mobile2');
this.desktop = this.svgContainer.find('#desktop');
this.timeLine = new TimelineMax({
yoyo: true,
paused: true,
onComplete: function() {
this.restart();
}
})
.to(this.desktop, 0.5, {
x: 13,
delay: 1
})
.to([this.mobile, this.mobile2], 0.5, {
x: -6,
delay: 1
}, 0)
.to(this.mobile2, 0, {
opacity: 1
})
.to([this.mobile, this.mobile2, this.desktop], 0.5, {
x: 0
})
.to(this.desktop, 0.5, {
x: 13,
delay: 1
})
.to([this.mobile, this.mobile2], 0.5, {
x: -6,
delay: 1
}, 2.0)
.to(this.mobile2, 0, {
opacity: 0
})
.to([this.mobile, this.mobile2, this.desktop], 0.5, {
x: 0
});
this.svgContainer.off('runAnimation').on('runAnimation', function() {
this.timeLine.play();
}.bind(this));
this.svgContainer.off('stopAnimation').on('stopAnimation', function() {
this.timeLine.reverse();
}.bind(this));
};
var AnimateBrand = function($main) {
this.svgContainer = $main.find("#brand-skill");
if (this.svgContainer.length === 0) {
return;
}
this.pen = this.svgContainer.find('#pen');
this.penHeight = 40;
this.penWidth = 82;
this.heart = this.svgContainer.find('#heart');
this.heartPath = this.heart.find('#heartpath')[0];
if (!this.heartPath) {
return;
}
this.pathobj = {
length: 0,
pathLength: this.heartPath.getTotalLength()
}
this.pen.css('transform-origin', '23px 100px 0');
this.timeLine = new TimelineMax({
yoyo: true,
paused: true
})
.to(this.pen, 0.4, {
rotation: 45
})
.to(this.pathobj, 1, {
length: this.pathobj.pathLength,
ease: Linear.easeNone,
onUpdateScope: this,
onUpdate: function() {
this.heartPath.style.strokeDasharray = [this.pathobj.length, this.pathobj.pathLength].join(' ');
var coords = this.heartPath.getPointAtLength(this.pathobj.length);
coords.y = coords.y - 102;
coords.x = coords.x - 22;
this.pen.css('transform', 'translate(' + coords.x + 'px, ' + coords.y + 'px) rotate(45deg)');
}
});
this.svgContainer.off('runAnimation').on('runAnimation', function() {
this.timeLine.play();
}.bind(this));
this.svgContainer.off('stopAnimation').on('stopAnimation', function() {
this.timeLine.reverse();
}.bind(this));
};
function setSkillAnimation($main) {
new AnimateInteractive($main);
new AnimateHTML($main);
new AnimateEvents($main);
new AnimateSDK($main);
new AnimateSocial($main);
new AnimateUX($main);
new AnimateWeb($main);
var is_firefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
if(!is_firefox){
//firefox 31 bug - https://bugzilla.mozilla.org/show_bug.cgi?id=1044355
new AnimateBrand($main);
}
$main.find("#skills li").on('mouseenter touchstart', function(e) {
if(e.type == 'touchstart'){
$("#skills li").find('svg').trigger('stopAnimation');
}
$(this).find('svg').trigger('runAnimation');
}).on('mouseleave', function() {
$(this).find('svg').trigger('stopAnimation');
});
}
setSkillAnimation($('body'));

代码中并没有太复杂的方法,大部分是条用jQuery来改变CSS3属性,比如通过改变旋转角度等让图标产生翻转、旋转、移动的动画特效。


大家可以下载完整的源码来学习SVG的相关特性和HTML5动画特效。


最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台