微信小程序心形点赞效果

  • 前言
  • 准备
  • 实现
    • 原理
    • 布局
    • 样式
    • 逻辑实现
  • 尾巴

前言

之前写过一篇文章微信小程序Canvas绘图API,简单介绍了下微信小程序(下面统称小程序)Canvas绘图相关API的使用,然后写了一篇利用绘图知识绘制自定义参数二维码的文章微信小程序生成自定义参数二维码。今天,我们继续利用绘图相关API来实现标题所说的内容。先上效果图镇楼:

准备

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

实现

这个效果看上去确实不错,那么具体是怎么实现的了?

原理

上面的三张心形图片分别绘制在三条不同的三阶贝塞尔曲线上,最终三条贝塞尔曲线汇集到一个相同的点。这三条贝塞尔曲线的起点和终点相同,然后分别通过两个不同的控制点来实现不同的路径效果。

布局

说到布局整个页面就两个元素,最下面的心形肯定是个image没跑,另外一个就是我们今天的主角:Cavans;接下来看布局文件:

<view><canvas canvas-id="mycanvas" class="canvas" /><image src="../../images/heart_button.png" class="heart" bindtap="onClickImage" style="{{style_img}}"></image>
</view>

image中的style_img主要是为了实现点击image的时候的放大效果,暂时可以先不用关注,其他的写法没啥难度。

样式

.canvas {background: transparent;width: 90px;height: 400px;position: fixed;right: 20px;bottom: 60px;
}
/* transform下面的属性是为了让动画看上去更自然 */
.heart {position: fixed;right: 45px;bottom: 30px;width: 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;
}

这里将canvas的高度设置成400px,宽度设置为90px,然后position设置为fixed(不知道fixed作用的请戳这里:微信小程序布局技巧(二)),最后设置底部心形的位置使之在canvas底部中间位置。如下图:

逻辑实现

要实现逻辑我们首先要找到的就是三条贝塞尔曲线,三阶贝塞尔曲线包括起点、终点和两个控制点(三阶贝塞尔曲线本文不做重点科普,不懂的童鞋去度娘)。从文章最开始效果图看,刚开始所有的心形都是从最底部心形的位置冒出来的,所以起点我们很好确定x:30,y:400,x坐标通过计算得出(90+25)-45-40,y坐标自然是canvas高度。而终点坐标则更简单了x:30,y:0,因为最终都汇集在canvas顶部,y坐标自然为0。但是中间控制点的坐标则没有这么有规律了,需要根据你想要的效果去慢慢尝试。本文中的三条贝塞尔曲线的参数如下:

[[{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}]]

这为了便于操作放入了一个二维数组,接下来就是js代码实现

var lastFrameTime = 0;
var count = 0;
var ctx = 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实例ctx = wx.createCanvasContext('mycanvas')},onUnload: function () {if (timer != null) {clearTimeout(timer)}},//不断绘制图片到cavansrequestAnimationFrame(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;},drawImage: 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;ctx.drawImage("../../images/heart1.png", xt1, yt1, 30, 30);ctx.drawImage("../../images/heart2.png", xt2, yt2, 30, 30);ctx.drawImage("../../images/heart3.png", xt3, yt3, 30, 30);ctx.draw();if (factor.t > 1) {factor.t = 0;clearTimeout(timer)if(repeatcount <= -1){that.startTimer(repeatcount)}else{if (count < repeatcount){that.startTimer(repeatcount)count++}else {that.draworiginal()count = 0;}}} else {timer = that.requestAnimationFrame(function () {that.drawImage(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 = 2count = 0that.startTimer(1)},//repeatcount -1就是循环,其他大于零的整数就是动画循环次数startTimer: function (repeatcount) {that.drawImage(that.data.img_path, repeatcount)},draworiginal(){ctx.drawImage("../../images/heart1.png", 30, 400, 30, 30);ctx.drawImage("../../images/heart2.png", 30, 400, 30, 30);ctx.drawImage("../../images/heart3.png", 30, 400, 30, 30);ctx.draw();}
})

上面注释都写的很清楚了,我们再梳理下流程:

  • 通过底部心形的点击事件,然后开启一个定时器。
  • 然后在定时器中不断的改变贝塞尔函数系数来计算三条不同贝塞尔曲线不同时刻的点坐标,最后将图片绘制到canvas上面。
  • 贝塞尔函数系数大于1的时候则停止绘制动画,否则递归调用drawImage函数来绘制图片到不同位置。
  • requestAnimationFrame函数用来控制动画的时间长短
  • draworiginal函数将图片都画到原始位置

最后我们看下repeatcount 为1的情况

点我用开发者工具打开

尾巴

马上快到伟大祖国70华诞了,借用此篇文章再次给我们伟大的祖国点赞,祝愿祖国的明天更加美好!

老规矩如果你喜欢我的文章,欢迎给我点赞,评论,谢谢!!

微信小程序心形点赞效果相关推荐

  1. 微信小程序的爱心点赞

    微信小程序的爱心点赞 解决方法 heart.png是白色的心,heart-active.png是红心 <image bindtap="clickHeart" class=&q ...

  2. 微信小程序轮播图中间变大_微信小程序实现带放大效果的轮播图

    本文实例为大家分享了微信小程序实现带放大效果的轮播图,供大家参考,具体内容如下 效果如图 WXML WXSS .Carousel{ margin-top: 49px; background-color ...

  3. 微信小程序实现城市选择效果(超详细)

    直接进入正题 首先在项目中同级创建一个components文件夹,在文件夹下创建region-picker文件夹,在该文件夹点击右键新建Component就会创建名为 region-picker.js ...

  4. php文字左右滚动通告,微信小程序左右滚动公告栏效果代码实例

    这篇文章主要介绍了微信小程序左右滚动公告栏效果代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 代码如下 {{notice}} x data: ...

  5. ar 微信小程序_微信小程序可以实现AR效果了

    微信小程序可以实现AR效果了 金羊网  作者:马化展  2019-07-08 金羊网讯 记者马化展报道:7月5日,微信宣布微信小程序可实现AR效果了.同日,首个小程序AR动态试妆的美妆品牌小程序正式落 ...

  6. 微信小程序实现星星评价效果

    这篇文章主要为大家详细介绍了微信小程序实现星星评价效果,支持多个条目评价,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 本文实例为大家分享了微信小程序实现星星评价效果的具体代码,供大家参考,具体内 ...

  7. 微信小程序实现星星评分效果

    微信小程序实现星星评分效果 思路很简单,小星星都是一张张独立的图片,点击的时候改变图片的路径就可以了. 我是用背景图片做的,先给盒子设置背景图片为灰色的小星星,盒子是根据js文件中的stars数组循环 ...

  8. 微信小程序学习做动画效果

    微信小程序开发交流qq群   173683895    承接微信小程序开发.扫码加微信. 微信扫码学习,在线指导微信小程序动画效果的实现

  9. [微信小程序]手指触摸动画效果(完整代码附效果图)

    微信小程序开发交流qq群   173683895 本文共有两个示例,先上图 示例一:  示例二: 示例一代码(微信小程序): // pages/test/test.js Page({container ...

最新文章

  1. g2o入门——g2o的基本使用方法
  2. 读后感与机翻《从视频中推断力量和学习人类效用》
  3. mysql创建索引要加index吗_MySql创建索引,添加索引
  4. php上传,PHP-文件上传和下载「程序员培养之路第三十八天」
  5. 字典树模板+洛谷P2580 于是他错误的点名开始了
  6. Crazy Drops 3
  7. 【OpenCV 例程200篇】74. 图像的抗混叠
  8. linux下移动或者复制文件覆盖相同文件夹时,文件夹里面的每个文件都提示是否覆盖...
  9. mysql版本引起的驱动问题
  10. Error: Invalid or corrupt
  11. 两个不同的list合并_Stata:数据合并与匹配mergereclink
  12. 启动FastDFS,安装nginx,整合fdfs与nginx,进行上传下载测试
  13. 使用boston房价数据进行线性回归分析
  14. hdu1260Tickets
  15. 百度有啊创始团队写博客 自曝高层动荡内幕
  16. 【推荐】移动App测试中的最佳做法
  17. QQ空间g_tk、bkn加密参数算法
  18. CentOS8迁移TencentOS 3.1实践
  19. new relic_Datadog,SignalFX,New Relic,Wavefront –您应该选择哪个仪表板?
  20. 解决Orcale登录界面乱码问题(linux)

热门文章

  1. 基于Python(sklearn)计算PLS中的VIP值
  2. 虹科案例 | 2016年 Komatsu 138US负载下发动机抖动
  3. edge+android+广告插件下载,edge浏览器怎么去广告? edge浏览器去广告插件adsafe的使用方法...
  4. C++中auto关键字编译错误解决
  5. 回馈粉丝,自费送价值2000的礼品和红包,先到先得!
  6. 世界各国的标准用电电压频率是多少
  7. DeepFM在贝壳房源详情页推荐场景的实践
  8. 字符流和字节流效率问题及原理,以及开发中使用
  9. 【电大题酷】【1】1200计算机应用基础
  10. IEEE Access:说我水刊?不服!