开始使用javascript中的动画排版/粒子(将粒子映射到单词)?

时间:2016-04-02 06:05:29

标签: javascript html canvas particles particle-system

好吧,所以我对HTML和CSS有很多经验,并且有一些Javascript经验(我可以编写基本的函数并用类似的语言编写)。

我正在寻找一些视觉项目,并且对进入粒子系统特别感兴趣。我有一个类似于Codecademy的名称生成器(https://www.codecademy.com/courses/animate-your-name/0/1)的想法,其中粒子被映射到一个单词并且如果悬停在上面则移动。似乎alphabet.js正是Codecademy演示的真正背后,但我无法准确理解他们如何将粒子映射到单词等等。

我已经完成了一些基本的教程,只是在画布中创建基本的粒子,但我不确定画布是最好的方法 - 使用众多可用库之一的演示(例如http://soulwire.github.io/sketch.js/examples/particles.html)不要使用画布。

所以我的问题是 - 在Javascript中初学者/中级开始使用粒子系统的最佳方法是什么?具体来说,要完成Codecademy名称效果还是类似?我应该尝试使用画布或哪个库最好开始,你会如何推荐开始?

1 个答案:

答案 0 :(得分:0)

此项目的代码可用于您的中级JS程序员状态。

CodeAcademy项目如何运作......

  • 首先用圆圈构建每个字母并将每个圆圈的中心点保存在一个数组中。 alphabet.js脚本包含圆心点阵列。

  • mousemove事件中,测试哪些圆圈在鼠标位置的指定半径范围内。然后使用简单的三角法从鼠标位置径向向外为每个发现的圆圈设置动画。

  • 当鼠标再次移动时,测试哪些圆圈不再在当前鼠标位置的指定半径范围内。然后将每个“外部”圆圈动画回原始位置。

你也可以使用没有任何库的原生html5画布......

允许任何文本“解散”并重新组合的另一种方法

  • 首先在画布上绘制文字。顺便说一句,这种方法将“解散”任何绘图,而不仅仅是文本。

  • 使用context.getImageData获取画布上每个像素的不透明度值。确定画布上的哪些像素包含文本的一部分。你可以判断一个像素是否是文本的一部分,因为它是不透明的而不是透明的。

现在执行CodeAcademy对其圈子执行的相同操作 - 但使用您的像素:

  • mousemove事件中,测试哪些像素位于鼠标位置的指定半径范围内。然后使用简单的三角法从鼠标位置径向向外为每个发现的像素设置动画。

  • 当鼠标再次移动时,测试哪些像素不再在当前鼠标位置的指定半径范围内。然后将每个“外部”像素动画回原始位置。

[添加:mousemove事件以测试圆圈是否在鼠标距离内]

注意:您可能希望保持一个动画帧运行,根据每个圆圈的标记(isInside)将圆圈移动到原始位置更近或更远。

function handleMouseMove(e){
    // tell the browser we're handling this event
    e.preventDefault();
    e.stopPropagation();
    // calc the current mouse position
    mouseX=parseInt(e.clientX-offsetX);
    mouseY=parseInt(e.clientY-offsetY);

    // test each circle to see if it's inside or outside
    // radius of 40px to current mouse position
    // circles[] is an array of circle objects shaped like this
    //      {x:,y:,r:,originalX:,originalY:,isInside:}
    var radius=40;
    for(var i=0;i<circles.length;i++){
        var c=circles[i];
        var dx=c.x-mouseX;
        var dy=c.y-mouseY;
        if(dx*dx+dy*dy<radius*radius){
            c.isInside=true;
            // move c.x & c.y away from its originalX & originalY
        }else{
            c.isInside=false;
            // if the circle is not already back at it's originalX, originalY
            // then move c.x & c.y back towards its originalX, originalY
        }
    }
}