微信小程序之自定义计时器

最近想在在做的微信小程序加一个计时器功能,就是可以设置一个时间,可以开始倒计时,暂停,最终实现结果(图1,2所示),可能这个配色及样式有点糟糕毕竟css太难了 ,可以在这个基础上进行扩展,如果时间到了会弹出图片或者播放音乐等等
在这里插入图片描述

图1

在这里插入图片描述

图2

1. block.wxml编写,写出计时器大概骨架

wxml中编写出大体需要的组件,代码如下:

<!--index.wxml-->
<image class="bg" src="../../images/webp (2).webp"></image>
<view hidden="{{clockShow}}">
  <view class="slider">
      <slider min="1" max="60" show-value activeColor="#E7624F"
      backgroundColor="#666666" value="{{time}}" bindchange="slideChange"></slider>
      </view>
      <view class="task_text">
        <view class="task_title">选择一个任务</view>
        <view class="task_desc">在接下来的{{time}}分钟内,您将专注做这件事</view>
      </view>
      <view class="task_cate">
        <view wx:for="{{cateArr}}" class="cate_item" wx:key="cate" bindtap="clickCate"
        data-index="{{index}}">
          <view class="cate_icon"> <image src="../../images/{{item.icon}}.png"></image> </view>
          <view class='cate_text {{index == cateActive ? "cate_text_active" : ""}}'>{{item.text}}</view>
        </view>
        <view class="start" bindtap="start">
        开始专注
        </view>
  </view>
</view>

<view class="clock" hidden="{{!clockShow}}" style="height:{{clockHeight}}rpx">
  <view class="progress">
    <canvas canvas-id="progress_bg" class="progress_bg"></canvas>
    <canvas canvas-id="progress_active" class="progress_active"></canvas>
    <view class="progress_text">{{timeStr}}</view>
  </view>
  <view class="btns">
    <view class="okBtn" bindtap="ok" wx:if="{{okShow}}">返回</view>
    <view class="pauseBtn" bindtap="pause" wx:if="{{pauseShow}}">暂停</view>
    <view class="continueCancelBtn" wx:if="{{continueCancelShow}}">
      <view class="continueBtn" bindtap="continue">继续</view>
      <view class="cancelBtn" bindtap="cancel">放弃</view>
    </view>
  </view>
</view>

2. block.wxss编写,写出计时器大概骨架

block.wxss对wxml中的组件编写样式,实现好看背景及布局,代码如下:

.adv1{
  width: 100%;
  height: 900rpx;
  background: url('/img/ba3.png') no-repaeat 0 0;
  background-size: contain;
}
.adv-img{
  width: 100%;
  height: 900rpx;
  position: absolute;
}
.tiaoguo{
  font-size: 25rpx;
  background-color: wheat;
  border-radius: 80rpx;
  display: inline-block;
  margin-left: 10rpx;
  position: absolute;
  z-index: 999;
  right: 25rpx;
  top: 850rpx;
  padding-left: 10rpx;
  padding-right: 10rpx;
}
button{
    border-radius: 18rpx;
    width: 220rpx;
    background-color: #EECBAD;
    color: #8B5742;
    margin-top: 38rpx;
    font-size: 33rpx;
}
.text2{
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    margin-top: 23rpx;
    font-size: 28rpx;
}

.bg{
  width: 100%;
  height: 100%;
  position:fixed; 
  background-size:100% 100%;
  z-index: -1;
  filter: blur(10rpx);
}
.silder{
  width: 650rpx;
  margin: 40rpx auto;
}
.task_text{
  height: 120rpx;
  margin: 40rpx auto;
  text-align: center;
}
.task_text .task_title{
  font-size: 35rpx;
  height: 70rpx;
  line-height: 70rpx;
}
.task_text .task_desc{
  font-size: 30rpx;
  height: 50rpx;
  line-height: 50rpx;
  color: #999999;
}
.task_cate{
  width: 660rpx;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
}
.task_cate .cate_item{
  width: 220rpx;
  height: 130rpx;
  text-align: center;
  margin-bottom: 50rpx;
}
.task_cate .cate_item .cate_icon{
  height: 70rpx;
}
.task_cate .cate_item .cate_icon image{
  width: 50rpx;
  height: 50rpx;
}
.task_cate .cate_item .cate_text{
  height: 60rpx;
  line-height: 60rpx;
  font-size: 30rpx;
}
.task_cate .cate_item .cate_text_active{
  color: #e41749;
}
.start{
  width: 280rpx;
  height: 90rpx;
  line-height: 90rpx;
  text-align: center;
  margin: 40rpx auto;
  border: 2rpx solid #e41749;
  color: #e41749;
  border-radius: 20rpx;
}
.clock{
  overflow: hidden;
  background: #8ac6d1;
}
.progress{
  width: 400rpx;
  height: 400rpx;
  /* background: orange; */
  margin: 140rpx auto;
  position: relative;
}
.progress .progress_bg,.progress_active{
  position: absolute;
  left: 0;
  top: 0;
  width: 400rpx;
  height: 400rpx;
}
.progress .progress_text{
  width: 160rpx;
  height: 60rpx;
  line-height: 60rpx;
  font-size: 30rpx;
  color: #ffffff;
  text-align: center;
  position: absolute;
  left: 120rpx;
  top: 170rpx;
}
.btns .okBtn, .btns .pauseBtn, .btns .continueBtn, .btns .cancelBtn{
  width: 280rpx;
  height: 80rpx;
  line-height: 80rpx;
  text-align: center;
  color: #ffffff;
  border: 3rpx solid #ffffff;
  border-radius: 20rpx;
  margin: 0 auto 20rpx auto;
}

3. block.js编写,写出计时器大概骨架

block.js动态绑定数据,实现开始计时,以及暂停计时等功能,代码如下:

//获取util实例
const app = getApp()
const util = require('../../utils/util.js')

Page({
  data: {
    clockShow:false,
    clockHeight:0,
    time:'5',
    mTime:300000,
    timeStr:'05:00',
    rate:'',
    timer:null,
    cateArr:[
      {
        icon: 'work',
        text: '工作'
      },
      {
        icon: 'study',
        text: '学习'
      },
      {
        icon: 'think',
        text: '思考'
      },
      {
        icon: 'write',
        text: '写作'
      },
      {
        icon: 'sport',
        text: '运动'
      },
      {
        icon: 'read',
        text: '阅读'
      }
    ],
    cateActive:'0',
    okShow:false,
    pauseShow:true,
    continueCancelShow:false
  },

  onLoad: function() {
    var res = wx.getSystemInfoSync();
    var rate = 750 / res.windowWidth;
    console.log(rate);
    this.setData({
      rate:rate,
      clockHeight:rate * res.windowHeight
    })
    
  },


  
  slideChange:function(e){
    this.setData({
      time:e.detail.value
    })
  },
  clickCate:function(e){
    this.setData({
      cateActive:e.currentTarget.dataset.index
    })
  },
  start:function(){
    this.setData({
      clockShow:true,
      mTime:this.data.time*60*1000,
      timeStr:parseInt(this.data.time) >= 10 ? this.data.time+':00' : 
      '0' + this.data.time+':00'
    })
    this.drawBg();
    this.drawActivve();
  },
  drawBg:function(){
    var lineWidth = 6 / this.data.rate;//px
    var ctx = wx.createCanvasContext('progress_bg');
    ctx.setLineWidth(lineWidth);
    ctx.setStrokeStyle('#000000');
    ctx.setLineCap('round');
    ctx.beginPath();
    ctx.arc(400/this.data.rate/2,400/this.data.rate/2,400/this.data.rate/2-2*lineWidth,0,2*Math.PI,false);
    ctx.stroke();
    ctx.draw();
  },
  // 动态画圆
  drawActivve:function(){
    var _this = this;
    var timer = setInterval(function(){
      //1.5-3.5
      var angle = 1.5 + 2*(_this.data.time*60*1000 - _this.data.mTime)/
      (_this.data.time*60*1000);
      var currentTime = _this.data.mTime - 100;
      _this.setData({
        mTime:currentTime
      });
      if(angle < 3.5){
        if(currentTime % 1000 == 0){
          var timeStr1 = currentTime / 1000;// s
          var timeStr2 = parseInt(timeStr1 / 60);// m
          var timeStr3 = (timeStr1 - timeStr2*60) >= 10 ? (timeStr1 - timeStr2*60) :
          '0'+(timeStr1 - timeStr2*60);
          var timeStr2 = timeStr2 >= 10 ? timeStr2 : '0'+timeStr2;
          _this.setData({
            timeStr:timeStr2+':'+timeStr3
          })
        }
        var lineWidth = 6 / _this.data.rate;//px
        var ctx = wx.createCanvasContext('progress_active');
        ctx.setLineWidth(lineWidth);
        ctx.setStrokeStyle('#ffffff');
        ctx.setLineCap('round');
        ctx.beginPath();
        ctx.arc(400/_this.data.rate/2,400/_this.data.rate/2,400/_this.data.rate/2-2*lineWidth,
          1.5*Math.PI,angle*Math.PI,false);
        ctx.stroke();
        ctx.draw();
      }else{
        var logs = wx.getStorageSync('logs') || [];
        logs.unshift({
          date:util.formatTime(new Date),
          cate:_this.data.cateActive,
          time:_this.data.time
        });
        wx.setStorageSync('logs', logs);
        _this.setData({
          timeStr:'00:00',
          okShow:true,
          pauseShow:false,
          continueCancelShow:false
        });
        clearInterval(timer);
      }
    },100)
    _this.setData({
      timer:timer
    })
  },
  pause:function(){
    clearInterval(this.data.timer);
    this.setData({
      pauseShow:false,
      continueCancelShow:true,
      okShow:false
    })
  },
  continue:function(){
    this.drawActivve();
    this.setData({
      pauseShow:true,
      continueCancelShow:false,
      okShow:false
    })
  },
  cancel:function(){
    clearInterval(this.data.timer);
    this.setData({
      pauseShow:true,
      continueCancelShow:false,
      okShow:false,
      clockShow:false
    })
  },
  ok:function(){
    clearInterval(this.data.timer);
    this.setData({
      pauseShow:true,
      continueCancelShow:false,
      okShow:false,
      clockShow:false
    })
  }


})

4. 在微信小程序项目根目录下新建utils文件夹,放置utils.js的文件

utils文件夹一定在项目根目录下(图3所示),utils.js文件是对日期格式进行处理,代码如下:
在这里插入图片描述

图3

utils.js代码:

const formatTime = date => {
  const year = date.getFullYear()
  const month = date.getMonth() + 1
  const day = date.getDate()
  const hour = date.getHours()
  const minute = date.getMinutes()
  const second = date.getSeconds()

  return [year, month, day].map(formatNumber).join('-') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}

const formatNumber = n => {
  n = n.toString()
  return n[1] ? n : '0' + n
}

module.exports = {
  formatTime: formatTime
}

到这里,我们就可以实现微信小程序简单的计时器,你也可以在这个基础上实现一些更复杂的更好看的功能

  • 10
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
80个微信小程序源码: 一个(仿) 一元夺宝主页设计 万年历 下拉刷新,tab切换 事项助手 云笔记 五十音图 五险一金计算 交互操作控件 人脸检测 今日头条 你画我猜 健康菜谱 全屏动画滚动 医药网 卡卡汽车 获取用户 设备信息 同乐居商城:购物车合算 商城 图书管理系统 图文信息;欢迎页面,音乐控制 图片自适应 ,富文本解析 圆形菜单 外卖:实现类似锚点功能 天气预报 妈妈课堂 小游戏-别踩白块 小熊的日记 小程序地图定位 小程序完整demo:飞翔的小鸟:canvas实现,java后端(适用1221) 小程序官方Demo 小程序版2048 小程序页面生成器 康爱多微商城:学习界面设计 录音机 微票 我厨 tab 界面设计 手势解锁 排队取号,map组件使用 掘金首页信息流 摇一摇换文章 教务系统 新浪读书 新闻客户端 易打卡 表单设计 星巴克中国 智能机器人 校内新闻大图 框架 水浒传 治疗师 涂鸦 瀑布流布局 用户反馈组件 相册;处理用户信息 省市选择控件 知乎 知乎日报 知乎日报1 科学计算器 移动小商城:基于node,包含前后台 移动端商城 网易云课堂 腾讯云小程序一站式解决方案 自定义tabbar 芒果TV 语音跟读 跑步 地理位置 计时器 身份证查询 轮播图+菜单 轮播图变换 重邮 面包旅行:界面设计,文本展示 题库:选择选项,切换至下一题 首字母排序选择 鲜花订购,animation动画卡片效果 麻将骰子:附详细教程
123个微信小程序源码: AppleMusic B站首页界面设计:附详细教程 cnode社区版 dribbble FlexLayout布局 gank HIapp IT-EBOOK leantodu LOL战绩查询 movecss效果 Railay:整体框架 redux绑定 TCP,IP长连接 todo list v2ex 一个(仿) 一元夺宝主页设计 万年历 下拉刷新,tab切换 东航订机票 事项助手 二维码生成器 云笔记 五十音图 五险一金计算 人脸检测 今日头条 仿微信DEMO 仿找事吧 仿网易云音乐 会议精灵 你画我猜 侧滑布局 健康菜谱 全屏动画滚动 分答小程序 创客+实现大量功能,推荐研究 剪刀石头布 医药网 卡卡汽车 获取用户 设备信息 同乐居商城:购物车合算 商城 图书管理系统 图文信息;欢迎页面,音乐控制 图片自适应 ,富文本解析 圆形菜单 城市切换 备忘录 外卖:实现类似锚点功能 大转盘 天气预报 妈妈课堂 家居电商 富文本解析,折线图,MD5,bluebird 小游戏-别踩白块 小熊的日记 小程序地图定位 小程序完整demo:飞翔的小鸟:canvas实现,java后端(适用1221) 小程序官方Demo 小程序版2048 小程序页面生成器 康爱多微商城:学习界面设计 微票 我厨 tab 界面设计 手势解锁 掘金首页信息流 摇一摇换文章 教务系统 新浪读书 新闻客户端 易打卡 表单设计 星巴克中国 智能机器人 机器人兔兔 极客学院 果库 查拼音 校内新闻大图 框架 步步高字典 水浒传 治疗师 涂鸦 滑动选项卡 滴滴公交-查公交 瀑布流布局 用户反馈组件 电商-拼团 倒计时 电影推荐 电影日历 画布:时钟 番茄时钟 百度小说 相册;处理用户信息 省市选择控件 知乎 知乎日报 知乎日报1 科学计算器 移动小商城:基于node,包含前后台 移动端商城 简易计算器 网易云课堂 腾讯云小程序一站式解决方案 自定义tabbar 芒果TV 语音跟读 豆瓣图书 豆瓣电影 货币汇率 购物车 跑步 地理位置 计时器 身份证查询 车源宝 轮播图+菜单 轮播图变换 辩论倒计时 重邮 题库:选择选项,切换至下一题 首字母排序选择 高仿苹果计算器 麻将骰子:附详细教程

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值