【问题标题】:Eyes following cursor - positioning?眼睛跟随光标 - 定位?
【发布时间】:2017-04-26 19:33:25
【问题描述】:

我正在尝试使用 Javascript 创建一个跟随鼠标在页面周围移动的东西。我希望它是米老鼠,我希望他的眼睛跟随鼠标在他的眼球周围移动......这是我迄今为止所拥有的代码(从网络上的各个地方收集,所以感谢写了什么部分的人):

<script>
var jseyesimg="http://oi67.tinypic.com/frnys.jpg";
var jseyeimg="http://oi63.tinypic.com/nxwa5u.jpg";
var jseyeslink="http://www.javascriptkit.com";

var jseyeso=null, jseye1=null, jseye2=null;
var standardbody=(document.compatMode=="CSS1Compat")? document.documentElement : document.body //create reference to common "body" across doctypes

function jseyesobj(id) {
var i, x;
x= document[id];
if (!x && document.getElementById) x= document.getElementById(id);
for (i=0; !x && i<document.forms.length; i++) x= document.forms[i][id];
return(x);
}

function jseyesmove(x, y) {
var ex, ey, dx, dy;
if (jseyeso && jseye1 && jseye2 && jseyeso.style) {
ex=jseyeso.offsetLeft+46; ey=jseyeso.offsetTop+58;
dx=x-ex; dy=y-ey;
r=(dx*dx/49+dy*dy/289<1) ? 1 : Math.sqrt(49*289/(dx*dx*289+dy*dy*49));
jseye1.style.left= r*dx+36.5+'px'; jseye1.style.top= r*dy+44+'px';
ex+=56; dx-=56;
r=(dx*dx/49+dy*dy/289<1) ? 1 : Math.sqrt(49*289/(dx*dx*289+dy*dy*49));
jseye2.style.left= r*dx+92.5+'px'; jseye2.style.top= r*dy+44+'px';
}
}

function jseyes() {
var img;
var x, y, a=false;

if (arguments.length==2) {
x= arguments[0];
y= arguments[1];
a= true;
}

img= "<div id='jseyeslayer' style='position:"+
       (a ? "absolute; left:"+x+"; top:"+y : "relative")+
       "; z-index:5; width:150; height:150 overflow:hidden'>"+
     "<div id='jseye1' style='position:absolute; left:130; top:44; z-index:6; width:21; height:29'>"+
       "<img src='"+jseyeimg+"' width=21 height=29 onClick=\"location.href='"+jseyeslink+"'\">"+
     "</div>"+
     "<div id='jseye2' style='position:absolute; left:160; top:44; z-index:6; width:21; height:29'>"+
       "<img src='"+jseyeimg+"' width=21 height=29 onClick=\"location.href='"+jseyeslink+"'\">"+
     "</div>"+
     "<img src='"+jseyesimg+"' width=300 height=300 onClick=\"location.href='"+jseyeslink+"'\">"+
 "</div>";
document.write(img);
jseyeso=jseyesobj('jseyeslayer');
jseye1=jseyesobj('jseye1');
jseye2=jseyesobj('jseye2');

document.onmousemove=jseyesmousemove;
}

function jseyesmousemove(e) {
    var mousex=(e)? e.pageX : event.clientX+standardbody.scrollLeft
    var mousey=(e)? e.pageY : event.clientY+standardbody.scrollTop
jseyesmove(mousex, mousey);
//return(false);
}
</script>

我不知道如何将眼睛放在眼球内。如果有人能告诉我什么值意味着什么,我想尝试一些数字来看看什么看起来最好。 :)

谢谢:)

【问题讨论】:

    标签: javascript cursor


    【解决方案1】:

    我个人认为用画布来做这样的事情更有意义。

    我在下面创建了一个带注释的示例。该示例不使用图像,因此您必须自己完成该部分,这是一个很好的关于 canvas API 信息的资源(包括如何绘制图像)can be found on MDN

    数学可以分解为:

    1. 计算鼠标与眼球中心的夹角
    2. 使用三角法在该角度找到眼睛圆周上的点。由于米奇的眼睛是椭圆而不是完美的圆形,因此数学非常复杂,因此它们的半径会根据角度而变化。 See this answer 了解更多详情。
    3. 减去瞳孔半径(再次使用点 2 的三角函数,因为半径会根据角度而变化)。

    注意:按“运行代码 sn-p”查看示例工作。

    const canvas = document.querySelector('canvas');
    const context = canvas.getContext('2d');
    const TWOPI = 2 * Math.PI;
    
    // size the canvas to the full width/height available
    // Note: this solution is not responsive
    canvas.width = innerWidth;
    canvas.height = innerHeight;
    
    // eye objects will be in charge of holding state and rendering themselves
    class Eye {
      constructor(x, y) {
        this.x = x;
        this.y = y;
        this.width = 40;
        this.height = 80;
        this.pupil = { x: 0, y: 0, width: 10, height: 20 };
      }
    
      draw() {
        const {x, y} = this;
        
        context.save();
        context.translate(x, y);
        
        this.drawOutline();
        this.drawPupil()
        
        context.restore();
      }
      
      drawOutline() {
        const {width, height} = this;
        
        context.beginPath();
        context.ellipse(0, 0, width, height, 0, 0, TWOPI);
        context.stroke();
      }
      
      drawPupil() {
        const {x, y, width, height} = this.pupil;
        
        context.beginPath();
        context.ellipse(x, y, width, height, 0, 0, TWOPI);
        context.fill();
      }
      
      track(object) {
        const {x, y, width, height, pupil} = this;
        // find the angle between the mouse and the center of the eye
        const xDiff = (x - object.x);  
        const yDiff = (y - object.y);
        const angle = Math.atan2(yDiff, xDiff) - Math.PI;
    
        if (!isNaN(angle)) {
          // calculate the point on the circumference of the eye
          const cX = (width * Math.cos(angle));
          const cY = (height * Math.sin(angle));
          // calculate the point on the circumference of the pupil
          const pX = pupil.width * Math.cos(angle);
          const pY = pupil.height * Math.sin(angle);
        
          //  position the pupil at the edge of the eye, minus the radius of the pupil
          pupil.x = cX - pX;
          pupil.y = cY - pY;
        }
      }
    }
    
    // on mousemove update the mouse position
    window.addEventListener('mousemove', e => {
      mouse.x = e.clientX;
      mouse.y = e.clientY;
    });
    
    const mouse = { x: 0, y: 0 };
    const leftEye = new Eye(100, 100);
    const rightEye = new Eye(200, 100);
    
    // on every tick redraw the eyes with a new position
    function tick() {
      // clear canvas
      context.clearRect(0, 0, canvas.width, canvas.height);
      
      // track the mouse and draw the left eye
      leftEye.track(mouse);
      leftEye.draw();
      
      // copy the state of the left eyes pupil
      rightEye.pupil.x = leftEye.pupil.x;
      rightEye.pupil.y = leftEye.pupil.y;
      //rightEye.track(mouse); // or use this for independent eye tracking
      rightEye.draw();
     
      requestAnimationFrame(tick);
    }
    
    // kick off animation loop
    tick();
    body { margin: 0; }
    &lt;canvas /&gt;

    如果您对可视化编程感兴趣,我认为您可以通过查看 p5.jswork of Daniel Shiffman 来学到很多东西;他有很多关于像这样的东西入门的视频。我希望这会有所帮助,祝你好运!

    【讨论】:

    • 谢谢!有什么办法可以将这些眼睛放在正确位置的图像之上?我在编程方面绝对糟糕,感觉这样会更容易! :D
    • 提高编程能力的唯一方法是进行实验,所以恐怕我把这个留给你了!为您指明正确的方向;使用 canvas API,您可以将米奇的图像绘制到眼前的画布上,有关更多信息,请参阅 MDN 上的此页面:developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/…。或者,您可以使用 CSS 将 &lt;canvas&gt; 元素的眼睛放在 HTML &lt;img&gt; 元素上。
    • 过去一个小时左右我一直在研究它,我想我正在慢慢弄清楚。非常感谢您的帮助:)
    猜你喜欢
    • 2011-08-22
    • 2015-10-07
    • 2013-03-23
    • 2021-05-25
    • 2018-09-01
    • 1970-01-01
    • 2020-09-30
    • 2015-02-03
    • 2015-11-12
    相关资源
    最近更新 更多