Loading

教你用原生CSS写炫酷页面切换效果,跟第三方组件说拜拜

因为项目需要,别人想让我给他写一个个人博客,并且给了我一个其他人的网页,可以点此查看。有的同学可能说了,第三方博客框架这么多,为什么还要去手写的,你说这个有可能是没有看到打开这个博客。

样式介绍

给大家看一下这个网页的大体样式。

这个界面可以说是非常漂亮,整体也是一个响应式布局,总体来说还算不错。但是抛开页面设计,这个网站有一个致命的缺点,就是没有做懒加载,这么多页面其实就是一个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();
};

网页布局

其实像这种抽屉式的网页布局大家应该都不陌生,大概就是设置positionabsolute,然后再使用left或者right属性进行布局,我在文章下面会给出全部代码的下载链接,大家如果感兴趣可以下载来看一下。

点击逻辑

通过我前面的介绍,大家应该是可以知道这个demo是可以通过按钮点击触发,也是可以通过点击蒙版来触发的,当我的鼠标移到蒙版的时候鼠标会改变一个样式,这个只要设置一个属性就可以啦

.overlay {
  cursor: url("你的图标url"), pointer;
}

具体的逻辑大家可以参照这个思维导图

其实当时这个逻辑搞了比较长时间,大家应该可以想到实现多个标签页的点击应该是使用栈来实现,始终把显示出来的抽屉页放在最顶层,这样也方便我们进行后续操作。

网页源码

需要源码的朋友可以点此下载😜

小结

在刚开始学web前端开发的时候,看到一些特别的网站觉得很炫酷,当时的第一想法是看看GitHub上有没有现成的组件库可以给我用,所以也造就了我原生css学的不是很扎实。但是到现在来讲,随着工作的需要,为了有更好的突破还是得努力学习原生web。一些框架和组件都是基于原生的,只有这些学扎实了之后才能更好地认识和使用这些现成的轮子。

posted @ 2019-08-23 23:55  Jacob是我了  阅读(2014)  评论(4编辑  收藏  举报