6

我在 Javascript 方面的基础并不是最强的,我很好奇其他人将如何应对我为自己创造的当前挑战。

我在玩 paper.js

下面的代码创建了这个截屏

眼睛对鼠标事件的反应方式与此处的眼睛相同(从该代码中学习)— www.arc.id.au/XEyes.html

这是我所拥有的:

// Eye position center
eCntrX = 100
eCntrY = 100

var topLid = new Path()
topLid.add(new Point(eCntrX - 60, eCntrY))
topLid.add(new Point(eCntrX, eCntrY - 28))
topLid.add(new Point(eCntrX + 60, eCntrY))
topLid.add(new Point(eCntrX, eCntrY + 28))

topLid.strokeWidth = '6'
topLid.strokeColor = '#000'
topLid.closed = true
topLid.smooth()

var iris = new Path.Circle(eCntrX, eCntrY, 24)
iris.fillColor = '#6CE0FF'
iris.strokeWidth = '6'
iris.strokeColor = '#000'

var pupil = new Path.Circle(eCntrX, eCntrY, 15)
pupil.fillColor = '#000'

var glint = new Path.Circle(eCntrX, eCntrY, 5)
glint.fillColor = '#fff'
glint.position = new Point(eCntrX + 6, eCntrY - 6)

var ball = new Group([iris, pupil, glint])


function onMouseMove(event) {

  // Cursor position
  var csrX = event.point.x
  var csrY = event.point.y

  // Ball position
  var ballX = ball.position.x
  var ballY = ball.position.y

  // Displacement
  var dx = csrX - ballX
  var dy = csrY - ballY

  //Radius
  var r = 5

  //Pythagerous thereom calcs. R
  var R = Math.sqrt(dx*dx+dy*dy)

  x = dx*r/R
  y = dy*r/R

  ball.position = new Point(eCntrX + x, eCntrY + y)

  // console.log('x:' + x + 'y:' + y)

}

我希望用眼睛填满整个页面。我的最终目标是创建这样的东西:

最终结果

我的问题是,创建交互式多只眼睛的最佳方法是什么。

我一直在玩'for',但 onMouseMove 函数只适用于最后创建的 Eye。

也一直在看 paperjs item.clone — paperjs.org/reference/item#clone

还是我为每只眼睛创建独特的变量的问题?

这是按要求提供的代码:

for(var i = 0; i < 10; i++){

  // Eye position center
  // 100, 300, 500, 600
  eCntrX = 100 * i + 100
  eCntrY = 100

  var topLid = new Path()
  topLid.add(new Point(eCntrX - 60, eCntrY))
  topLid.add(new Point(eCntrX, eCntrY - 28))
  topLid.add(new Point(eCntrX + 60, eCntrY))
  topLid.add(new Point(eCntrX, eCntrY + 28))

  topLid.strokeWidth = '6'
  topLid.strokeColor = '#000'
  topLid.closed = true
  topLid.smooth()

  var iris = new Path.Circle(eCntrX, eCntrY, 24)
  iris.fillColor = '#6CE0FF'
  iris.strokeWidth = '6'
  iris.strokeColor = '#000'

  var pupil = new Path.Circle(eCntrX, eCntrY, 15)
  pupil.fillColor = '#000'

  var glint = new Path.Circle(eCntrX, eCntrY, 5)
  glint.fillColor = '#fff'
  glint.position = new Point(eCntrX + 6, eCntrY - 6)

  var ball = new Group([iris, pupil, glint])

}

function onMouseMove(event) {

    // Cursor position
    var csrX = event.point.x
    var csrY = event.point.y

    // Ball position
    var ballX = ball.position.x
    var ballY = ball.position.y

    // Displacement
    var dx = csrX - ballX
    var dy = csrY - ballY

    //Radius
    var r = 5

    //Pythagerous thereom calcs. R
    var R = Math.sqrt(dx*dx+dy*dy)

    x = dx*r/R
    y = dy*r/R

    ball.position = new Point(eCntrX + x, eCntrY + y)

    console.log('x:' + x + 'y:' + y)

}
4

2 回答 2

4

您需要创建一个包含所有眼睛的变量,然后在 mousemove 事件中循环遍历该变量中的元素并应用逻辑依次定位每个眼睛。

var eyeballs = [];
for (...) {
   .... 
   //var ball = new Group([iris, pupil, glint])
   eyeballs.push(new Group([iris, pupil, glint]));
}

function onMouseMove(event) {
    for (var i = 0, len = eyeballs.length; i < len; i++) {
        var ball = eyeballs[i];
        ...
        ball.position = new Point(eCntrX + x, eCntrY + y);
    }
}
于 2012-10-14T00:27:16.217 回答
2

我对 Paper.js 不熟悉,但我至少可以为您提供有关如何围绕它构建框架的想法。

基本上,你需要一个眼球工厂。一种制造眼球物体并将它们扔回你的东西。因此,您可以将它们挂在令人毛骨悚然的眼球墙上。

下面的代码示例不会完全起作用,您必须插入细节,但应该很容易理解。

var Eyeball = function(params){

    // Eye position center
    var eCntrX = params.x,
        eCntrY = params.y;

    var topLid = new Path()
    topLid.add(new Point(eCntrX - 60, eCntrY))
    topLid.add(new Point(eCntrX, eCntrY - 28))
    topLid.add(new Point(eCntrX + 60, eCntrY))
    topLid.add(new Point(eCntrX, eCntrY + 28))

    topLid.strokeWidth = '6'
    topLid.strokeColor = '#000'
    topLid.closed = true
    topLid.smooth()

    var iris = new Path.Circle(eCntrX, eCntrY, 24)
    iris.fillColor = '#6CE0FF'
    iris.strokeWidth = '6'
    iris.strokeColor = '#000'

    var pupil = new Path.Circle(eCntrX, eCntrY, 15)
    pupil.fillColor = '#000'

    var glint = new Path.Circle(eCntrX, eCntrY, 5)
    glint.fillColor = '#fff'
    glint.position = new Point(eCntrX + 6, eCntrY - 6)

    var ball = new Group([iris, pupil, glint]);


    //listen for the current mouse coordinates and update
    document.addEventListener('mousemove', function(event){

        // Cursor position
        var csrX = event.x,
        csrY = event.y;

        // Ball position
        var ballX = ball.position.x
        var ballY = ball.position.y

        // Displacement
        var dx = csrX - ballX
        var dy = csrY - ballY

        //Radius
        var r = 5

        //Pythagerous thereom calcs. R
        var R = Math.sqrt(dx*dx+dy*dy)

        x = dx*r/R
        y = dy*r/R

        ball.position = new Point(eCntrX + x, eCntrY + y)

    },false);

}

var eye = new Eyeball({x:100,y:100}); //if you want/need to pass in parameters for new Eyeballs like color or shape or whatever, you can define them in this object then access them in 'params' inside the Eyeball constructor.

为您的眼球壁制作多个眼球:

for(var i=0; i<100; i++){
   var eye = new Eyeball({x: Math.floor(Math.random()*300), y: Math.floor(Math.random()*300)});
}

在您的代码中,不会在任何地方调用 onMouseMove 函数。我不知道这是否是 Paper.js 调用的名称,还是您忘记包含更多代码。

如果您可以为我回答最后一部分,我会尝试用完整的答案来更新它。

更新

好的,让我们进行下一步,为您的眼球添加耳朵。顺便说一句,这简直太恶心了。

这个想法是每个眼球都是一个应该能够监听事件的对象。

paper.js 这样做的方式需要您在每个 mouseMove 事件上循环遍历所有眼球并更新定位。这可能会在每次更新期间锁定用户界面(想象一下成千上万的眼球!),因为 javascript 是单线程的。

我们要做的是让每个眼球对象直接监听“mousemove”事件,从中可以获取当前鼠标位置的 x 和 y 属性。我们通过在每个眼球内添加一个事件监听器来做到这一点。由于每个事件都将在其 Eyeball 实例的上下文中执行,因此“ball”变量对于每个事件都是唯一的。查看更新的示例代码,让我知道这一切是否有效。我很想看到一个有一百个眼球跟踪我的鼠标的示例页面。我认为...

于 2012-10-14T00:36:11.367 回答