来接私活吧?小程序接私活必备功能-婚恋交友【附完整代码】

简介: 来接私活吧?小程序接私活必备功能-婚恋交友【附完整代码】

一、应用介绍

这次要分享的小程序功能为好友匹配动画界面,这是一款以交友相亲为背景的恋爱主题样式组件。

css样式JS原生语法打造,支持多端的开发,小程序、H5、APP均能丝滑享受。


二、效果展示

image.gif


三、技术与难点

3.1 基本开发环境

  • 开发框架:uniapp
  • 代码语法:vue 2htmlcss3


3.2 开发要点

  • (1)头像图片的生成
  • 先引入<image>标签,配置好相应的图片路径
   <image class="dot" src="randomImg"  style="width: 92px;height: 92px;border-radius: 50px;"></image>`
  -   再通过CSS样式将其变成圆形
   -webkit-border-radius: 50%;
   -moz-border-radius: 50%;
   border-radius: 50%;


  • (2)CSS动画的引入对于网页元素的动画效果我们使用CSS 3 动画,不太熟悉的小伙伴可以直接查看文档进行学习:CSS动画教程
  • 先声明一个放缩动画变量
@keyframes 动画变量名(taoren) {
  0% {
    -webkit-transform:scale(0) translateX(0);
    transform:scale(0) translateX(0);
    opacity:.6
  }
  5% {
    -webkit-transform:scale(1) translateX(0) translateY(-80%);
    transform:scale(1) translateX(0) translateY(-80%);
    opacity:.8
  }
  20% {
    opacity:1
  }
  30% {
    opacity:.2
  }
  32% {
    opacity:0;
    visibility:hidden
  }
  50% {
    -webkit-transform:scale(1.9) translateX(-40px) translateY(-340%);
    transform:scale(1.9) translateX(-40px) translateY(-340%)
  }
  100% {
    -webkit-transform:translateX(-100px);
    transform:translateX(-100px)
  }
}
- 将动画变量绑定到相应的元素样式中
.相应原始的Class名称 {
  animation:taoren
}


(3)JS循环逻辑的控制

在元素和动画都具备的基础之上,接下来进行更重要的操作:将元素所设置的动画按照特定的规则进行重复播放。

  • JS中要实现重复播放的逻辑,通常的做法是使用setInterval方法
      this.interval = setInterval((function() {
        // 动画逻辑
        }
      ), this.intervalTime)


四、完整源码

代码基于vue 2语法编写,拷贝出来需保存为.vue文件。该示例代码中,包括三大模块:<script>,<template>,<style>,三大模块的作用分别是:控制元素逻辑和数据绑定,编写组织页面元素的渲染,控制和渲染元素的样式

<template>
  <view class="center">
    <view class="container">
      <image class="dot" src="randomImg"  style="width: 92px;height: 92px;border-radius: 50px;"></image>
      <view class="pulse"></view>
      <view class="pulse1"></view>
      <view class="prize-flying" >
        <view v-for="(item,index) in flyLeftList" class="fly-prize fly-left" 
        :style="{ 'background': 'url('+ item.img +')', '-webkit-animation-duration': flySpeed + 's','animation-duration': flySpeed + 's' }"></view>
        <view v-for="(item,index) in flyCenterList" class="fly-prize fly-center"
        :style="{ 'background': 'url('+ item.img +')', '-webkit-animation-duration': flySpeed + 's','animation-duration': flySpeed + 's' }"></view>
        <view v-for="(item,index) in flyRightList" class="fly-prize fly-right"
        :style="{ 'background': 'url('+ item.img +')', '-webkit-animation-duration': flySpeed + 's','animation-duration': flySpeed + 's' }"></view>
      </view>
    </view>
    <view class="flex justify-center items-center match-button" @click="showMan">
      <view class="match-btn">
        心动匹配
      </view>
    </view>
    </view>
</template>
<script>
  import utils from '@/utils/utils'
  export default {
    components: {utils},
    data() {
      return {
        show:false,
        randomImg:'/static/imgs/mm1.jpg',
        flyLeftList: [],
        flyCenterList: [],
        flyRightList: [],
        userList:[{img:'/static/imgs/mm1.jpg'},{img:'/static/imgs/mm2.jpg'},{img:'/static/imgs/mm3.jpg'}],
        flySpeed: 25,
        indexRecord: 0,
        intervalTime: 2.5,
        interval: null,
      };
    },
    // 从后台进入前台显示
    onShow() {
      this.flyLeftList=[];
      this.flyCenterList=[];
      this.flyRightList=[];
      this.refreshUser();
    },
    // 从前台进入后台
    onHide() {
      this.flyLeftList=[];
      this.flyCenterList=[];
      this.flyRightList=[];
      clearInterval(this.interval);
    },
    methods:{
      showMan(){
        console.log('========')
        this.show =true
      },
      refreshUser(){
        this.flyInterval();
      },
      flyInterval() {
        if(this.interval != null){
          clearInterval(this.interval);
        }
        var t = this;
        this.pushFlyList(),
        this.interval = setInterval((function() {
          t.pushFlyList()
        }
        ), 1e3 * this.intervalTime)
      },
      pushFlyList() {
        var t = 0;
        while (t < 3) {
          this.indexRecord == this.userList.length - 1 ? this.indexRecord = 0 : this.indexRecord++;
          var a = this.userList[this.indexRecord];
            switch (t) {
              case 0:
                this.flyLeftList.push(a);
                break;
              case 1:
                this.flyCenterList.push(a);
                break;
              case 2:
                this.flyRightList.push(a);
                break
            }
          t++ 
        }
      },
    }
  }
</script>
<style lang="scss">
page{
  height: 100%;
  background: url('~@/static/imgs/home/bg.png');
}
.match-button{
  background-image: linear-gradient(to top, #c471f5 0%, #fa71cd 100%);
  color: #ffff;
  border-radius: 100rpx;
  padding: 20rpx;
}
.center {
  height: 100%;
  flex: auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  //background-color: red;
}
@keyframes warn {
  0% {
    transform: scale(0.3);
    -webkit-transform: scale(0.3);
    opacity: 0.0;
  }
  25% {
    transform: scale(0.3);
    -webkit-transform: scale(0.3);
    opacity: 0.1;
  }
  50% {
    transform: scale(0.5);
    -webkit-transform: scale(0.5);
    opacity: 0.3;
  }
  75% {
    transform: scale(0.8);
    -webkit-transform: scale(0.8);
    opacity: 0.5;
  }
  100% {
    transform: scale(1);
    -webkit-transform: scale(1);
    opacity: 0.0;
  }
}
@keyframes warn1 {
  0% {
    transform: scale(0.3);
    -webkit-transform: scale(0.3);
    opacity: 0.0;
  }
  25% {
    transform: scale(0.3);
    -webkit-transform: scale(0.3);
    opacity: 0.1;
  }
  50% {
    transform: scale(0.3);
    -webkit-transform: scale(0.3);
    opacity: 0.3;
  }
  75% {
    transform: scale(0.5);
    -webkit-transform: scale(0.5);
    opacity: 0.5;
  }
  100% {
    transform: scale(0.8);
    -webkit-transform: scale(0.8);
    opacity: 0.0;
  }
}
.container {
  position: relative;
  width: 96px;
  height: 96px;
  /*border: 1px solid #000; hovertree.com */
}
/* 保持大小不变的小圆圈 何问起 */
.dot {
  position: absolute;
  width: 92px;
  height: 92px;
  //left: -2.5px;
    //top: -2.5px;
  -webkit-border-radius: 50%;
  -moz-border-radius: 50%;
  //border: 2px solid red;
  border-radius: 50%;
  z-index: 2;
  animation: msClock 1.8s linear infinite; 
}
@keyframes msClock{ 
  0%,90%,100%{ transform: rotate(0) scale(1);}
  20%,40%{ transform: rotate(-15deg) scale(1.1);}
  30%,50%{ transform: rotate(15deg) scale(1.1);}
}
/* 产生动画(向外扩散变大)的圆圈  */
.pulse {
  position: absolute;
  width: 320px;
  height: 320px;
    left: -120px;
    top: -120px;
  border: 6px solid $dating-color-primary;
  -webkit-border-radius: 50%;
  -moz-border-radius: 50%;
  border-radius: 50%;
  z-index: 1;
  opacity: 0;
  -webkit-animation: warn 2s ease-out;
  -moz-animation: warn 2s ease-out;
  animation: warn 2s ease-out;
  -webkit-animation-iteration-count: infinite;
  -moz-animation-iteration-count: infinite;
  animation-iteration-count: infinite;
  box-shadow: 1px 1px 30px $dating-color-primary;
}
.pulse1 {
  position: absolute;
  width: 320px;
  height: 320px;
    left: -120px;
    top: -120px;
  border: 6px solid $dating-color-primary;
  -webkit-border-radius: 50%;
  -moz-border-radius: 50%;
  border-radius: 50%;
  z-index: 1;
  opacity: 0;
  -webkit-animation: warn1 2s ease-out;
  -moz-animation: warn1 2s ease-out;
  animation: warn1 2s ease-out;
  -webkit-animation-iteration-count: infinite;
  -moz-animation-iteration-count: infinite;
  animation-iteration-count: infinite;
  box-shadow: 1px 1px 30px $dating-color-primary;
}
a{color:blue;text-decoration:none;}
.match-button{
  position: fixed;
  bottom: calc(var(--status-bar-height) + 120rpx);
}
.prize-flying{
  z-index:99;
  width:100px;
  position:absolute;
  bottom:50%;
  left:50%;
  -webkit-transform:translateX(-50%);
  transform:translateX(-50%)
}
.prize-flying .fly-prize {
  text-align:center;
  position:absolute;
  top:100%;
  opacity:0;
  width:39px;
  height:39px;
  background-repeat:no-repeat!important;
  background-size:100% 100%!important;
  border-radius:50%;
  background:#fff;
  padding:7px
}
.showCard {
  z-index:10;
  animation:warn
}
.prize-flying .fly-left {
  left:0;
  z-index:5;
  animation:flyleft-data-v-1a236634
}
.prize-flying .fly-center {
  left:30px;
  z-index:3;
  animation:flycenter-data-v-1a236634
}
.prize-flying .fly-right {
  right:0;
  z-index:5;
  animation:flyright-data-v-1a236634
}
@keyframes flyleft-data-v-1a236634 {
  0% {
    -webkit-transform:scale(0) translateX(0);
    transform:scale(0) translateX(0);
    opacity:.6
  }
  5% {
    -webkit-transform:scale(1) translateX(0) translateY(-80%);
    transform:scale(1) translateX(0) translateY(-80%);
    opacity:.8
  }
  20% {
    opacity:1
  }
  30% {
    opacity:.2
  }
  32% {
    opacity:0;
    visibility:hidden
  }
  50% {
    -webkit-transform:scale(1.9) translateX(-40px) translateY(-340%);
    transform:scale(1.9) translateX(-40px) translateY(-340%)
  }
  100% {
    -webkit-transform:translateX(-100px);
    transform:translateX(-100px)
  }
}
@keyframes flycenter-data-v-1a236634 {
  0% {
    -webkit-transform:scale(0) translateX(0);
    transform:scale(0) translateX(0);
    opacity:.6
  }
  5% {
    -webkit-transform:scale(1) translateX(0) translateY(-80%);
    transform:scale(1) translateX(0) translateY(-80%);
    opacity:.8
  }
  20% {
    opacity:1
  }
  30% {
    opacity:.2
  }
  32% {
    opacity:0;
    visibility:hidden
  }
  34% {
    opacity:0
  }
  50% {
    -webkit-transform:scale(1.9) translateX(0) translateY(-340%);
    transform:scale(1.9) translateX(0) translateY(-340%)
  }
  100% {
    -webkit-transform:translateX(0);
    transform:translateX(0)
  }
}
@keyframes flyright-data-v-1a236634 {
  0% {
    -webkit-transform:scale(0) translateX(0);
    transform:scale(0) translateX(0);
    opacity:.6
  }
  5% {
    -webkit-transform:scale(1) translateX(0) translateY(-80%);
    transform:scale(1) translateX(0) translateY(-80%);
    opacity:.8
  }
  20% {
    opacity:1
  }
  30% {
    opacity:.2
  }
  32% {
    opacity:0;
    visibility:hidden
  }
  34% {
    opacity:0
  }
  50% {
    -webkit-transform:scale(1.9) translateX(40px) translateY(-340%);
    transform:scale(1.9) translateX(40px) translateY(-340%)
  }
  100% {
    -webkit-transform:translateX(100px);
    transform:translateX(100px)
  }
}
</style>


相关文章
|
6天前
|
存储 自然语言处理 小程序
微信小程序多语言切换神器:简繁体切换功能完全指南
随着全球化的发展,支持多种语言的应用程序愈发重要。本文介绍了如何在微信小程序中实现简体与繁体字体之间的切换功能,以满足不同地区用户的需求。通过创建utils文件夹并编写相应的转换函数,开发者可以方便地实现语言切换,从而提升用户体验。文章中还附带了示例代码和效果图,帮助读者更好地理解和应用这一功能。
31 0
微信小程序多语言切换神器:简繁体切换功能完全指南
|
6天前
|
开发框架 小程序 JavaScript
小程序代码丢失!反编译找回
小程序源代码的容易获取问题确实存在一些潜在的安全隐患。然而,现在的小程序开发框架采用像 Babel 这样的打包工具,将 JavaScript 逻辑代码混合在一个文件中并进行转编译,使其变得难以理解。
14 0
小程序代码丢失!反编译找回
|
18天前
|
小程序 Linux Python
查找首字母与Python相关的的英文词汇小程序的续篇---进一步功能完善
查找首字母与Python相关的的英文词汇小程序的续篇---进一步功能完善
14 1
|
5月前
|
JavaScript Java 测试技术
基于小程序的移动学习平台+springboot+vue.js附带文章和源代码说明文档ppt
基于小程序的移动学习平台+springboot+vue.js附带文章和源代码说明文档ppt
42 0
|
1月前
|
小程序 JavaScript Go
代码总有一个是你想要的分享63个微信小程序源
分享63个微信小程序源代码,包括电商系统、同城拼车、博客等多种应用,涵盖C#、Node.js、Golang等技术栈。每个项目附带源码和示例,适合初学者和开发者参考学习。提取码:8888,代码效果参考:http://www.603393.com/sitemap.xml。
47 2
|
2月前
|
Web App开发 缓存 小程序
【Azure API 管理】从微信小程序访问APIM出现200空响应的问题中发现CORS的属性[terminate-unmatched-request]功能
【Azure API 管理】从微信小程序访问APIM出现200空响应的问题中发现CORS的属性[terminate-unmatched-request]功能
|
2月前
|
小程序 前端开发 开发者
|
2月前
|
小程序 前端开发 API
Ant Design Mini 问题之在微信小程序中,由于不支持slot特性,Ant Design Mini的什么组件功能受到了限制,如何解决
Ant Design Mini 问题之在微信小程序中,由于不支持slot特性,Ant Design Mini的什么组件功能受到了限制,如何解决
|
2月前
|
小程序 前端开发 JavaScript
微信小程序实现微信支付(代码和注释很详细)
微信小程序实现微信支付(代码和注释很详细)
|
2月前
|
小程序 JavaScript 前端开发
微信小程序开发必备前置知识:基本代码构成与语法
【8月更文挑战第8天】微信小程序的基本代码构成与语法
85 0
微信小程序开发必备前置知识:基本代码构成与语法