先来张图:
源码:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>MyHtml.html</title>

    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    
    <style type="text/css">#btnDiv{
position: absolute;
top: 400px;
left: 600px;
}#main{
position: absolute;
top: 100px;
left: 600px;
}
</style><script type="text/javascript">function doSmall(){

var effectDiv = document.getElementById("effectDiv");
if(effectDiv != null || effectDiv != undefined){
alert("已经有实例,运行完再点吧!");
}else{
//隐藏当前层
var objDiv = document.getElementById("main");
//objDiv.style.display = "none";
//创建特效层
var effectDiv = document.createElement("div");
effectDiv.setAttribute("id","effectDiv");
//newDiv.innerHTML = "abc";
effectDiv.style.position = "absolute";
effectDiv.style.top = "100px";
effectDiv.style.left = "600px";
effectDiv.style.width = "300px";
effectDiv.style.height = "180px";
effectDiv.style.border = "1px dashed black";
effectDiv.style.overflow = "hidden";
document.body.appendChild(effectDiv);
//目标位置
var purposeX = 300;
var purposeY = 300;

var purpose = document.createElement("button");
purpose.setAttribute("id","purposePoint");
purpose.style.position = "absolute";
purpose.style.border = "1px solid black";
purpose.style.backgroundColor = "black";
purpose.style.width = "3px";
purpose.style.height = "3px";
purpose.style.overflow = "hidden";
purpose.style.left = purposeX;
purpose.style.top = purposeY;
document.body.appendChild(purpose);

//移动方向,该加还是该减
var centerPointX = parseInt(effectDiv.style.left) + (parseInt(effectDiv.style.width)) / 2;
var moveForwardX = (centerPointX > purposeX) ? '-' : '+'; var centerPointY = parseInt(effectDiv.style.top) + (parseInt(effectDiv.style.height)) / 2;
var moveForwardY = (centerPointY > purposeY) ? '-' : '+';

//特殊情况,回到自身中心点
if(centerPointX == purposeX && centerPointY == purposeY){
moveForwardX = '+';
moveForwardY = '+';
}

//alert(moveForwardX + "\t" + moveForwardY);

//var distance = Math.sqrt(Math.pow((Math.abs(centerPointX - purposeX)),2) + Math.pow((Math.abs(centerPointY - purposeY)),2));
//alert(distance); //两点距离

//特效缩小
effectSmall(purposeX,purposeY,moveForwardX,moveForwardY);
}
}/*
 * 缩小效果,newDiv宽width每次减小 10%
 */
function effectSmall(purposeX,purposeY,moveForwardX,moveForwardY){

var effectDiv = document.getElementById("effectDiv");
//特效层当前宽度
var eWidth = parseInt(effectDiv.style.width);
//特效层当前高度
var eHeight = parseInt(effectDiv.style.height);
//特效层当前中心点X轴
var eLeft = parseInt(effectDiv.style.left);
//特效层当前中心点Y轴
var eTop = parseInt(effectDiv.style.top);

//alert(eWidth + "\t" + eHeight + "\t" + eLeft + "\t" + eTop);


//中心点坐标
var centerPointX = eLeft + eWidth / 2;
var centerPointY = eTop + eHeight / 2;

//两点横、纵坐标绝对值(距离)
var distanceX = Math.abs(centerPointX - purposeX);
var distanceY = Math.abs(centerPointY - purposeY);

/* 宽度的增量 10% */
var calcWidth = eWidth * 0.1;
var vWidth = Math.round(calcWidth);
vWidth = (vWidth < 1) ? 1 : vWidth;

/* 高度的增量 10% */
var calcHeight = eHeight * 0.1;
var vHeight = Math.round(calcHeight);
vHeight = (vHeight < 1) ? 1 : vHeight;

/* 中心点 距离 目标点 的横坐标增量 */
var calcDistanceX = ((distanceX * vWidth) / eWidth) / 2;
//var calcDistanceX = (parseInt(distanceX) * 0.1) / 2;
var vDistanceX = Math.round(calcDistanceX);
vDistanceX = (vDistanceX < 1) ? 1 : vDistanceX; /* 中心点 距离 目标点 的纵坐标增量 */
var calcDistanceY = ((distanceY * vHeight) / eHeight) / 2;
//var calcDistanceY = (parseInt(distanceY) * 0.1) / 2;
var vDistanceY = Math.round(calcDistanceY);
vDistanceY = (vDistanceY < 1) ? 1 : vDistanceY;

//高度大于1就不断减小,同时位移
if(eHeight > 1){

if(eWidth >= vWidth){
effectDiv.style.width = (eWidth - vWidth) + 'px';
effectDiv.style.left = eval(eLeft + moveForwardX + vDistanceX) + 'px';
}else{
effectDiv.style.width = 0 + 'px';
}

if(eHeight >= vHeight){
effectDiv.style.height = (eHeight - vHeight) + 'px';
effectDiv.style.top = eval(eTop + moveForwardY + vDistanceY) + 'px';
}else{
effectDiv.style.height = 0 + 'px';
}

timer = setTimeout("effectSmall(" + purposeX + "," + purposeY + ",'" + moveForwardX + "','" + moveForwardY + "')",40);
}else{
effectDiv.style.display = "none";

var effectDiv = document.getElementById("effectDiv");
document.body.removeChild(effectDiv);

var purposePoint = document.getElementById("purposePoint");
document.body.removeChild(purposePoint);

clearTimeout(timer);
document.getElementById("main").style.display = "block";
}
if(eWidth < 50){
//alert(calcWidth + "\t" + calcHeight + "\n\nwidth:" + effectDiv.style.width + "\t" + "height:" + effectDiv.style.height + "\n\n" + "中心点坐标:\n\t" + centerPointX + "\t" + centerPointY);
}
}
function testMath(){
//alert(Math.abs(-200)); //绝对值
//alert(Math.pow(450,2)); //平方
//alert(Math.sqrt(214600)); //开平方
//alert(Math.round(0.5)); //最接近的整数

var aaa = "+";
alert(eval(4 + aaa + 5));
}</script>  </head>
  
  <body>
    
<div id="main">
<table border="1px solid #345323" style="width: 300px; height: 180px;">
<tr><td align="center">left: 600px;top: 100px</td></tr>
<tr><td align="center"><input type="button" style="width: 3px; height: 3px; background-color: black; border: 1px solid black;"></td></tr>
<tr><td align="center">width: 300px;height: 180px</td></tr>
</table>
</div> <div id="btnDiv">
<input type="button" value="缩小" onclick="doSmall()" />
<input type="button" value="测试JS的Math方法" onclick="testMath()" />
</div>


  </body>
</html>
我这个特效很简单,就俩动作,一个是effectDiv自身不断缩小到一个点;同时这个effectDiv位移到设定的目标点B(300,,300)
,如果把如下两行代码注释,只有缩小效果,看起来就很不错:effectDiv.style.left = eval(eLeft + moveForwardX + vDistanceX) + 'px';
effectDiv.style.top = eval(eTop + moveForwardY + vDistanceY) + 'px';
但是这两行代码加上,让效果层同时发生位移,就很丑了。请教大虾,位移应该怎么计算才能让effectDiv的中心点按图中的理想轨迹运动?也就是一条直线,不发生漂移,而且刚好运动到目标点,效果层effectDiv缩小到一个点,消失

解决方案 »

  1.   

    我喜欢这种游戏,哈上一个
    有注释,自己改哈。<html>
    <head>
        <title></title>
        <style type="text/css">
            #div1
            {
                border:1px solid #f0f0f0;
                background-color:#d0d0d0;
                position:absolute;
                left:50px;
                top:50px;
                width:100px;
                height:100px;
                overflow:hidden;
            }
        </style>
        <script language="javascript" type="text/javascript">
            function Timer() {
                this.steps = 100;   //分多少步完成
                this.curStep = 0;   //当前步数
                this.delay = 1;     //时间间隔
                this.percent = 0;   //进度百分比
                this.methods = [];  //所注册的方法
            }
            Timer.prototype = (function () {
                var timer = null;   //运行时的实例
                function Running() {
                    //结束,退出
                    if (timer.curStep >= timer.steps) return;                timer.curStep++;    //步数加1
                    timer.percent = timer.curStep / timer.steps;   //计算进度
                    for (var i = 0; i < timer.methods.length; i++) {
                        var fun = timer.methods[i];
                        fun(timer.percent); //调用所注册的方法
                    }
                    setTimeout(Running, timer.delay);
                }
                function Start() {
                    timer = this;   //设置当前运行实例
                    this.curStep = 0;
                    setTimeout(Running, this.delay);    //开始运行
                }            //添加一个方法
                function RegMethod(fun) {
                    this.methods.push(fun);
                }
                return {
                    //返回两个public的方法
                    Start: Start,
                    RegMethod: RegMethod
                };
            })();        var startPoint = { x: 0, y: 0 };    //开始位置
            var endPoint = { x: 300, y: 300 };  //结束位置
            function MoveDiv(percent) {
                //根据进度,计算位置
                var div = document.getElementById("div1");
                var pos = {
                    x: (endPoint.x - startPoint.x) * percent + startPoint.x,
                    y: (endPoint.y - startPoint.y) * percent + startPoint.y
                };
                div.style.left = pos.x + "px";
                div.style.top = pos.y + "px";
            }        var startSize = { w: 100, h: 100 }; //开始大小
            var endSize = { w: 5, h: 5 };   //结束大小
            function ResizeDiv(percent) {
                //根据进度,计算大小
                var div = document.getElementById("div1");
                var size = {
                    w: (endSize.w - startSize.w) * percent + startSize.w,
                    h: (endSize.h - startSize.h) * percent + startSize.h
                };
                div.style.width = size.w + "px";
                div.style.height = size.h + "px";
            }
            window.onload = function () {
                var t = new Timer();
                //注册两个效果
                t.RegMethod(MoveDiv);
                t.RegMethod(ResizeDiv);
                t.Start();  //启动
            }
        </script>
    </head>
    <body>
        <div id="div1"></div>
    </body>
    </html>
      

  2.   

    http://www.cnblogs.com/cloudgamer/default.html?OnlyTitle=1http://www.cnblogs.com/cloudgamer/archive/2008/05/17/1201386.html
      

  3.   

    修改一下MoveDiv函数就行了,相信不难的,只是换个公式而已
      

  4.   

    对,只需要点小改动。
    function MoveDiv(percent) { //根据进度,计算位置 
        var div = document.getElementById("div1");
    var size = {w:div.offsetWidth,h:div.offsetHeight};
    var pos = { x: (endPoint.x - startPoint.x) * percent + startPoint.x, y: (endPoint.y - startPoint.y) * percent + startPoint.y };
    div.style.left = pos.x - size.w/2 + "px";
    div.style.top = pos.y - size.h/2 + "px"; 
    }
      

  5.   

    提醒一下:div.offsetWidth 是不准确的  还有clientWidth 
    FF跟IE不统一  用div.style.width最合适了
      

  6.   

    我只看了那位漂亮大姐的代码,已经满足了我的需求,按百分比来算,给了我一种新思路,多谢了。那现在开始散分了,人人有份。最后贴出我做的一个Demo,支持IE、FF,其他浏览器没试过,未果,如果您有兴趣,可以帮俺测一下,谢谢:<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title>MyHtml.html</title>
        <meta http-equiv="content-type" content="text/html; charset=UTF-8">
        <style type="text/css">#main{
    position: absolute;
    top: 100px;
    left: 600px;
    }
    #bgDiv{
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: #D4D4D4;
    display: block;
    filter:Alpha(opacity=30);
        -moz-opacity: 0.3;
        opacity: 0.3;
    }</style><script type="text/javascript">function doSmall(event){
    bgDiv.style.display = "none";

    var effectDiv = document.getElementById("effectDiv");
    if(effectDiv != null || effectDiv != undefined){
    alert("已经有实例,运行完再点吧!");
    }else{
    //隐藏当前层
    var objDiv = document.getElementById("main");
    //objDiv.style.display = "none";
    //创建特效层
    var effectDiv = document.createElement("div");
    effectDiv.setAttribute("id","effectDiv");
    //effectDiv.innerHTML = "abc";
    effectDiv.style.position = "absolute";
    effectDiv.style.top = "100px";
    effectDiv.style.left = "600px";
    effectDiv.style.width = "300px";
    effectDiv.style.height = "180px";
    effectDiv.style.border = "1px dashed black";
    effectDiv.style.overflow = "hidden";
    document.body.appendChild(effectDiv);

    //速度
    var speed = 30;
    //目标位置
    var isIE = !-[1,];
    if(isIE){
    var purposeX = event.clientX;
    var purposeY = event.clientY;
    }else{
    var purposeX = event.pageX;
    var purposeY = event.pageY;
    }
    var purposeDiv = document.createElement("div");
    purposeDiv.setAttribute("id","purposePoint");
    purposeDiv.style.position = "absolute";
    purposeDiv.style.border = "1px solid black";
    purposeDiv.style.backgroundColor = "black";
    purposeDiv.style.width = "3px";
    purposeDiv.style.height = "3px";
    purposeDiv.style.overflow = "hidden";
    purposeDiv.style.left = purposeX + "px";
    purposeDiv.style.top = purposeY + "px";;
    document.body.appendChild(purposeDiv); var times = 1;
    //特效缩小
    effectSmall(purposeX,purposeY,times,speed);
    }
    }/*
     * 缩小效果,effectDiv宽width每次减小 10%
     */
    function effectSmall(purposeX,purposeY,times,speed){
    bgDiv.style.display = "none";
    //获得特效层实例
    var effectDiv = document.getElementById("effectDiv");

    //百分比
    var percent = times / 100;

    var startDivSize = {w: parseInt(effectDiv.style.width),h: parseInt(effectDiv.style.height)};
    var endDivSize = {w: 3,h: 3};

    //特效层左上方顶点
    var point = {x: parseInt(effectDiv.style.left),y: parseInt(effectDiv.style.top)};

    /* 特效层缩小 */
    effectDiv.style.width = (endDivSize.w - startDivSize.w) * percent + startDivSize.w + 'px';
    effectDiv.style.height = (endDivSize.h - startDivSize.h) * percent + startDivSize.h + 'px';

    /* 特效层位移 */
    effectDiv.style.left = (purposeX - point.x) * percent + point.x + 'px';
    effectDiv.style.top = (purposeY - point.y) * percent + point.y + 'px'; if(times < 30){
    times++;
    timer = setTimeout("effectSmall(" + purposeX + "," + purposeY + "," + times + "," + speed + ")",speed);
    }else{ document.body.removeChild(document.getElementById("effectDiv")); document.body.removeChild(document.getElementById("purposePoint"));

    bgDiv.style.display = "block";

    clearTimeout(timer);
    }
    }</script>  </head>
      
      <body>
        
    <div id="main">
    <table border="1px solid #345323" style="width: 300px; height: 180px;">
    <tr><td align="center">left: 600px;top: 100px</td></tr>
    <tr><td align="center">●</td></tr>
    <tr><td align="center">width: 300px;height: 180px</td></tr>
    </table>
    </div>

    <div id="bgDiv" onclick="doSmall(event)"></div>

      </body>
    </html>