序
520: 网络情人节是信息时代的爱情节日, 定于每年的 5 月 20 日和 5 月 21 日. 该节日源于歌手范晓萱的《数字恋爱》中 "520" 被喻成 "我爱你" , 以及音乐人吴玉龙的网络歌曲中 "我爱你" 与 "网络情人" 的紧密联系. 后来,"521" 也逐渐被情侣们赋予了 "我愿意, 我爱你" 的意思."网络情人节" 又被称为 "结婚吉日","表白日","撒娇日","求爱节".
那么, 作为程序员, 如何通过专业技能向自己的另一半表达爱意呢?
效果
520.gif
技术栈
技术栈 [及环境] | 版本 |
---|---|
vue-cli | 3.x |
vue | 2.x |
element-ui | 2.x |
sass | sCSS |
实现
分析
不难看出, 页面分为三个部分: 背景, 旋转导航花瓣及弹框;
6 个花瓣对应对个导航栏, 每个导航栏颜色及打开弹窗的背景色相同;
弹窗共用, 动态展示不同的弹窗内容区域及改变标题即可;
动画: 这里动画均有原生 css3 的 @keyframes 完成, 在 animation 里调用.
功能点
导航切换
旋转动画
走马灯(相册轮播)
标签切换(足迹中标签)
table 表格(说说)
时间轴(时刻)
弹幕效果(留言)
缩放效果(中心图片点击缩放)
项目一览
项目结构如下:
├── README.md // 项目说明
├── babel.config // babel 配置
├── package.JSON // 包配置
├── public
│ ├── favicon.ico // 放在 title 前的页面 logo
│ └── index.html // 主页面
├── src
│ ├── assets
│ │ ├── CSS // 自定义配置 CSS
│ │ └── love // 图片资源
│ ├── love
│ │ └── love.vue // 520 主题组件
│ ├── App.vue
│ ├── router.JS // 路由
│ └── main.JS // 主配置
└── vue.config.JS // vue 自定义配置
其中, 项目重点在 love.vue 组件中
功能点简述
1. 导航及切换
旋转菜单切换. gif
首先, 6 个导航位, 文字不同, icon 不同;
其次, 点击菜单需要有旋转效果, 菜单旋转缩小, 弹框旋转放大展示;
最后, 判断 / 写入弹框卡片 (下简称卡片) 背景色.
- // template 部分
- <div class="leafs">
- <div v-for="(item, index) in menuList"
- :key="item.name"
- class="leaf"
- @click="runCircle(item.name, index)"
- :class="`leaf${index+1}`">
- <img :src="item.url" alt="">
- <span class="nameSpain"><i :class="item.icon"></i> {{ item.name }}</span>
- </div>
- <!-- 小心心 -->
- <div class="heart"
- :class="{heartScale: heartScaleSign}"
- @click="heartScale">
- <img src="../assets/love/heart.png" alt="">
- </div>
- </div>
- // script 部分
- data() {
- return {
- show: false,
- runCircleSign: false, // 旋转变小
- heartScaleSign: false, // 心 变大缩小
- cardMiss: false, // 卡片动画消失
- showCard: false, // 卡片显示状态
- cardName: '', // 卡片 title
- cardChange: -1, // 切换卡片
- cardGround: '', // 卡片背景色
- menuList: [
- {
- url: require('../assets/love/leaf1.png'),
- icon: 'el-icon-picture-outline',
- name: '相册'
- },
- {
- url: require('../assets/love/leaf2.png'),
- icon: 'el-icon-location',
- name: '足迹'
- },
- {
- url: require('../assets/love/leaf3.png'),
- icon: 'el-icon-edit',
- name: '说说'
- },
- {
- url: require('../assets/love/leaf4.png'),
- icon: 'el-icon-date',
- name: '时刻'
- },
- {
- url: require('../assets/love/leaf5.png'),
- icon: 'el-icon-news',
- name: '留言'
- },
- {
- url: require('../assets/love/leaf6.png'),
- icon: 'el-icon-printer',
- name: '影集'
- }
- ],
- cardType: 0,
- menuIndex: -1,
- activeName: 'first', // 当前标签
- }
- },
- methods: {
- // 菜单缩放
- runCircle (name, index) {
- let _this = this;
- // 缩放
- this.runCircleSign = ! this.runCircleSign;
- this.menuIndex = index;
- // 赋值名称
- this.cardName = name;
- // 显示卡片
- this.showCard = true;
- // 卡片颜色
- switch (index) {
- case 0:
- _this.cardGround = 'rgba(129,15,175,0.4)';
- _this.cardType = 0;
- break;
- case 1:
- _this.cardGround = 'rgba(12,136,145,0.6)';
- _this.cardType = 1;
- break;
- case 2:
- _this.cardGround = 'rgba(255,235,45,0.6)';
- _this.cardType = 2;
- break;
- case 3:
- _this.cardGround = 'rgba(196,0,83,0.6)';
- _this.cardType = 3;
- break;
- case 4:
- _this.cardGround = 'rgba(87,174,157,0.6)';
- _this.cardType = 4;
- break;
- case 5:
- _this.cardGround = 'rgba(255,125,0,0.6)';
- _this.cardType = 5;
- break;
- }
- },
- // 心 缩放
- heartScale () {
- this.heartScaleSign = ! this.heartScaleSign;
- },
- // 消失卡片 && 菜单复原
- backSign () {
- let _this = this;
- _this.cardMiss = true;
- _this.runCircleSign = ! _this.runCircleSign;
- setTimeout(() => {
- _this.showCard = false;
- _this.cardMiss = false;
- }, 3000)
- },
- },
2. 弹幕效果
弹幕效果. gif
1. 输入内容;
2. 循环展示;
3. 随即高度及标签颜色;
4. 利用本地存储持久化;
5. 动画漂移效果.
- // template
- <div class="haveWords">
- <!-- 展示内容 -->
- <div class="cont">
- <el-tag v-for="el in ku"
- :key="el.id"
- class="fly"
- :type="el.type"
- :style="{top:el.top +'px'}"
- >
- {{ el.msg }}
- </el-tag>
- </div>
- <!-- 输入内容 -->
- <div class="dealBox">
- <el-input
- type="textarea"
- :autosize="{ minRows: 2, maxRows: 5}"
- placeholder="请输入留言"
- v-model.trim="msg"
- size="small">
- </el-input>
- <el-button type="primary" size="small" @click="sendData">Biu~</el-button>
- </div>
- </div>
- // script
- data() {
- return {
- msg: null, // 缓存
- ku: JSON.parse(localStorage.kuArr), // 存取数据
- msgKu: []
- }
- },
- methods: {
- // 弹幕
- sendData () {
- // 5 中标签模式
- let typeArr = ['','success','info','warning','danger'];
- let localArr = this.ku;
- // 判空 不为空则继续 为空则提示输入
- if(this.msg !== '' && this.msg !== null) {
- let num1 = Math.random() * 500;
- let num2 = Math.random() * 5;
- let arrMark = Math.floor(num2);
- let top = Math.floor(num1);
- let obj = {msg:this.msg,top:top,type:typeArr[arrMark]};
- localArr.push(obj);
- localStorage.kuArr = JSON.stringify(localArr);
- this.msg = "";
- } else {
- this.$message.warning('要先输入哦~');
- }
- },
- },
别的功能点基本上都是 element-ui 中组件自带或基于组件开发的, 熟悉 element-ui 的小伙伴应该极为熟悉. 有感兴趣的朋友可自行去 element-ui 官网学习. element 飞机票
后
有对本 demo 感兴趣的或者想要作者源码的可以关注公众号流眸, 回复 "520 源码" 拿到代码哦~
公众号二维码. jpg
同时, 欢迎做客我的博客 Lomo 朱幸民.
来源: http://www.jianshu.com/p/1fcbc2920cc5