vue实现直播间点赞飘心效果的示例代码


Posted in Javascript onSeptember 20, 2019

前言:

在开发公司项目的时候,遇到了直播间的一些功能,其中点赞冒泡飘心,就折腾了好久,canvas学的不好,自己写不来,百度找了一堆都是js原生写法,迁移到vue项目里来好多问题,百度也解决不了。自己试着慢慢解决,竟然在不知不觉中通了!废话不多说,直接上代码,复制粘贴即可使用

示例:

vue实现直播间点赞飘心效果的示例代码

不动就不动吧.png

```第一步```:先在外部新建一个js文件,取名index.js(名字自己随便取)

index.js代码内容如下:

/**
 * LikeHeart
 * @version: 1.0.0
 * @author tennylv
 * @date 2018-05-24
 *
 */
'use strict';
(function (root, factory) {
  if (typeof exports === 'object') {
    module.exports = factory();
    //CMD
  } else if (typeof define === 'function' && define.amd) {
    define(factory);
    //AMD
  } else {
    //WINDOW
    root.LikeHeart = factory(); 
  }
})(this, function() {

  var LikeHeart = function(opt) {

    /**
     * 初始化心
     * 
     * @param {object} 
     * @object.x {number} 心起点位置x
     * @object.y {number} 心起点位置y
     * @object.endX {number} 心结束位置x
     * @object.endY {number} 心结束位置y
     * @object.height {number} 高
     * @object.width {number} 宽
     * @object.angelBegin {number} 左右摇摆起始角度(可为负值)
     * @object.angelEnd {number} 左右摇摆结束角度
     * @object.angleLeft {bool} 是否起始从坐往右摇摆
     * @object.noScale {bool} 是否使用缩放心动画
     * @object.scaleDis {number} 缩放心临界值(默认从起始位置到升高50)
     * @object.noFadeOut {bool} 是否使用fadeOut
     * @object.opacityDis {number} fadeout心临界值(默认距离结束位置40)
     * @object.speed {number} 上升速度 
     * @object.bezierPoint {obj} 贝塞尔曲线4个点的值参考https://aaaaaaaty.github.io/bezierMaker.js/playground/playground.html
     * @object.fadeOut {function} 每个心fadeOut之后回调
     * @object.image {obj} 图片对象
     */


     this.id = opt.id;
     this.x = opt.x;
     this.y = opt.y;
     this.endX = opt.endX;
     this.endY = opt.endY;
     this.orignY = opt.y;
     this.height = opt.height;
     this.width = opt.width;
     this.angle = 0;
     this.angleLeft = opt.angleLeft;
     this.angelBegin = opt.angelBegin || (-20 + rand(1,2));
     this.angelEnd = opt.angelEnd || (20 + rand(1,4));
     this.scale = 0;
     this.scaleDis = opt.scaleDis || 50;
     this.opacityDis = opt.opacityDis || 40;
     this.noScale = opt.noScale;
     this.noAngel = opt.noAngel;
     this.opacity = 1;
     this.speed = opt.speed || 0.0027;
     this.bezierPoint = opt.bezierPoint;
     this.bezierDis = 0;
     this.onFadeOut = opt.onFadeOut;
     this.IMG = opt.image;

     this.move = function (ctx) {

      if (this.opacity === 0) {

        this.onFadeOut && this.onFadeOut(this);
      }

      this.y = getBezierLine(this).yt;
      this.x = getBezierLine(this).xt;


      this.angle = rangeAngle(this);
      this.scale = getFScale(this);
      this.opacity = getFAlpha(this);


      ctx.save();
      ctx.translate(this.x, this.y);
      ctx.rotate(this.angle*(Math.PI/180));
      ctx.scale(this.scale, this.scale);
      ctx.globalAlpha = this.opacity;

      ctx.drawImage(this.IMG, -(this.IMG.width/2), -(this.IMG.height/2), this.width, this.height);
      ctx.restore();
     };

  };


  /**
   * 计算心左右摇摆的方法
   */
  function rangeAngle(heart) {
    if (heart.noAngel) {
      return 0;
    }
    let _angle = heart.angle;

    // 心介于[start, end]之间不断变化角度
    if(_angle >= heart.angelEnd) {
      // 角度不断变小,向左摇摆
      heart.angleLeft = false;
    } else if (_angle <= heart.angelBegin){
      // 角度不断变大,向又摇摆
      heart.angleLeft = true;
    }

    // 动态改变角度
    if (heart.angleLeft) {
      _angle = _angle + 1;
    } else {
      _angle = _angle - 1;
    }

    return _angle;

  }


  /**
   * 计算缩放角度的方法
   */
  function getFScale(heart){
    if (heart.noScale) {
      return 1;
    }
    let _scale = heart.scale;


    // 随着距离起始点的距离增加,scale不断变大
    let dis = heart.orignY - heart.y;
    _scale = (dis / heart.scaleDis);

    // 当大于设置的阈值时变成1
    if (dis >= heart.scaleDis) {
      _scale = 1;
    }

    return _scale;
  }

  /**
   * 计算透明度的方法
   */
  function getFAlpha(heart) {

    let _opacity = heart.opacity;

    let dis = heart.y - heart.endY;

    if (dis <= heart.opacityDis) {

      _opacity = Math.max((dis / heart.opacityDis), 0);

    } else {
      _opacity = 1;
    }
    return _opacity;
  }

  /**
   * 获得min-max的随机整数
   */
  function rand (min, max) {
   return Math.floor(Math.random() * (max - min + 1)) + min;
  }

  /**
   * 获得贝塞尔曲线路径
   * 一共4个点
   */
  function getBezierLine(heart){
    var obj = heart.bezierPoint;
    var p0 = obj.p0;
    var p1 = obj.p1;
    var p2 = obj.p2;
    var p3 = obj.p3;
    var t = heart.bezierDis;
    var cx = 3 * (p1.x - p0.x),
      bx = 3 * (p2.x - p1.x) - cx,
      ax = p3.x - p0.x - cx - bx,

      cy = 3 * (p1.y - p0.y),
      by = 3 * (p2.y - p1.y) - cy,
      ay = p3.y - p0.y - cy - by,

      xt = ax * (t * t * t) + bx * (t * t) + cx * t + p0.x,
      yt = ay * (t * t * t) + by * (t * t) + cy * t + p0.y;

    heart.bezierDis += heart.speed;

    return {
      xt: xt,
      yt: yt
    }
  }

  return LikeHeart;

});
```第二步```:引入需要用到的页面
import LikeHeart from "../../../static/js/index";
```第三步```:直接复制下面这一段
<script>
import LikeHeart from "../../../static/js/index";
export default {
 props: ["ClassTimePlayer", "videoUrl"],
 data() {
  return {
   width: 175, //初始宽度
   height: 400, //初始高度
   heartList: [], //初始数组
   heartCount: 0 //累加计数初始值
  };
 },
 methods: {
  getRandomDis() {
   if (Math.random() > 0.5) {
    return -(Math.random() * 43);
   } else {
    return +(Math.random() * 43);
   }
  },
  createHeart() {
   this.heartCount++;
   let positionArray = [
    {
     x: 100,
     y: 400,
     endX: 100,
     endY: 100
    }
   ];
   let img = new Image();
   // img.src = "../../static/img/" + Math.ceil(Math.random() * 2) + ".png";
   img.src = `../../static/img/${Math.ceil(Math.random() * 5)}.png`;
   let p1 = {
    x: 100 + this.getRandomDis(),
    y: 300 + this.getRandomDis()
   };
   let p2 = {
    x: 100 + this.getRandomDis(),
    y: 200 + this.getRandomDis()
   };
   return new LikeHeart({
    id: this.heartCount,
    x: positionArray[0].x,
    y: positionArray[0].y,
    endX: positionArray[0].endX,
    endY: positionArray[0].endY,
    onFadeOut: this.removeItem,
    noAngel: true,//决定是否从小到大
    // noScale: true,//决定是否左右摆动
    width: 30, //决定心的大小
    height: 30,
    image: img,
    bezierPoint: {
     p0: {
      x: positionArray[0].x,
      y: positionArray[0].y
     },
     p1: p1,
     p2: p2,
     p3: {
      x: positionArray[0].endX,
      y: positionArray[0].endY
     }
    }
   });
  },
  removeItem(item) {
   var array = [];
   for (var i = 0; i < this.heartList.length; i++) {
    if (this.heartList[i].id !== item.id) {
     array.push(this.heartList[i]);
    }
   }
   this.heartList = array;
  },
  },

  
  
 
 mounted() {
  // 飘心
  var _this = this;
  var ctx = document.getElementById("cvs").getContext("2d");
  (ctx.canvas.width = _this.width),
   (ctx.canvas.height = _this.height),
   (function loop() {
    ctx.clearRect(0, 0, _this.width, _this.height);
    _this.heartList.forEach(function(item) {
     item && item.move(ctx);
    });
    requestAnimationFrame(loop);
   })();
  setInterval(function() {
   _this.heartList.push(_this.createHeart());
  }, 700);
  document.getElementById("cvs").addEventListener(
   "click",
   function() {
    console.log(111111)
    _this.heartList.push(_this.createHeart());
   },
   false
  );
 },
};
</script>
图片自己去换,至于在哪里换 
img.src = `../../static/img/${Math.ceil(Math.random() * 5)}.png`;
这个就是咯
 ```最后一步```:在html里,写上这个 
  <!-- 飘心 -->
  <canvas id="cvs"></canvas>

收尾:

然后就实现了。这个代码我也是百度的某个大神的,最后说明下不是我写的哈。迁移到vue中稍微修改了一下,勿喷。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Auntion-TableSort国人写的一个javascript表格排序的东西
Nov 12 Javascript
js 获取Listbox选择的值的代码
Apr 15 Javascript
jquery 鼠标滑动显示详情应用示例
Jan 24 Javascript
Javascript中的数组常用方法解析
Jun 17 Javascript
JS模拟bootstrap下拉菜单效果实例
Jun 17 Javascript
jQuery实现div横向拖拽排序的简单实例
Jul 13 Javascript
概述VUE2.0不可忽视的很多变化
Sep 25 Javascript
AngularJS实现与Java Web服务器交互操作示例【附demo源码下载】
Nov 02 Javascript
浅析Angular2子模块以及异步加载
Apr 24 Javascript
利用JS实现scroll自定义滚动效果详解
Oct 17 Javascript
微信小程序实现登录注册tab切换效果
Dec 29 Javascript
vue.js+elementUI实现点击左右箭头切换头像功能(类似轮播图效果)
Sep 05 Javascript
vue+layui实现select动态加载后台数据的例子
Sep 20 #Javascript
layui 中select下拉change事件失效的解决方法
Sep 20 #Javascript
微信小程序实现打开并下载服务器上面的pdf文件到手机
Sep 20 #Javascript
在layui框架中select下拉框监听更改事件的例子
Sep 20 #Javascript
关于layui 下拉列表的change事件详解
Sep 20 #Javascript
刷新页面后让控制台的js代码继续执行
Sep 20 #Javascript
layui动态绑定事件的方法
Sep 20 #Javascript
You might like
php与XML、XSLT、Mysql的结合运用实现代码
2009/11/19 PHP
更改localhost为其他名字的方法
2014/02/10 PHP
php 读取文件夹下所有图片、文件的实例
2018/10/17 PHP
PHP单例模式数据库连接类与页面静态化实现方法
2019/03/20 PHP
让网页根据不同IE版本显示不同的内容
2009/02/08 Javascript
JavaScript 高效运行代码分析
2010/03/18 Javascript
Extjs在exlipse中设置自动提示的方法
2010/04/07 Javascript
浅谈JavaScript编程语言的编码规范
2011/10/21 Javascript
日期处理的js库(迷你版)--自建js库总结
2011/11/21 Javascript
JQuery防止退格键网页后退的实现代码
2012/03/23 Javascript
jquery 面包屑导航 具体实现
2013/06/05 Javascript
JavaScript数字和字符串转换示例
2014/03/26 Javascript
jquery中show()、hide()和toggle()用法实例
2015/01/15 Javascript
JavaScript使用yield模拟多线程的方法
2015/03/19 Javascript
jquery操作select元素和option的实例代码
2016/02/03 Javascript
angular 基于ng-messages的表单验证实例
2017/05/04 Javascript
EasyUI的DataGrid每行数据添加操作按钮的实现代码
2017/08/22 Javascript
Windows下使用Nodejs运行js的方法
2017/09/02 NodeJs
javascript基本常用排序算法解析
2017/09/27 Javascript
gulp安装以及打包合并的方法教程
2017/11/19 Javascript
js 提取某()特殊字符串长度的实例
2017/12/06 Javascript
详解vue 数据传递的方法
2018/04/19 Javascript
微信小程序登录数据解密及状态维持实例详解
2019/05/06 Javascript
基于js实现数组相邻元素上移下移
2020/05/19 Javascript
Vue如何跨组件传递Slot的实现
2020/12/14 Vue.js
[39:07]LGD vs VP 2018国际邀请赛淘汰赛BO3 第二场 8.21
2018/08/22 DOTA
简单介绍利用TK在Python下进行GUI编程的教程
2015/04/13 Python
Python中的二维数组实例(list与numpy.array)
2018/04/13 Python
linux下python中文乱码解决方案详解
2019/08/28 Python
python利用Excel读取和存储测试数据完成接口自动化教程
2020/04/30 Python
HTML5标签与HTML4标签的区别示例介绍
2013/07/18 HTML / CSS
英国手机壳购买网站:Case Hut
2019/04/11 全球购物
优秀通讯员事迹材料
2014/01/28 职场文书
后勤服务中心总经理工作职责
2014/03/03 职场文书
活动总结报告范文
2014/05/04 职场文书
2014年党务工作总结
2014/11/25 职场文书