parabola.js抛物线与加入购物车效果的示例代码


Posted in Javascript onOctober 25, 2017

在做购物车的时候发现一个很好用抛物线特效parabola.js,可先点击DEMO体验下。下面贴出一些关键代码,具体代码可在GitHub上查看

parabola.js

var funParabola = function (element, target, options) {
  /*
   * 网页模拟现实需要一个比例尺
   * 如果按照1像素就是1米来算,显然不合适,因为页面动不动就几百像素
   * 页面上,我们放两个物体,200~800像素之间,我们可以映射为现实世界的2米到8米,也就是100:1
   * 不过,本方法没有对此有所体现,因此不必在意
   */

  var defaults = {
    speed: 166.67, // 每帧移动的像素大小,每帧(对于大部分显示屏)大约16~17毫秒
    curvature: 0.001, // 实际指焦点到准线的距离,你可以抽象成曲率,这里模拟扔物体的抛物线,因此是开口向下的
    progress: function () {
    },
    complete: function () {
    }
  };

  var params = {};
  options = options || {};

  for (var key in defaults) {
    params[key] = options[key] || defaults[key];
  }

  var exports = {
    mark: function () {
      return this;
    },
    position: function () {
      return this;
    },
    move: function () {
      return this;
    },
    init: function () {
      return this;
    }
  };

  /* 确定移动的方式 
   * IE6-IE8 是margin位移
   * IE9+使用transform
   */
  var moveStyle = "margin", testDiv = document.createElement("div");
  if ("oninput" in testDiv) {
    ["", "ms", "webkit"].forEach(function (prefix) {
      var transform = prefix + (prefix ? "T" : "t") + "ransform";
      if (transform in testDiv.style) {
        moveStyle = transform;
      }
    });
  }

  // 根据两点坐标以及曲率确定运动曲线函数(也就是确定a, b的值)
  /* 公式: y = a*x*x + b*x + c;
   */
  var a = params.curvature, b = 0, c = 0;

  // 是否执行运动的标志量
  var flagMove = true;

  if (element && target && element.nodeType == 1 && target.nodeType == 1) {
    var rectElement = {}, rectTarget = {};

    // 移动元素的中心点位置,目标元素的中心点位置
    var centerElement = {}, centerTarget = {};

    // 目标元素的坐标位置
    var coordElement = {}, coordTarget = {};

    // 标注当前元素的坐标
    exports.mark = function () {
      if (flagMove == false) return this;
      if (typeof coordElement.x == "undefined") this.position();
      element.setAttribute("data-center", [coordElement.x, coordElement.y].join());
      target.setAttribute("data-center", [coordTarget.x, coordTarget.y].join());
      return this;
    }

    exports.position = function () {
      if (flagMove == false) return this;

      var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft,
        scrollTop = document.documentElement.scrollTop || document.body.scrollTop;

      // 初始位置
      if (moveStyle == "margin") {
        element.style.marginLeft = element.style.marginTop = "0px";
      } else {
        element.style[moveStyle] = "translate(0, 0)";
      }

      // 四边缘的坐标
      rectElement = element.getBoundingClientRect();
      rectTarget = target.getBoundingClientRect();

      // 移动元素的中心点坐标
      centerElement = {
        x: rectElement.left + (rectElement.right - rectElement.left) / 2 + scrollLeft,
        y: rectElement.top + (rectElement.bottom - rectElement.top) / 2 + scrollTop
      };

      // 目标元素的中心点位置
      centerTarget = {
        x: rectTarget.left + (rectTarget.right - rectTarget.left) / 2 + scrollLeft,
        y: rectTarget.top + (rectTarget.bottom - rectTarget.top) / 2 + scrollTop
      };

      // 转换成相对坐标位置
      coordElement = {
        x: 0,
        y: 0
      };
      coordTarget = {
        x: -1 * (centerElement.x - centerTarget.x),
        y: -1 * (centerElement.y - centerTarget.y)
      };

      /*
       * 因为经过(0, 0), 因此c = 0
       * 于是:
       * y = a * x*x + b*x;
       * y1 = a * x1*x1 + b*x1;
       * y2 = a * x2*x2 + b*x2;
       * 利用第二个坐标:
       * b = (y2+ a*x2*x2) / x2
       */
      // 于是
      b = (coordTarget.y - a * coordTarget.x * coordTarget.x) / coordTarget.x;

      return this;
    };

    // 按照这个曲线运动
    exports.move = function () {
      // 如果曲线运动还没有结束,不再执行新的运动
      if (flagMove == false) return this;

      var startx = 0, rate = coordTarget.x > 0 ? 1 : -1;

      var step = function () {
        // 切线 y'=2ax+b
        var tangent = 2 * a * startx + b; // = y / x
        // y*y + x*x = speed
        // (tangent * x)^2 + x*x = speed
        // x = Math.sqr(speed / (tangent * tangent + 1));
        startx = startx + rate * Math.sqrt(params.speed / (tangent * tangent + 1));

        // 防止过界
        if ((rate == 1 && startx > coordTarget.x) || (rate == -1 && startx < coordTarget.x)) {
          startx = coordTarget.x;
        }
        var x = startx, y = a * x * x + b * x;

        // 标记当前位置,这里有测试使用的嫌疑,实际使用可以将这一行注释
        element.setAttribute("data-center", [Math.round(x), Math.round(y)].join());

        // x, y目前是坐标,需要转换成定位的像素值
        if (moveStyle == "margin") {
          element.style.marginLeft = x + "px";
          element.style.marginTop = y + "px";
        } else {
          element.style[moveStyle] = "translate(" + [x + "px", y + "px"].join() + ")";
        }

        if (startx !== coordTarget.x) {
          params.progress(x, y);
          window.requestAnimationFrame(step);
        } else {
          // 运动结束,回调执行
          params.complete();
          flagMove = true;
        }
      };
      window.requestAnimationFrame(step);
      flagMove = false;

      return this;
    };

    // 初始化方法
    exports.init = function () {
      this.position().mark().move();
    };
  }

  return exports;
};

实现

// body
<div class="container">
  ![](dist/01.png)
  <center>点击加入购物车查看效果</center>

  <!--动画图片-->
  <div class="img-element" id="imgElement">
    ![](dist/02.jpg)
  </div>
  <!--购物车-->
  <div class="shop-cart" id="shopCart"></div>

  <span class="shop-cart-num">0</span>
  <div class="add-shop-cart"><!--加入购物车--></div>
</div>
// script
// 起始位置元素
var imgElement = document.querySelector('#imgElement'),
  // 终点位置元素
  shopCartElement = document.querySelector('#shopCart'),
  // 购物车数量
  proNum = 0;

// 初始化抛物线动画
var myParabola = funParabola(imgElement, shopCartElement, {
  speed: 100,// 每帧移动的像素大小
  curvature: 0.005,// 实际指焦点到准线的距离
  complete: function () {
    imgElement.style.visibility = "hidden";
    $('.shop-cart-num').text(++proNum);
  }
});
// 绑定加入购物车事件
$('.add-shop-cart').click(function () {
  // 重置位置
  $('#imgElement').css({ left: '70px', bottom: '25px', visibility: 'visible' });

  myParabola.position().move();
});

效果图

parabola.js抛物线与加入购物车效果的示例代码

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

Javascript 相关文章推荐
jquery ui dialog ie8出现滚动条的解决方法
Dec 06 Javascript
类似php的js数组的in_array函数自定义方法
Dec 27 Javascript
浅谈Jquery为元素绑定事件
Apr 27 Javascript
cocos creator Touch事件应用(触控选择多个子节点的实例)
Sep 10 Javascript
vue-devtools的安装步骤
Apr 23 Javascript
JS与SQL方式随机生成高强度密码示例
Dec 29 Javascript
微信小程序实现简单表格
Feb 14 Javascript
vue实现百度下拉列表交互操作示例
Mar 12 Javascript
node.js基于socket.io快速实现一个实时通讯应用
Apr 23 Javascript
微信小程序传值以及获取值方法的详解
Apr 29 Javascript
详解vue中多个有顺序要求的异步操作处理
Oct 29 Javascript
通过Kettle自定义jar包供javascript使用
Jan 29 Javascript
通过js控制时间,一秒一秒自己动的实例
Oct 25 #Javascript
js 显示日期时间的实例(时间过一秒加1)
Oct 25 #Javascript
JavaScript编程设计模式之观察者模式(Observer Pattern)实例详解
Oct 25 #Javascript
BootStrap 标题设置跨行无效的解决方法
Oct 25 #Javascript
vue基于mint-ui的城市选择3级联动的示例
Oct 25 #Javascript
浅谈Vue的加载顺序探讨
Oct 25 #Javascript
JavaScript模块模式实例详解
Oct 25 #Javascript
You might like
PHP远程连接MYSQL数据库非常慢的解决方法
2008/07/05 PHP
php5编程中的异常处理详细方法介绍
2008/07/29 PHP
程序员编程十条戒律
2009/07/09 PHP
PHP在获取指定目录下的目录,在获取的目录下面再创建文件,多平台
2011/08/03 PHP
Codeigniter框架实现获取分页数据和总条数的方法
2014/12/05 PHP
jQuery 自定义函数写法分享
2012/03/30 Javascript
微信分享的标题、缩略图、连接及描述设置方法
2014/10/14 Javascript
node.js中的buffer.toString方法使用说明
2014/12/14 Javascript
AngularJS学习笔记之基本指令(init、repeat)
2015/06/16 Javascript
浅谈express.js框架中间件(middleware)
2019/04/07 Javascript
JQuery通过键盘控制键盘按下与松开触发事件
2020/08/07 jQuery
你不知道的 TypeScript 高级类型(小结)
2020/08/28 Javascript
[04:44]DOTA2 2017全国高校联赛视频回顾
2017/08/21 DOTA
python获取当前计算机cpu数量的方法
2015/04/18 Python
Python爬虫包BeautifulSoup异常处理(二)
2018/06/17 Python
Django之模型层多表操作的实现
2019/01/08 Python
将Python文件打包成.EXE可执行文件的方法
2019/08/11 Python
Python 实现的 Google 批量翻译功能
2019/08/26 Python
python3+opencv生成不规则黑白mask实例
2020/02/19 Python
python自动下载图片的方法示例
2020/03/25 Python
如何通过python实现IOU计算代码实例
2020/11/02 Python
matplotlib实现数据实时刷新的示例代码
2021/01/05 Python
美国二手复古奢侈品包包购物网站:LXRandCo
2019/06/18 全球购物
家得宝墨西哥官网:The Home Depot墨西哥
2019/11/18 全球购物
捷克母婴用品购物网站:Feedo.cz
2020/12/28 全球购物
小学教师的自我评价范例
2013/10/31 职场文书
物业管理专业个人的自我评价
2013/11/19 职场文书
我的网上商城创业计划书
2013/12/26 职场文书
中专生职业生涯规划书范文
2014/01/10 职场文书
拉歌口号大全
2014/06/13 职场文书
洗手间标语
2014/06/23 职场文书
小学国旗下的演讲稿
2014/08/28 职场文书
2014年少先队工作总结
2014/12/03 职场文书
建国大业观后感600字
2015/06/01 职场文书
MySQL 使用SQL语句修改表名的实现
2021/04/07 MySQL
一次SQL如何查重及去重的实战记录
2022/03/13 MySQL