因为项目需要,别人想让我给他写一个个人博客,并且给了我一个其他人的网页,可以点此查看。有的同学可能说了,第三方博客框架这么多,为什么还要去手写的,你说这个有可能是没有看到打开这个博客。
样式介绍
给大家看一下这个网页的大体样式。
这个界面可以说是非常漂亮,整体也是一个响应式布局,总体来说还算不错。但是抛开页面设计,这个网站有一个致命的缺点,就是没有做懒加载,这么多页面其实就是一个HTML文件,所有的资源图片以及文字信息等全部是一次性加载,所以你想打开这个界面还是比较困难的,需要等待一些时间。
我们这次只看设计。其实用Vue的朋友们应该都听过element-ui
这个组件库,它里面有一个抽屉组件可以用。其实用这种现成的组件的局限性大家都很清楚,虽然说开发很快,但是定制化有很多限制,向上面GIF图中的效果他就不能很好的实现。于是本着学习的态度我们来实现一下这个样式。
实现方法
话不多说,我们先来看一下实现效果
我们大致实现了想要实现的效果:
- 点击不同标签页出现相应界面
- 切换动画
- 点击蒙版收回顶层标签页
切换动画
动画的实现方法有很多,在CSS里面写动画的话我比较常用keyframes,但是在这里我是用js来控制动画,没有使用css动画属性。js实现动画的话大家思考一下连环画的生成原理,其实就是在很短的事件里面对图片的频繁移动,只要移动速度合适,我们的眼睛就会认为我们看到了一个移动的物体。
我js实现动画的原理和此类似,设定一个延时与起始位置,让他在规定时间内按照liner均匀移动,当然你也可以不使用liner,比如说X2,这些也都是可以的。
关于实现方法,我是写了一个animation类,这个类包括延时、函数(liner或者其他渐变函数)、completed等,可以很好地进行动画生成与控制。下面来看一下这段代码
class Animator {
// 构造函数
constructor() {
this.durationTime = 0;
this.easingFn = k => k;
this.eventHandlers = new Map();
}
// 动画移动速度所用的函数
easing(fn) {
if (typeof fn !== "function") {
throw new Error("Easing must be a function, such as k => k");
}
this.easingFn = fn;
return this;
}
// 动画时间
duration(time) {
if (typeof time !== "number") {
throw new Error("Duration must be a number");
}
this.durationTime = time;
return this;
}
// 响应函数
on(type, handler) {
if (typeof handler !== "function") {
throw new Error("Handler must be a function");
}
this.eventHandlers.set(type, handler);
return this;
}
// 动画生成
animate() {
const duration = this.durationTime;
const easing = this.easingFn;
const update = this.eventHandlers.get("update") || (t => t);
const complete = this.eventHandlers.get("complete") || (() => {});
let timer = null;
const startTime = +new Date();
function step() {
const percent = Math.min(1, (+new Date() - startTime) / duration);
if (percent < 1) {
update(easing(percent));
timer = requestAnimationFrame(step);
} else {
cancelAnimationFrame(timer);
update(easing(1));
complete();
}
}
timer = requestAnimationFrame(step);
}
}
/*
* 这里是专门写了一个产生动画的函数
* 传参: start:Number, step:Number, el:object(元素对象)
* 传入这些参数之后就可以产生相应的动画效果
*/
var move = function(start, step, el) {
new Animator()
.duration(200)
.easing(k => k)
.on("update", t => {
el.style.right = String(start + t * step) + "%";
})
.animate();
};
网页布局
其实像这种抽屉式的网页布局大家应该都不陌生,大概就是设置position
为absolute
,然后再使用left
或者right
属性进行布局,我在文章下面会给出全部代码的下载链接,大家如果感兴趣可以下载来看一下。
点击逻辑
通过我前面的介绍,大家应该是可以知道这个demo是可以通过按钮点击触发,也是可以通过点击蒙版来触发的,当我的鼠标移到蒙版的时候鼠标会改变一个样式,这个只要设置一个属性就可以啦
.overlay {
cursor: url("你的图标url"), pointer;
}
具体的逻辑大家可以参照这个思维导图
其实当时这个逻辑搞了比较长时间,大家应该可以想到实现多个标签页的点击应该是使用栈来实现,始终把显示出来的抽屉页放在最顶层,这样也方便我们进行后续操作。
网页源码
需要源码的朋友可以点此下载?
小结
在刚开始学web前端开发的时候,看到一些特别的网站觉得很炫酷,当时的第一想法是看看GitHub上有没有现成的组件库可以给我用,所以也造就了我原生css学的不是很扎实。但是到现在来讲,随着工作的需要,为了有更好的突破还是得努力学习原生web。一些框架和组件都是基于原生的,只有这些学扎实了之后才能更好地认识和使用这些现成的轮子。