js实现匀速下落动画怎么实现

JavaScript022

js实现匀速下落动画怎么实现,第1张

/*

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