新博客改造的一些有趣的技术要点
最近随着 Ghost 升级,博客主题也做了一些动效的调整,这里面有一些比较有意思的细节,可以和大家分享下。
落地页动画衔接
从首页列表点击进去,实际上是比较简单的 transition 过渡,主要是利用透明度变化和背景图片的放大缩小来完成的。
.cover,
.overlay{
content: '';
display: block;
position: absolute;
top: 0;
left: 0;
right: 0;
height: 100%;
background-color: #000;
background-position: center center;
opacity: .2;
background-size: cover;
}
.cover{
opacity: 0;
transition: opacity 1.5s, transform 2s;
transition-timing-function: cubic-bezier(0.5, 0, 0.2, 1);
background-color: transparent;
transform: scale(1.2, 1.2);
}
&.loaded {
.cover{
opacity: 1;
transform: scale(1, 1);
}
}
而列表页的反之,是 hover 后进行放大
&:hover{
.cover{
opacity: .75;
transform: scale(1.2, 1.2);
}
}
视察滚动 (Parallax Scrolling)
Parallax Scrolling是最近几年一直都非常火的的交互效果,而这次博客改版在三处用到了 parallax scrolling。分别是首页 header ,详情页 header, 个人联系方式的 footer 处。
头部 header
头部的动效是利用了 background-attachment 的属性,它可以用来表示背景图像是否固定或者随着页面的其余部分滚动。项目中我们设置了 fixed
,这样就会出现内容滚动但是背景图像依旧保持位置。
.slideshow .bg-overlay {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-position: center center;
background-repeat: no-repeat;
background-size: cover;
background-attachment: fixed; // set this value
box-shadow: 0 -2rem 3rem -2rem rgba(0, 0, 0, .45) inset, 0 -3rem 3rem -2rem rgba(0, 0, 0, .45) inset, 0 -4rem 5rem -4rem rgba(0, 0, 0, .35) inset, 0 -10rem 3rem -3rem rgba(0, 0, 0, .35) inset, 0 -15rem 3rem -3rem rgba(0, 0, 0, .35) inset, 0 -20rem 5rem -3rem rgba(0, 0, 0, .35) inset;
transition: opacity 0.6s;
-webkit-transition: opacity 0.6s;
-webkit-transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1);
transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1);
}
SNS Footer 的特效
这里是利用 JS 的 scrollTop
值太进行计算的。我们通过获取滚动条距离顶部的高度,然后再通过 设置 background-position
或者 transllateY
来进行动态更新。
$(document.body).on('scroll', function(e) {
var top = e.target.scrollTop;
var wH = window.innerHeight;
if (top > 70 && top <= wH) {
$('.overlay').css({
opacity: 0.2 + 0.8 * (top / wH),
});
$('.js-post-meta').css({
opacity: 1 - 0.8 * (top / wH),
transform: 'translateY(' + top / 3 + 'px)',
});
$('.js-post-cover').css({
backgroundPositionY: '-' + top / 4 + 'px',
});
} else if(top < 70) {
$('.js-post-cover').css({
backgroundPositionY: '0px',
});
}
var ratio = 1;
if (isMobile) {
ratio = 3;
}
if (top > (contentHeight - 700)) {
// ... code
$('.blur-circle.lg').css({
// opacity: 1 - 0.8 * (top / wH),
transform: 'translateY(' + (contentHeight - top - 700) / (2 * ratio) + 'px)',
});
}
});
SVG Filter
页面多出用到了 SVG ,除了目前所有的 ICON 用到了 svg-sprite ,这次还利用 gradient 和 filter 去实现球的模糊效果。
<svg width="120px" height="120px" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="gradient4">
<stop offset="5%" stop-color="#5573e3" />
<stop offset="95%" stop-color="#7022ed" />
</linearGradient>
<filter id="f4" x="0" y="0">
<feGaussianBlur in="SourceGraphic2" stdDeviation="2" />
</filter>
</defs>
<circle cx="50" fill="url(#gradient4)" filter="url(#f4)" cy="50" r="35"/>
</svg>
关于 feGaussianBlur 可以到官方 MDN 了解。
CSS LONG Shadow
Tag 页面放了一个 基于 less
实现的 长投影-long shadow。
.longshadow(@color: #e3e3e3, @angle: 45, @size: 10, @flag: 1, @temp: "") when (@size > 0) {
@angle360: @angle * (pi() / 180);
@x: round(@flag * cos(@angle360));
@y: round(@flag * sin(@angle360));
@shadow: ~"@{x}px @{y}px 0px @{color}";
@close: ~"@{shadow}, @{temp}";
@alltogether: ~"@{close} 0px 0px 0px @{color}";
.loop(@string, @index) when (@index < 1) {
text-shadow: @string;
}
.loop(@alltogether, @size - 1);
.longshadow(@color, @angle, @size - 1,@flag + 1, @close);
}
CodePen 演示地址