动画效果-饿了么购物车动效


饿了么购物车动画实现

NO PICTURE SAY JB

源码自取

演示网址,可能是其他练习🤣

前言

好久好久没有更新博客了,最近工作确实有点忙,最近的项目总结也一直拖着没写,但是懒才是原罪😔,年轻人要努力啊😤

实现技术

  1. 移动端布局: flex + rem + flexible(移动端貌似用视口单位更好) + SVG
  2. 前端框架: VUE(使用了VUE脚手架,版本3+)
  3. 第三方插件:better-scroll

实现过程

基本结构的搭建

开发是以宽750px的屏幕为基准的,使用rem是为了适应不同尺寸的屏幕。flexible的原理是将屏幕直接分为10等份,以750的屏幕来说,每一份是75px,然后设置1rem === 75px就可以了。

引入flexible

需要注意的地方

当屏幕宽度小于750的时候强制指定根元素的: font-size: 75px去覆盖flexible的值,rem(root rm)是根据根元素的font-size大小确定的。

好用的vscode插件

px to rem & rpx:自动帮你把px转化为rem,前提是需要设置好参考值:1rem对应多少px

在项目中使用SVG

  1. 安装插件: npm install vue-svg-loader --save
  2. 在根目录下新建vue.config.js
const path = require('path')

function resolve(dir) {
  return path.join(__dirname, './', dir)
}

module.exports = {
  chainWebpack: config => {
    config.plugin('define').tap(args => {
      const argv = process.argv
      const icourt = argv[argv.indexOf('--icourt-mode') + 1]

      args[0]['process.env'].MODE = `"${icourt}"`

      return args
    })
    // svg rule loader
    const svgRule = config.module.rule('svg') // 找到svg-loader
    svgRule.uses.clear() // 清除已有的loader, 如果不这样做会添加在此loader之后
    svgRule.exclude.add(/node_modules/) // 正则匹配排除node_modules目录
    svgRule // 添加svg新的loader处理
      .test(/\.svg$/)
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({
        symbolId: 'icon-[name]',
      })

    // 修改images loader 添加svg处理
    const imagesRule = config.module.rule('images')
    imagesRule.exclude.add(resolve('src/icons')) //存储svg文件的根目录
    config.module
      .rule('images')
      .test(/\.(png|jpe?g|gif|svg)(\?.*)?$/)
  },
  configureWebpack: {
    devServer: {
      open: true,
      // https: true,
      proxy: {
        '/user': {
          target: 'https://devadminschool.icourt.cc',
        },
        '/live': {
          target: 'https://devadminschool.icourt.cc',
        },
      },
    },
  },
}
  1. 新建 svgIcon.vue组件
<template>
  <svg :class="svgClass" aria-hidden="true">
    <use :xlink:href="iconName"/>
  </svg>
</template>

<script>
export default {
  name: "svgIcon",
  props: {
    iconClass: {
      type: String,
      required: true,
    },
    className: {
      type: String,
      default: '',
    },
  },
  computed: {
    iconName() {
      return `#icon-${this.iconClass}`
    },
    svgClass() {
      if (this.className) {
        return 'svg-icon ' + this.className
      } else {
        return 'svg-icon'
      }
    },
  }
}
</script>

<style scoped>
.svg-icon {
  width: 1em;
  height: 1em;
  fill: currentColor;
  overflow: hidden;
}
</style>
  1. src目录下新建icons文件夹

这个文件夹跟第二步中的对应,如下图

  1. icons中新建svg文件夹(存储svg文件)和 index.js

    //index.js 内容
    import Vue from 'vue'
    import SvgIcon from '@/components/svgIcon' // svg组件
    
    // 注册到全局
    Vue.component('svg-icon', SvgIcon)
    
    const requireAll = requireContext => requireContext.keys().map(requireContext)
    const req = require.context('./svg', false, /\.svg$/)
    requireAll(req)
  2. 在项目中使用

功能点实现

滑动效果实现

滑动效果要考虑到左侧与右侧的联动,点击左侧,右侧需要调到相应位置,滑动右侧,左侧也要相应变化。

对于右侧:获取每一个大类(例如:湘菜、川菜)距离顶部的距离(offsetTop),然后监听scroll事件,将事件的y值与每一项的offsetTop对比来联动左侧

对于左侧: 点击的哪一个直接将右侧的dom元素的实例上滑-offsetTop

遇到的坑

使用BScroll的时候,发现滑动不了:

加入购物车效果实现

当点击+的时候,需要实现购物车跳入的动画,通过 vue 过渡实现

补充:

  1. getBoundingClientRect()是DOM元素到浏览器的可视距离

  1. 通过监听 transitionend、animationend进行相应状态变化

努力哦,少年!!!


文章作者: 木叶勇
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 木叶勇 !
  目录