小程序仿直播点爱心

不多说,直接上代码

准备

首先要准备的主要是四张图片,相信大家一看就知道这四张图片的用途了
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

js部分

var lastFrameTime = 0;
var counts = 0;
var ctxs = null;
var factor = {
  speed: .008, // 运动速度,值越小越慢
  t: 0 //  贝塞尔函数系数
};
var that;

var timer = null; // 循环定时器

Page({
  data: {
    style_img: '',
    img_path: [
      [{
        x: 30,
        y: 400
      }, {
        x: 70,
        y: 300
      }, {
        x: -50,
        y: 150
      }, {
        x: 30,
        y: 0
      }],
      [{
        x: 30,
        y: 400
      }, {
        x: 30,
        y: 300
      }, {
        x: 80,
        y: 150
      }, {
        x: 30,
        y: 0
      }],
      [{
        x: 30,
        y: 400
      }, {
        x: 0,
        y: 90
      }, {
        x: 80,
        y: 100
      }, {
        x: 30,
        y: 0
      }]
    ]
    //这里是贝塞尔曲线参数
  },
  onLoad: function (options) {
    that = this
    //获取canvas实例
    ctxs = wx.createCanvasContext('myscanvas')
  },

  onUnload: function () {
    if (timer != null) {
      clearTimeout(timer)
    }

  },
  //不断绘制图片到cavans
  requestAnimationFrame(callback) {
    var currTime = new Date().getTime();
    //手机屏幕刷新率一般为60Hz,大概16ms刷新一次,这里为了使页面看上去更流畅自然,通过改变timedis的值可以控制动画的快慢
    var timedis = 16 - (currTime - lastFrameTime)
    var timeToCall = Math.max(0, timedis);
    var id = setTimeout(callback, timeToCall);
    lastFrameTime = currTime + timeToCall;
    return id;
  },
  drawImages: function (data, repeatcount) {
    if (repeatcount == 0) {
      return
    }
    var p10 = data[0][0]; // 三阶贝塞尔曲线起点坐标值
    var p11 = data[0][1]; // 三阶贝塞尔曲线第一个控制点坐标值
    var p12 = data[0][2]; // 三阶贝塞尔曲线第二个控制点坐标值
    var p13 = data[0][3]; // 三阶贝塞尔曲线终点坐标值

    var p20 = data[1][0];
    var p21 = data[1][1];
    var p22 = data[1][2];
    var p23 = data[1][3];

    var p30 = data[2][0];
    var p31 = data[2][1];
    var p32 = data[2][2];
    var p33 = data[2][3];

    var t = factor.t;

    /*计算多项式系数*/
    var cx1 = 3 * (p11.x - p10.x);
    var bx1 = 3 * (p12.x - p11.x) - cx1;
    var ax1 = p13.x - p10.x - cx1 - bx1;

    var cy1 = 3 * (p11.y - p10.y);
    var by1 = 3 * (p12.y - p11.y) - cy1;
    var ay1 = p13.y - p10.y - cy1 - by1;

    /*计算xt yt坐标值 */
    var xt1 = ax1 * (t * t * t) + bx1 * (t * t) + cx1 * t + p10.x;
    var yt1 = ay1 * (t * t * t) + by1 * (t * t) + cy1 * t + p10.y;

    /** 计算多项式系数*/
    var cx2 = 3 * (p21.x - p20.x);
    var bx2 = 3 * (p22.x - p21.x) - cx2;
    var ax2 = p23.x - p20.x - cx2 - bx2;

    var cy2 = 3 * (p21.y - p20.y);
    var by2 = 3 * (p22.y - p21.y) - cy2;
    var ay2 = p23.y - p20.y - cy2 - by2;

    /*计算xt yt坐标值*/
    var xt2 = ax2 * (t * t * t) + bx2 * (t * t) + cx2 * t + p20.x;
    var yt2 = ay2 * (t * t * t) + by2 * (t * t) + cy2 * t + p20.y;


    /** 计算多项式系数*/
    var cx3 = 3 * (p31.x - p30.x);
    var bx3 = 3 * (p32.x - p31.x) - cx3;
    var ax3 = p33.x - p30.x - cx3 - bx3;

    var cy3 = 3 * (p31.y - p30.y);
    var by3 = 3 * (p32.y - p31.y) - cy3;
    var ay3 = p33.y - p30.y - cy3 - by3;

    /*计算xt yt坐标值*/
    var xt3 = ax3 * (t * t * t) + bx3 * (t * t) + cx3 * t + p30.x;
    var yt3 = ay3 * (t * t * t) + by3 * (t * t) + cy3 * t + p30.y;
    factor.t += factor.speed;
    ctxs.drawImage("./image/20190927164317146.png", xt1, yt1, 30, 30);
    ctxs.drawImage("./image/20190927164322462.png", xt2, yt2, 30, 30);
    ctxs.drawImage("./image/2019092716432733.png", xt3, yt3, 30, 30);
    ctxs.draw();
    if (factor.t > 1) {
      factor.t = 0;
      clearTimeout(timer)
      if (repeatcount <= -1) {
        that.startTimer(repeatcount)
      } else {
        if (counts < repeatcount) {
          that.startTimer(repeatcount)
          counts++
        } else {
          that.draworiginal()
          counts = 0;
        }
      }
    } else {
      timer = that.requestAnimationFrame(function () {
        that.drawImages(that.data.img_path, repeatcount)
      })
    }
  },
  onClickImage: function (e) {
    //点击心形的时候动画效果
    that.setData({
      style_img: 'transform:scale(1.3);'
    })
    setTimeout(function () {
      that.setData({
        style_img: 'transform:scale(1);'
      })
    }, 500)
    factor.t = 2
    counts= 0
    that.startTimer(1)
  },
  //repeatcount -1就是循环,其他大于零的整数就是动画循环次数
  startTimer: function (repeatcount) {
    that.drawImages(that.data.img_path, repeatcount)
  },
  draworiginal() {
    ctxs.drawImage("./image/20190927164311343.png", 30, 400, 30, 30);
    ctxs.drawImage("./image/20190927164317146.png", 30, 400, 30, 30);
    ctxs.drawImage("./image/20190927164322462.png", 30, 400, 30, 30);
    ctxs.draw();
  }
})
css部分
.fold{
   670rpx;
  height: 720rpx;
  position: fixed;
  bottom: 200rpx;
  left: 50%;
  transform: translateX(-50%);
}

.scrollFold{
  height:100%;
   100%;
}
.fold text{
  position: absolute;
  line-height: 90rpx;
  font-size: 32rpx;
   100%;
  border-radius: 16rpx;
  background: #fff;
  box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.1);
  display: block;
  text-align: center;

}
.fold view{
  position: fixed;
   100%;
  text-align: right;
  font-size: 36rpx;
  z-index: 10;
}



.canvas {
  background: transparent;
   90px;
  height: 400px;
  position: fixed;
  right: 20px;
  bottom: 60px;
}
/* transform下面的属性是为了让动画看上去更自然 */
.heart {
  position: fixed;
  right: 45px;
  bottom: 30px;
   40px;
  height: 40px;
  transform: scale(1);
  -webkit-transform: scale(1);
  -webkit-transition: ease all;
  -moz-transition: ease all;
  transition: ease all;
  -webkit-transition-duration: 700ms;
  -moz-transition-duration: 700ms;
  transition-duration: 700ms;
}
wxml部分
<view>
  <canvas canvas-id="myscanvas" class="canvas" />
  <image src="./image/20190927164311343.png" class="heart" bindtap="onClickImage" style="{{style_img}}"></image>
</view>
调用方法时请注意this指向
正道的光终将来临,当太阳升起的时候,光芒总会普照大地温暖人间。些许的阴霾也终会有被阳光洒满的一天
原文地址:https://www.cnblogs.com/sjruxe/p/13403626.html