data:2022-11-17
author:lfp
move运动函数
dom--需要运动的对象
json--{width:100,height:100,left:100,top:100}
callback--回调函数 可调用自己 实现异步动画效果
*/
//主函数
function move(dom,json,callback){
//让每一次动画都是新的开始,防止出现动画一直不停的运行
if(dom.timer)clearInterval(dom.timer)
var i=0
var start=0
//在对象中增加timer 便于控制他停止
dom.timer=setInterval(function(){
i++
//循环每一个目标属性添加动画方法
for(var attr in json){
//获取当前attr的属性值 已经去除了px 还有 如果初始值是auto 用零代替
var cur=getStyle(dom,attr)
if(i==1)start=cur
//拿到该属性的目标值
var target=json[attr]
//设置分成10次增加增量 你可以根据需要修改
var speed=(target-start)/10
console.log(speed+"====="+cur)
//如果没有达到目标值就一直加
if(Math.abs(cur-target)>1){
dom.style[attr]=cur+speed+"px"
}else{
//达到目标值了就停止或者其他情况也停止
clearInterval(dom.timer)
//等停止了动画再回调函数进行另外的操作
if(callback)callback.call(dom)
}
}
},45)
}
//配套函数
function getStyle(dom,attr){
var value=""
if(window.getComputedStyle){
value=window.getComputedStyle(dom,false)[attr]
}else{
value=dom.currentStyle[attr]
}
value=parseInt(value)
return value || 0//如果你再样式中没有设置初始的值就会出现NaN 所以要用0来补充
}
function $(id){
//return document.getElementById(id)
return document.querySelector("#"+id)
}
<!DOCTYPE html><html>
<head>
<meta charset=UTF-8>
<title>Yugi</title>
<style>
*{
margin:0
padding:0
}
</style>
<script>
var Yugi = function(w, h, v)
{
this.w = w
this.h = h
this.v = v
}
Yugi.prototype = new Yugi
Yugi.prototype.constructor = Yugi
Yugi.pointToPoint = function(a, b) {
return Math.sqrt(Math.pow(a[0] - b[0], 2) + Math.pow(a[1] - b[1], 2))
}
Yugi.pointToAngle = function(origin, point) {
var PI = Math.PI
if (point[0] == origin[0]) {
if (point[1] > origin[1])
return PI * 0.5
return PI * 1.5
} else if (point[1] == origin[1]) {
if (point[0] > origin[0])
return 0
return PI
}
var t = Math.atan((origin[1] - point[1]) / (origin[0] - point[0]) * 1)
if (point[0] > origin[0] && point[1] < origin[1])
return t + 2 * PI
if (point[0] > origin[0] && point[1] > origin[1])
return t
return t + PI
}
Yugi.prototype.create = function(e, _sX, _sY)
{
var div = document.createElement("div")
div.style.position = "absolute"
div.style.cursor = "pointer"
div.style.width = this.w + "px"
div.style.height = this.h + "px"
var L = e.clientX + _sX - this.w / 2, T = e.clientY + _sY - this.h / 2
div.style.left = L + "px"
div.style.top = T + "px"
div.style.backgroundColor = "red"
document.body.appendChild(div)
this.elem = div
this.currPoint = [L, T]
}
Yugi.prototype.move = function(e, _sX, _sY)
{
var me = this, x = e.clientX + _sX - me.w / 2, y = e.clientY + _sY - me.h / 2
var newPoint = [x, y]
var sleep = 20, speed = me.v / sleep
me.interval && clearInterval(me.interval)
me.interval = setInterval(function() {
var len = Yugi.pointToPoint(me.currPoint, newPoint)
if (len < 1) {
clearInterval(me.interval)
me.interval = 0
} else {
var angle = Yugi.pointToAngle(me.currPoint, newPoint)
me.currPoint = [me.currPoint[0] + Math.cos(angle) * Math.min(len / 2, speed), me.currPoint[1] + Math.sin(angle) * Math.min(len / 2, speed)]
me.elem.style.left = me.currPoint[0] + 'px'
me.elem.style.top = me.currPoint[1] + 'px'
}
}, sleep)
}
var yugi = new Yugi(30, 30, 500)
document.onclick = function(e)
{
e = e || window.event
var _sX = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft
var _sY = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
var me = yugi
if (!me.elem) {
me.create(e, _sX, _sY)
}
else {
if (!me.interval) {
var cloned = document.createElement("div")
cloned.innerHTML = me.elem.outerHTML
document.body.appendChild(cloned.children[0])
}
me.move(e, _sX, _sY)
}
}
document.oncontextmenu = new Function("return false")
</script>
</head>
<body></body>
</html>
盒子 原来的位置 0+ 10 盒子现在的offsetLeft 10
|-5| = 5
这三个函数都是 数学函数
Math
比如说 console.log(Math.ceil(1.01)) 结果 是 2
console.log(Math.ceil(1.9))结果 2
console.log(Math.ceil(-1.3)) 结果 是 -1
比如说 console.log(Math.floor(1.01)) 结果 是 1
console.log(Math.floor(1.9)) 结果 1
console.log(Math.floor(-1.3)) 结果 是 -2
console.log(Math.round(1.01)) 结果 是 1
console.log(Math.round(1.9)) 结果 是 2
匀速动画的原理: 盒子本身的位置 + 步长
缓动动画的原理:盒子本身的位置 + 步长 (不断变化的)
( 缺陷:只能水平方向!随后的“封装运动框架单个属性会进一步改进” )
我们访问得到css 属性,比较常用的有两种:
点语法可以得到 width 属性 和 top属性 ** 带有单位的 。 100px
但是这个语法有非常大的 缺陷**, 不变的。
后面的width 和 top 没有办法传递参数的。
var w = width
box.style.w
最大的优点 : 可以给属性传递参数
我们想要获得css 的样式, box.style.left 和 box.style.backgorundColor
但是它只能得到 行内的样式。
但是我们工作最多用的是 内嵌式 或者 外链式 。
怎么办?
核心: 我们怎么才能得到内嵌或者外链的样式呢?
外部(使用<link>)和内嵌(使用<style>)样式表中的样式(ie和opera)
两个选项是必须的, 没有伪类 用 null 替代
我们这个元素里面的属性很多, left top width ===
我们想要某个属性, 就应该 返回该属性,所有继续封装 返回当前样式的 函数。
千万要记得 每个 的意思 : 那是相当重要
flag在js中一般作为开关,进行判断。
等动画执行完毕再去执行的函数 回调函数
我们怎么知道动画就执行完毕了呢?
很简单 当定时器停止了。 动画就结束了
案例源码:
in运算符也是一个二元运算符,但是对运算符左右两个操作数的要求比较严格。in运算符要求第1个(左边的)操作数必须是字符串类型或可以转换为字符串类型的其他类型,而第2个(右边的)操作数必须是数组或对象。只有第1个操作数的值是第2个操作数的属性名,才会返回true,否则返回false
案例源码:
链接: http://pan.baidu.com/s/1miEvqoo
密码:7fv8