用java编写一个抛物线运动_JavaScript实现的抛物线运动效果

d8cc9aa1acd9fb02a814ef701d43f835.png

最近做购物车功能,看到天猫上的购物车有元素抛物线运动效果,所以也想凑热闹实现一个。

网上搜索了一下,看了一下张鑫旭的《小折腾:JavaScript与元素间的抛物线轨迹运动》,原理张鑫旭已经讲的很清楚了,多说了也没什么意思,就是数学公式。不过看代码个人觉得有点变扭,那不是我的习惯,所以自己重新写了一个。

如何使用:

运动位移的元素必须设置为position: absolute,通过绝对定位控制left,top来实现的;

首先你可以new一个对象:

var bool = new Parabola({

el: "#boll",

offset: [500, 100],

curvature: 0.005,

duration: 3000,

callback: function () {

alert("完成后回调")

},

stepCallback: function (x, y) {

console.log(x, y);

$("

").appendTo("body").css({

"position": "absolute",

"top": this.elOriginalTop + y,

"left": this.elOriginalLeft + x,

"background-color": "#CDCDCD",

"width": "5px",

"height": "5px",

"border-radius": "5px"

});

}

});

参数说明:

参数名

数据类型

默认值

描述

el

jQuery||String(选择器)

null

必须填写的参数,要移动的元素,可以是jQuery对象或选择器

offset

Array

[0, 0]

表示移动元素在X,Y轴的偏移位置,设置了targetEl参数后,该参数将失效

targetEl

jQuery||String(选择器)

null

终点元素,这时就会自动获取该元素的left、top值,来表示移动元素在X,Y轴的偏移位置;设置了这个参数,offset将失效

duration

Number

500

运动的时间,默认500毫秒

curvature

Number

0.001

抛物线曲率,就是弯曲的程度,越接近于0越像直线,默认0.001

callback

Function

null

运动后执行的回调函数,this指向该对象

stepCallback

Function

null

运动过程中执行的回调函数,this指向该对象,接受x,y参数,分别表示X,Y轴的偏移位置。

autostart

Boolean

false

是否自动开始运动,默认为false

方法:

.reset()

重置元素的位置

.start()

开始执行动画

.stop()

停止动画

.setOptions(options)

重置options参数

JS代码:

;

(function () {

var _$ = function (_this) {

return _this.constructor == jQuery ? _this : $(_this);

};

// 获取当前时间

function now() {

return +new Date();

}

// 转化为整数

function toInteger(text) {

text = parseInt(text);

return isFinite(text) ? text : 0;

}

var Parabola = function (options) {

this.initialize(options);

};

Parabola.prototype = {

constructor: Parabola,

/**

* 初始化

* @classDescription 初始化

* @param {Object} options 插件配置 .

*/

initialize: function (options) {

this.options = this.options || this.getOptions(options);

var ops = this.options;

if (!this.options.el) {

return;

}

this.$el = _$(ops.el);

this.timerId = null;

this.elOriginalLeft = toInteger(this.$el.css("left"));

this.elOriginalTop = toInteger(this.$el.css("top"));

// this.driftX X轴的偏移总量

//this.driftY Y轴的偏移总量

if (ops.targetEl) {

this.driftX = toInteger(_$(ops.targetEl).css("left")) - this.elOriginalLeft;

this.driftY = toInteger(_$(ops.targetEl).css("top")) - this.elOriginalTop;

} else {

this.driftX = ops.offset[0];

this.driftY = ops.offset[1];

}

this.duration = ops.duration;

// 处理公式常量

this.curvature = ops.curvature;

// 根据两点坐标以及曲率确定运动曲线函数(也就是确定a, b的值)

//a=this.curvature

/* 公式: y = a*x*x + b*x + c;

*/

/*

* 因为经过(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

*/

// 于是

this.b = ( this.driftY - this.curvature * this.driftX * this.driftX ) / this.driftX;

//自动开始

if (ops.autostart) {

this.start();

}

},

/**

* 初始化 配置参数 返回参数MAP

* @param {Object} options 插件配置 .

* @return {Object} 配置参数

*/

getOptions: function (options) {

if (typeof options !== "object") {

options = {};

}

options = $.extend({}, defaultSetting, _$(options.el).data(), (this.options || {}), options);

return options;

},

/**

* 定位

* @param {Number} x x坐标 .

* @param {Object} y y坐标 .

* @return {Object} this

*/

domove: function (x, y) {

this.$el.css({

position: "absolute",

left: this.elOriginalLeft + x,

top: this.elOriginalTop + y

});

return this;

},

/**

* 每一步执行

* @param {Data} now 当前时间 .

* @return {Object} this

*/

step: function (now) {

var ops = this.options;

var x, y;

if (now > this.end) {

// 运行结束

x = this.driftX;

y = this.driftY;

this.domove(x, y);

this.stop();

if (typeof ops.callback === 'function') {

ops.callback.call(this);

}

} else {

//x 每一步的X轴的位置

x = this.driftX * ((now - this.begin) / this.duration);

//每一步的Y轴的位置y = a*x*x + b*x + c; c==0;

y = this.curvature * x * x + this.b * x;

this.domove(x, y);

if (typeof ops.stepCallback === 'function') {

ops.stepCallback.call(this);

}

}

return this;

},

/**

* 设置options

* @param {Object} options 当前时间 .

*/

setOptions: function (options) {

this.reset();

if (typeof options !== "object") {

options = {};

}

this.options = this.getOptions(options);

this.initialize('parabola', this.options);

return this;

},

/**

* 开始

*/

start: function () {

var self = this;

// 设置起止时间

this.begin = now();

this.end = this.begin + this.duration;

if (this.driftX === 0 && this.driftY === 0) {

// 原地踏步就别浪费性能了

return;

}

/*timers.push(this);

Timer.start();*/

if (!!this.timerId) {

clearInterval(this.timerId);

this.stop();

}

this.timerId = setInterval(function () {

var t = now();

self.step(t);

}, 13);

return this;

},

/**

* 重置

*/

reset: function (x, y) {

this.stop();

x = x ? x : 0;

y = y ? y : 0;

this.domove(x, y);

return this;

},

/**

* 停止

*/

stop: function () {

if (!!this.timerId) {

clearInterval(this.timerId);

}

return this;

}

};

var defaultSetting = {

el: null,

//偏移位置

offset: [0, 0],

//终点元素,这时就会自动获取该元素的left、top,设置了这个参数,offset将失效

targetEl: null,

//运动的时间,默认500毫秒

duration: 500,

//抛物线曲率,就是弯曲的程度,越接近于0越像直线,默认0.001

curvature: 0.001,

//运动后执行的回调函数

callback: null,

// 是否自动开始,默认为false

autostart: false,

//运动过程中执行的回调函数

stepCallback: null

};

window.Parabola = Parabola;

})();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值