<body>
<div style="background: rgb(228, 170, 180); width: 1000px;height: 50px"></div>
<div style="background: rgb(228, 109, 130); width: 1000px;height: 50px"></div>
<div style="background: rgb(233, 50, 80); width: 1000px;height: 50px"></div>
<div style="background: rgb(236, 9, 51); width: 1000px;height: 50px"></div>
<div id="ball" style="position:absolute;top: 50px; left: 100px;background:rgb(21, 109, 43);width:50px;height:50px"></div>
<div>
输入小球要移动的方向:<input id="prop"/>
输入小球移动后的位置:<input id="pos"/>
<button id="moveBtn">开始移动</button>
<button id="cancelBtn">撤销</button>
</div>
<script>
const tween = {
linear: function(allDistance, duration, time, startPos) {
return allDistance/duration*time + startPos
}
}
const Animate = function(dom) {
this.dom = dom;
this.startTime = 0;
this.duration = 0;
this.endPos = 0;
this.startPos = 0;
this.easing = null;
this.propertyName = null
}
Animate.prototype.start = function(propertyName, endPos, duration, easing) {
this.startTime = +new Date;
this.duration = duration
this.endPos = endPos
this.startPos = this.dom.getBoundingClientRect()[propertyName];
this.easing = tween[easing]
this.propertyName = propertyName
let timer = setInterval(() => {
console.log('timer')
if (this.step() === false) {
clearInterval(timer)
timer = null
}
}, 19)
}
Animate.prototype.step = function() {
const now = +new Date;
if (now >= this.startTime + this.duration) {
this.update(this.endPos)
return false
}
const pos = this.easing(this.endPos - this.startPos, this.duration, now - this.startTime, this.startPos)
this.update(pos)
}
Animate.prototype.update = function(pos) {
this.dom.style[ this.propertyName ] = pos + 'px';
}
var ball = document.getElementById( 'ball' );
var pos = document.getElementById( 'pos' );
var prop = document.getElementById( 'prop' );
var moveBtn = document.getElementById( 'moveBtn' );
var cancelBtn = document.getElementById( 'cancelBtn' );
let moveCommand = null
const MoveCommand = function() {
this.receiver = Array.prototype.shift.call(arguments)
this.args = arguments
this.oldArgs = null
}
MoveCommand.prototype.execute = function() {
this.receiver.start(...this.args);
const argsCopy = [...this.args]
Array.prototype.splice.call(argsCopy, 1, 1, this.receiver.startPos)
this.oldArgs = argsCopy
}
MoveCommand.prototype.undo = function() {
this.receiver.start(...this.oldArgs);
}
moveBtn.onclick = function(){
var animate = new Animate( ball );
moveCommand = new MoveCommand(animate, prop.value || 'left', pos.value, 1000, 'linear')
moveCommand.execute();
}
cancelBtn.onclick = function() {
moveCommand.undo();
}
</script>
</body>