因为项目需要,别人想让我给他写一个个人博客,并且给了我一个其他人的网页,可以点此查看。有的同学可能说了,第三方博客框架这么多,为什么还要去手写的,你说这个有可能是没有看到打开这个博客。
样式介绍
给大家看一下这个网页的大体样式。
这个界面可以说是非常漂亮,整体也是一个响应式布局,总体来说还算不错。但是抛开页面设计,这个网站有一个致命的缺点,就是没有做懒加载,这么多页面其实就是一个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。一些框架和组件都是基于原生的,只有这些学扎实了之后才能更好地认识和使用这些现成的轮子。