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

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

一、应用介绍

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

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>


相关文章
|
20天前
|
移动开发 小程序 前端开发
几千怎么部署搭建校园服务平台,校园圈子论坛系统小程序搭建,校园系统源码,多种功能一体的综合性校园平台
校园圈子论坛是一款集交友、二手市场、聊天等多功能于一体的校园社交平台,支持App、小程序和H5三端交付。学生可处理闲置物品、结识新朋友,通过算法匹配兴趣相投的用户。平台提供分享邀请机制,支持自动绑定推荐关系,并设有奖励机制。开发过程中需注重数据安全与系统稳定性,确保功能兼容及性能优化。
61 5
|
21天前
|
移动开发 小程序 前端开发
使用php开发圈子系统特点,如何获取圈子系统源码,社交圈子运营以及圈子系统的功能特点,圈子系统,允许二开,免费源码,APP 小程序 H5
开发一个圈子系统(也称为社交网络或社群系统)可以是一个复杂但非常有趣的项目。以下是一些关键特点和步骤,帮助你理解如何开发、获取源码以及运营一个圈子系统。
98 3
|
24天前
|
小程序 安全 搜索推荐
陪玩小程序的搭建解析与功能需求
陪玩小程序是为玩家提供专业陪玩服务的应用,嵌入社交或游戏平台,具备智能匹配、实时聊天、预约服务等功能,支持便捷高效的游戏体验。源码交付时需提供详细文档、技术支持及定制开发服务,确保客户能顺利维护和升级。选择陪玩小程序时应关注功能需求、用户体验、安全性和成本效益,以确保最佳使用效果。
38 0
|
21天前
|
小程序 安全 网络安全
清晰易懂!陪玩系统源码搭建的核心功能,陪玩小程序、陪玩app的搭建步骤!
陪玩系统源码包含多种约单方式、实时语音互动、直播间与聊天室、大神申请与抢单、动态互动与社交及在线支付与评价等核心功能。搭建步骤包括环境准备、源码上传与解压、数据库配置、域名与SSL证书绑定、伪静态配置及后台管理。注意事项涵盖源码安全性、二次开发、合规性和技术支持。确保平台安全、合规并提供良好用户体验是关键。
|
2月前
|
小程序 数据挖掘 UED
开发1个上门家政小程序APP系统,都有哪些功能?
在快节奏的现代生活中,家政服务已成为许多家庭的必需品。针对传统家政服务存在的问题,如服务质量不稳定、价格不透明等,我们历时两年开发了一套全新的上门家政系统。该系统通过完善信用体系、提供奖励机制、优化复购体验、多渠道推广和多样化盈利模式,解决了私单、复购、推广和盈利四大痛点,全面提升了服务质量和用户体验,旨在成为家政行业的领导者。
|
3月前
|
存储 自然语言处理 小程序
微信小程序多语言切换神器:简繁体切换功能完全指南
随着全球化的发展,支持多种语言的应用程序愈发重要。本文介绍了如何在微信小程序中实现简体与繁体字体之间的切换功能,以满足不同地区用户的需求。通过创建utils文件夹并编写相应的转换函数,开发者可以方便地实现语言切换,从而提升用户体验。文章中还附带了示例代码和效果图,帮助读者更好地理解和应用这一功能。
135 0
微信小程序多语言切换神器:简繁体切换功能完全指南
|
3月前
|
开发框架 小程序 JavaScript
小程序代码丢失!反编译找回
小程序源代码的容易获取问题确实存在一些潜在的安全隐患。然而,现在的小程序开发框架采用像 Babel 这样的打包工具,将 JavaScript 逻辑代码混合在一个文件中并进行转编译,使其变得难以理解。
69 0
小程序代码丢失!反编译找回
|
3月前
|
小程序 Linux Python
查找首字母与Python相关的的英文词汇小程序的续篇---进一步功能完善
查找首字母与Python相关的的英文词汇小程序的续篇---进一步功能完善
34 1
|
4月前
|
小程序 JavaScript Go
代码总有一个是你想要的分享63个微信小程序源
分享63个微信小程序源代码,包括电商系统、同城拼车、博客等多种应用,涵盖C#、Node.js、Golang等技术栈。每个项目附带源码和示例,适合初学者和开发者参考学习。提取码:8888,代码效果参考:http://www.603393.com/sitemap.xml。
123 2
|
5月前
|
Web App开发 缓存 小程序
【Azure API 管理】从微信小程序访问APIM出现200空响应的问题中发现CORS的属性[terminate-unmatched-request]功能
【Azure API 管理】从微信小程序访问APIM出现200空响应的问题中发现CORS的属性[terminate-unmatched-request]功能