草像贝兹曲线平滑的动画? [英] Grass like smoothing animation on beziercurve?

查看:131
本文介绍了草像贝兹曲线平滑的动画?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是什么,我想achieve-- GRASS动画(所需的动画)

这是项目所在站在目前 - 我的头发动画

这是上面code - 我的头发动画(由坊间)的 - 头发动画的markE`s code

问题: -

我可以给动作来毛发,但动画应该更像波浪草一样freeflowing.Its不是很顺畅now.What可以做,使头发更加自然的方式流动。
请为我提供一个小样本如果可能的话!

 <帆布ID =myCanvasWIDTH =500HEIGHT =500的风格=背景色:古董白>< /帆布>

JAVASCRIPT

  //鼠标位置
变种X2 = 0;
变种Y2 = 0;window.addEventListener(鼠标移动功能(){移动(事件);的init()},FALSE)//这些变量在我们的贝塞尔曲线定义折弯
变种bend9 = 0;
变种bend8 = 0;
变种bend7 = 0;
变种bend6 = 0;
变种bend5 = 0;
变种bend4 = 0;
变种BEND3 = 0;
变种bend2 = 0;
变种bend1 = 0;//函数来得到鼠标cordinates
功能移动(事件){
    bend_value(); //该函数定义如下
    尝试
    {
        X2 = event.touches [0] .pageX;
        Y2 = event.touches [0] .pageY;
    }
    赶上(错误)
    {
        尝试
        {
            X2 = event.clientX;
            Y2 = event.clientY;
        }
        赶上(E)
        {
        }
    }    尝试
    {
        。事件preventDefault();
    }
    赶上(E)
    {
    }
    如果(间(y2,204,237)及&放大器;之间(x2,115,272))
    {
    的console.log(XMOVE =+ X2,yMove偏移=+ y2)的
    }}//功能贝塞尔曲线的声明范围
之间功能(VAL,最小值,最大值)
{
    返回VAL> = min的放大器;&安培; VAL< = MAX;
}(函数(){
    头发=功能(){
        返回此;
    };    hair.prototype = {     draw_hair:功能(A,B,C,D,E,F,G,H){            VAR SX = 136 + A; //启动中的moveTo curve.used位置(SX,SY)
            变种SY = 235 + B;
            VAR cp1x = 136 + C; //控制点1
            VAR cp1y = 222 + D;
            VAR cp2x = 136 + E; //控制点2
            VAR cp2y = 222 + F;
            VAR endx = 136 +克; //终点
            VAR恩迪= 210 + H;         变种帆布=的document.getElementById('myCanvas');
         VAR上下文= canvas.getContext('2D');
// context.clearRect(0,0500500);
         context.strokeStyle =灰色;
         context.lineWidth =8;
         context.beginPath();
         context.moveTo(SX,SY);
         context.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,endx,恩迪);
         context.lineCap ='圆';
         context.stroke();
// context.restore();
// context.save();
    }
};
})();//这个功能提供,并计算在鼠标移动弯曲
功能bend_value(){
    VAR REF1 = 135; //这是参考点,头发或曲线1号
    变种REF2 = 150; //头发没有2等
    VAR REF3 = 165;
    VAR REF4 = 180;
    VAR REF5 = 195;
    VAR REF6 = 210;
    VAR ref7 = 225;
    VAR ref8 = 240;
    VAR REF9 = 255;
如果(间(x2,115,270)及&放大器;之间(y2,205,236))
{
    如果(X2> = 135安培;&安培; X2< = 145){bend1 =(X2-REF1)*(2.2);}
    如果(2次&下; = 135&放大器;&放大器; X2> = 125){bend1 =(X2-REF1)*(2.2);}    如果(2次> = 150&放大器;&放大器; X2&下; = 160){bend2 =(X2-REF2)*(2.2);}
    如果(2次&下; = 150&放大器;&放大器; X2> = 140){bend2 =(X2-REF2)*(2.2);}    如果(2次> = 165&放大器;&放大器; X2&下; = 175){BEND3 =(X2-REF3)*(2.2);}
    如果(X2< = 165安培;&安培; X2> = 155){BEND3 =(X2-REF 3)*(2.2);}    如果(2次> = 180&放大器;&放大器; X2&下; = 190){bend4 =(X2-REF4)*(2.2);}
    如果(2次&下; = 180&放大器;&放大器; X2> = 170){bend4 =(X2-REF4)*(2.2);}    如果(2次> = 195&放大器;&放大器; X2&下; = 205){bend5 =(X2-REF5)*(2.2);}
    如果(X2< = 195安培;&安培; X2> = 185){bend5 =(X2-REF5)*(2.2);}    如果(X2> = 210安培;&安培; X2< = 220){bend6 =(X2-REF6)*(2.2);}
    如果(2次&下; = 210&放大器;&放大器; X2> = 200){bend6 =(X2-REF6)*(2.2);}    如果(2次> = 225&放大器;&放大器; X2&下; = 235){bend7 =(X2-ref7)*(2.2);}
    如果(2次&下; = 225&放大器;&放大器; X2> = 215){bend7 =(X2-ref7)*(2.2);}    如果(2次> = 240&放大器;&放大器; X2&下; = 250){bend8 =(X2-ref8)*(2.2);}
    如果(2次&下; = 240&放大器;&放大器; X2> = 230){bend8 =(X2-ref8)*(2.2);}    如果(2次> = 255&放大器;&放大器; X2&下; = 265){bend9 =(X2-REF9)*(2.2);}
    如果(X2< = 255安培;&安培; X2> = 245){bend9 =(X2-REF9)*(2.2);}
    }
}功能的init(){//这个函数绘制每一根头发/曲线
    变种帆布=的document.getElementById('myCanvas');
    VAR上下文= canvas.getContext('2D');
    VAR明确= context.clearRect(0,0500500);
    VAR保存= context.save();// / *的console.log(bend2 =+ bend2)
//执行console.log(BEND3 =+ BEND3)
//的console.log(bend4 =+ bend4)
//的console.log(bend5 =+ bend5)
//的console.log(bend6 =+ bend6)
//的console.log(bend7 =+ bend7)
//的console.log(bend8 =+ bend8)
//的console.log(bend9 =+ bend9)* /    HD1 =新发(); // HD1代表发得出1,本是绘制头发没有1中创建一个实例
    明确;
    hd1.draw_hair(0,0,0,0,0,0,0 + bend1 / 2,0); //这些参数传递给函数drawhair和弯曲的beint从功能bend_value检索()
    保存;    HD2 =新发();
    明确;
    hd2.draw_hair(15,0,15,0,15,0,15 + bend2 / 2,0);
    保存;    HD3 =新发();
    明确;
    hd3.draw_hair(30,0,30,0,30,0,30 + BEND3 / 2,0);
    保存;    HD4 =新发();
    明确;
    hd4.draw_hair(45,0,45,0,45,0,45 + bend4 / 2,0);
    保存;    HD5 =新发();
    明确;
    hd5.draw_hair(60,0,60,0,60,0,60 + bend5 / 2,0);
    保存;
 }在window.onload =函数(){
    在里面();
    disableSelection(document.body的)
}功能disableSelection(目标){
    如果(typeof运算target.onselectstart!=未定义)// IE
        target.onselectstart =函数(){返回false}
    否则,如果(typeof运算target.style.MozUserSelect!=未定义)//火狐
        target.style.MozUserSelect =无
    否则//所有其​​他如:歌剧
        target.onmousedown =函数(){返回false}
    target.style.cursor =默认
}


解决方案

更新:我目前正在调整的 code 产生请求的结果和评论它。

 (函数(){//将code被封装在一个自调用函数的范围隔离
  使用严格的;   //以下几行创建快捷方式的Box2D类型使用的建设者
   VAR B2Vec2 = Box2D.Common.Math.b2Vec2,
      B2BodyDef = Box2D.Dynamics.b2BodyDef,
      B2Body = Box2D.Dynamics.b2Body,
      B2FixtureDef = Box2D.Dynamics.b2FixtureDef,
      B2Fixture = Box2D.Dynamics.b2Fixture,
      B2World = Box2D.Dynamics.b2World,
      B2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape,
      B2RevoluteJoint = Box2D.Dynamics.Joints.b2RevoluteJoint,
      B2RevoluteJointDef = Box2D.Dynamics.Joints.b2RevoluteJointDef;  //这将确保有要求回调更新图形下一帧的方法
  window.requestAnimationFrame =
    window.requestAnimationFrame || //根据标准
    window.mozRequestAnimationFrame || //对于Mozilla
    window.webkitRequestAnimationFrame || //对于webkit的
    window.msRequestAnimationFrame || //为IE
    函数(f){window.setTimeout(函数(){F(Date.now());},1000至60年); }; //如果全部的寄托都失败  VAR世界=新B2World(新B2​​Vec2(0,-10),真),//创建重力的世界
      physicalObjects = [],//保持模拟对象的列表
      windInput = 0,//为风的输入在当前帧中
      风= 0,//当前风(平滑的输入值+随机性)
      STRAW_COUNT = 10,//吸管数量
      GRASS_RESET_SPEED = 2,//如何快速应秸秆重置为目标角度
      POWER_MOUSE_WIND = 120,//多少鼠标影响风
      POWER_RANDOM_WIND = 180; //多少随机性影响风  // GrassPart是一块吸管的原型。它具有以下性质
  //位置:片的位置
  //密度:一块密度
  //目标:片的目标角度
  // statik:一个布尔值,说明如果一块是静态的(即不动)
  功能GrassPart(位置,密度,目标statik){
    this.width = 0.05;
    this.height = 0.5;
    this.target =目标;    //要创建一个Box2D的身体,你必须设置一个主体定义
    //并创建至少一个夹具。
    VAR bdef =新B2BodyDef(),FDEF =新B2FixtureDef();
    //在这个例子中,我们指定如果身体是静态的还是没有(基层
    //必须静态保持在其位置的吸管),和其原始
    //位置。
    bdef.type = statik? B2Body.b2_staticBody:B2Body.b2_dynamicBody;
    bdef.position.SetV(位置);    //工件的夹具是与一个给定密度的盒子。负组索引
    //可以确保秸秆不发生冲突。
    fdef.shape =新B2PolygonShape();
    fdef.shape.SetAsBox(this.width / 2,this.height / 2);
    fdef.density =密度;
    fdef.filter.groupIndex = -1;    //主体和夹具被创建并添加到世界
    this.body = world.CreateBody(bdef);
    this.body.CreateFixture(FDEF);
  }  //该方法被称为用于动画的每一帧。它致力于将原来的
  //秸秆(联合)的角度。时间参数是闲置在这里,但包含了
  // 当前时间。
  GrassPart.prototype.update =功能(时间){
    如果(this.joint){
      this.joint.SetMotorSpeed​​(GRASS_RESET_SPEED *(this.target - this.joint.GetJointAngle()));
    }
  };  //链接方法用于使用联合在一起,秸秆的连接件
  //其他:一块链接
  //扭矩:联合(刚性)的强度
  GrassPart.prototype.link =功能(其它,扭矩){
    //这是所有Box2D的具体。在手册中查找。
    VAR jdef =新B2RevoluteJointDef();
    变种p值= this.body.GetWorldPoint(新B2Vec2(0,0.5)); //获取接合处的世界坐标
    jdef.Initialize(this.body,other.body页);
    jdef.maxMotorTorque =扭矩;
    jdef.motorSpeed​​ = 0;
    jdef.enableMotor =真;    //联合加入世界
    this.joint = world.CreateJoint(jdef);
  };  //一个原型草秸秆
  //位置:秸秆的根底部的位置
  功能草(位置){
    VAR POS =新B2Vec2(position.x,position.y);
    VAR角= 1.2 *的Math.random() - 0.6; //随机化目标角度    //创建三块,静态根和到多,将它们放置在线路。
    //第二个参数是关节的刚度。它控制着一根稻草是如何弯曲。
    //第三是目标角度和不同角度的片指定。
    this.g1 =新GrassPart(POS,1角/ 4,真正的); //这是静态的根
    pos.Add(新B2​​Vec2(0,1));
    this.g2 =新GrassPart(POS,0.75,角度);
    pos.Add(新B2​​Vec2(0,1));
    this.g3 =新GrassPart(POS,0.5);    //件连接成救命稻草
    this.g1.link(this.g2,20);
    this.g2.link(this.g3,3);    //件添加到模拟对象的列表
    physicalObjects.push(this.g1);
    physicalObjects.push(this.g2);
    physicalObjects.push(this.g3);
  }  Grass.prototype.draw =函数(上下文){
      变种p值=新B2Vec2(0,0.5);
      变种P1 = this.g1.body.GetWorldPoint(对);
      变种P2 = this.g2.body.GetWorldPoint(对);
      变种P3 = this.g3.body.GetWorldPoint(对);      context.strokeStyle =灰色;
      context.lineWidth = 0.4;
      context.lineCap ='圆';      context.beginPath();
      context.moveTo(p1.x,p1.y);
      context.quadraticCurveTo(p2.x,p2.y,p3.x,p3.y);
      context.stroke();
  };    VAR lastX,草= [],背景=的document.getElementById('画布')的getContext(2D)。    功能updateGraphics(时间){
      window.requestAnimationFrame(updateGraphics);      风= 0.95 *风+ 0.05 *(POWER_MOUSE_WIND * windInput + POWER_RANDOM_WIND *的Math.random() - POWER_RANDOM_WIND / 2);
      windInput = 0;
      world.SetGravity(新B2Vec2(风,-10));      physicalObjects.forEach(函数(OBJ){如果(obj.update)obj.update(时间);});
      world.Step(1/60,8,3);
      world.ClearForces();      context.clearRect(0,0,context.canvas.width,context.canvas.height);
      context.save();
      context.translate(context.canvas.width / 2,context.canvas.height / 2);
      context.scale(context.canvas.width / 20,-context.canvas.width / 20);
      grass.forEach(函数(O){o.draw(上下文);});
      context.restore();
    }    document.getElementsByTagName('身体')[0]阅读进度(鼠标移动功能(E){
      windInput = Math.abs(lastX - e.x)LT; 200? 0.2 *(e.x - lastX):0;
      lastX = e.x;
    });    无功W = 8;
    对于(VAR I = 0; I< STRAW_COUNT;我++){
      grass.push(新草(新B2Vec2(W *(ⅰ/(STRAW_COUNT-1)) - W / 2,-1)));
    }    window.requestAnimationFrame(updateGraphics);
})();

This is what I am trying to achieve--GRASS Animation(Desired animation)

This is where the project is standing currently --My hair animation

This is a more structurised code of the above code --My hair animation(by markE)--markE`s code of hair animation

PROBLEM:--

I am able to give movements to hairs but animation should be more like wavy grass like freeflowing.Its not very smooth now.What can be done to make the hairs flow in more natural manner. Please provide me with a small sample if possible!!!

    <canvas id="myCanvas" width="500" height="500" style="background-color: antiquewhite" ></canvas>

JAVASCRIPT

//mouse position
var x2=0;
var y2=0;

window.addEventListener("mousemove",function(){moving(event);init()},false)

//these variables define the bend in our bezier curve
var bend9=0;
var bend8=0;
var bend7=0;
var bend6=0;
var bend5=0;
var bend4=0;
var bend3=0;
var bend2=0;
var bend1=0;

//function to get the mouse cordinates
function moving(event) {
    bend_value();//this function is defined below
    try
    {
        x2 = event.touches[0].pageX;
        y2 = event.touches[0].pageY;
    }
    catch (error)
    {
        try
        {
            x2 = event.clientX;
            y2 = event.clientY;
        }
        catch (e)
        {
        }
    }

    try
    {
        event.preventDefault();
    }
    catch (e)
    {
    }
    if(between(y2,204,237) && between(x2,115,272))
    {
    console.log("Xmove="+x2,"Ymove="+y2)
    }

}

//function for declaring range of bezier curve
function between(val, min, max)
{
    return val >= min && val <= max;
}

(function() {
    hair = function() {
        return this;
    };

    hair.prototype={

     draw_hair:function(a,b,c,d,e,f,g,h){

            var sx  =136+a;//start position of curve.used in moveTo(sx,sy)
            var sy  =235+b;
            var cp1x=136+c;//control point 1
            var cp1y=222+d;
            var cp2x=136+e;//control point 2
            var cp2y=222+f;
            var endx=136+g;//end points
            var endy=210+h;

         var canvas = document.getElementById('myCanvas');
         var context = canvas.getContext('2d');
//         context.clearRect(0, 0,500,500);
         context.strokeStyle="grey";
         context.lineWidth="8";
         context.beginPath();
         context.moveTo(sx,sy);
         context.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,endx,endy);
         context.lineCap = 'round';
         context.stroke();
//         context.restore();
//         context.save();
    }
};
})();

//this function provides and calculate the bend on mousemove
function bend_value(){
    var ref1=135;//this is ref point for  hair or curve no 1
    var ref2=150;//hair no 2 and so on
    var ref3=165;
    var ref4=180;
    var ref5=195;
    var ref6=210;
    var ref7=225;
    var ref8=240;
    var ref9=255;
if(between(x2,115,270) && between(y2,205,236))
{
    if(x2>=135 && x2<=145){bend1=(x2-ref1)*(2.2);}
    if(x2<=135 && x2>=125){bend1=(x2-ref1)*(2.2);}

    if(x2>=150 && x2<=160){bend2=(x2-ref2)*(2.2);}
    if(x2<=150 && x2>=140){bend2=(x2-ref2)*(2.2);}

    if(x2>=165 && x2<=175){bend3=(x2-ref3)*(2.2);}
    if(x2<=165 && x2>=155){bend3=(x2-ref3)*(2.2);}

    if(x2>=180 && x2<=190){bend4=(x2-ref4)*(2.2);}
    if(x2<=180 && x2>=170){bend4=(x2-ref4)*(2.2);}

    if(x2>=195 && x2<=205){bend5=(x2-ref5)*(2.2);}
    if(x2<=195 && x2>=185){bend5=(x2-ref5)*(2.2);}

    if(x2>=210 && x2<=220){bend6=(x2-ref6)*(2.2);}
    if(x2<=210 && x2>=200){bend6=(x2-ref6)*(2.2);}

    if(x2>=225 && x2<=235){bend7=(x2-ref7)*(2.2);}
    if(x2<=225 && x2>=215){bend7=(x2-ref7)*(2.2);}

    if(x2>=240 && x2<=250){bend8=(x2-ref8)*(2.2);}
    if(x2<=240 && x2>=230){bend8=(x2-ref8)*(2.2);}

    if(x2>=255 && x2<=265){bend9=(x2-ref9)*(2.2);}
    if(x2<=255 && x2>=245){bend9=(x2-ref9)*(2.2);}
    }
}

function init(){//this function draws each hair/curve
    var canvas = document.getElementById('myCanvas');
    var context = canvas.getContext('2d');
    var clear=context.clearRect(0, 0,500,500);
    var save=context.save();

//   /* console.log("bend2="+bend2)
//    console.log("bend3="+bend3)
//    console.log("bend4="+bend4)
//    console.log("bend5="+bend5)
//    console.log("bend6="+bend6)
//    console.log("bend7="+bend7)
//    console.log("bend8="+bend8)
//    console.log("bend9="+bend9)*/

    hd1 = new hair();//hd1 stands for hair draw 1.this is an instance created for drawing hair no 1
    clear;
    hd1.draw_hair(0,0,0,0,0,0,0+bend1/2,0);//these parameters passed to function drawhair and bend is beint retrieved from function bend_value()
    save;

    hd2 = new hair();
    clear;
    hd2.draw_hair(15,0,15,0,15,0,15+bend2/2,0);
    save;

    hd3 = new hair();
    clear;
    hd3.draw_hair(30,0,30,0,30,0,30+bend3/2,0);
    save;

    hd4 = new hair();
    clear;
    hd4.draw_hair(45,0,45,0,45,0,45+bend4/2,0);
    save;

    hd5 = new hair();
    clear;
    hd5.draw_hair(60,0,60,0,60,0,60+bend5/2,0);
    save;
 }

window.onload = function() {
    init();
    disableSelection(document.body)
}

function disableSelection(target){
    if (typeof target.onselectstart!="undefined") //IE
        target.onselectstart=function(){return false}
    else if (typeof target.style.MozUserSelect!="undefined") //Firefox
        target.style.MozUserSelect="none"
    else //All other ie: Opera
        target.onmousedown=function(){return false}
    target.style.cursor = "default"
}

解决方案

Update: I'm currently adjusting the code to produce the requested result and commenting it.

(function() { // The code is encapsulated in a self invoking function  to isolate the scope
  "use strict";

   // The following lines creates shortcuts to the constructors of the Box2D types used
   var B2Vec2 = Box2D.Common.Math.b2Vec2,
      B2BodyDef = Box2D.Dynamics.b2BodyDef,
      B2Body = Box2D.Dynamics.b2Body,
      B2FixtureDef = Box2D.Dynamics.b2FixtureDef,
      B2Fixture = Box2D.Dynamics.b2Fixture,
      B2World = Box2D.Dynamics.b2World,
      B2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape,
      B2RevoluteJoint = Box2D.Dynamics.Joints.b2RevoluteJoint,
      B2RevoluteJointDef = Box2D.Dynamics.Joints.b2RevoluteJointDef;

  // This makes sure that there is a method to request a callback to update the graphics for next frame
  window.requestAnimationFrame =
    window.requestAnimationFrame || // According to the standard
    window.mozRequestAnimationFrame || // For mozilla
    window.webkitRequestAnimationFrame || // For webkit
    window.msRequestAnimationFrame || // For ie
    function (f) { window.setTimeout(function () { f(Date.now()); }, 1000/60); }; // If everthing else fails

  var world = new B2World(new B2Vec2(0, -10), true), // Create a world with gravity
      physicalObjects = [], // Maintain a list of the simulated objects
      windInput = 0, // The input for the wind in the current frame
      wind = 0, // The current wind (smoothing the input values + randomness)
      STRAW_COUNT = 10, // Number of straws
      GRASS_RESET_SPEED = 2, // How quick should the straw reset to its target angle
      POWER_MOUSE_WIND = 120, // How much does the mouse affect the wind
      POWER_RANDOM_WIND = 180; // How much does the randomness affect the wind

  // GrassPart is a prototype for a piece of a straw. It has the following properties
  //  position: the position of the piece
  //  density: the density of the piece
  //  target: the target angle of the piece
  //  statik: a boolean stating if the piece is static (i.e. does not move)
  function GrassPart(position, density, target, statik) {
    this.width = 0.05;
    this.height = 0.5;
    this.target = target;

    // To create a physical body in Box2D you have to setup a body definition
    // and create at least one fixture.
    var bdef = new B2BodyDef(), fdef = new B2FixtureDef();
    // In this example we specify if the body is static or not (the grass roots 
    // has to be static to keep the straw in its position), and its original
    // position.
    bdef.type = statik? B2Body.b2_staticBody : B2Body.b2_dynamicBody;
    bdef.position.SetV(position);

    // The fixture of the piece is a box with a given density. The negative group index
    // makes sure that the straws does not collide.
    fdef.shape = new B2PolygonShape();
    fdef.shape.SetAsBox(this.width/2, this.height/2);
    fdef.density = density;
    fdef.filter.groupIndex = -1;

    // The body and fixture is created and added to the world
    this.body = world.CreateBody(bdef);
    this.body.CreateFixture(fdef);
  }

  // This method is called for every frame of animation. It strives to reset the original
  // angle of the straw (the joint). The time parameter is unused here but contains the
  // current time.
  GrassPart.prototype.update = function (time) {
    if (this.joint) {
      this.joint.SetMotorSpeed(GRASS_RESET_SPEED*(this.target - this.joint.GetJointAngle()));
    }
  };

  // The link method is used to link the pieces of the straw together using a joint
  // other: the piece to link to
  // torque: the strength of the joint (stiffness)
  GrassPart.prototype.link = function(other, torque) {
    // This is all Box2D specific. Look it up in the manual.
    var jdef = new B2RevoluteJointDef();
    var p = this.body.GetWorldPoint(new B2Vec2(0, 0.5)); // Get the world coordinates of where the joint
    jdef.Initialize(this.body, other.body, p);
    jdef.maxMotorTorque = torque;
    jdef.motorSpeed = 0;
    jdef.enableMotor = true;

    // Add the joint to the world
    this.joint = world.CreateJoint(jdef);
  };

  // A prototype for a straw of grass
  // position: the position of the bottom of the root of the straw
  function Grass(position) {
    var pos = new B2Vec2(position.x, position.y);
    var angle = 1.2*Math.random() - 0.6; // Randomize the target angle

    // Create three pieces, the static root and to more, and place them in line.
    // The second parameter is the stiffness of the joints. It controls how the straw bends.
    // The third is the target angle and different angles are specified for the pieces.
    this.g1 = new GrassPart(pos, 1, angle/4, true); // This is the static root
    pos.Add(new B2Vec2(0, 1));
    this.g2 = new GrassPart(pos, 0.75, angle);
    pos.Add(new B2Vec2(0, 1));
    this.g3 = new GrassPart(pos, 0.5);

    // Link the pieces into a straw
    this.g1.link(this.g2, 20);
    this.g2.link(this.g3, 3);

    // Add the pieces to the list of simulate objects
    physicalObjects.push(this.g1);
    physicalObjects.push(this.g2);
    physicalObjects.push(this.g3);
  }

  Grass.prototype.draw = function (context) {
      var p = new B2Vec2(0, 0.5);
      var p1 = this.g1.body.GetWorldPoint(p);
      var p2 = this.g2.body.GetWorldPoint(p);
      var p3 = this.g3.body.GetWorldPoint(p);

      context.strokeStyle = 'grey';
      context.lineWidth = 0.4;
      context.lineCap = 'round';

      context.beginPath();
      context.moveTo(p1.x, p1.y);
      context.quadraticCurveTo(p2.x, p2.y, p3.x, p3.y);
      context.stroke();
  };

    var lastX, grass = [], context = document.getElementById('canvas').getContext('2d');

    function updateGraphics(time) {
      window.requestAnimationFrame(updateGraphics);

      wind = 0.95*wind + 0.05*(POWER_MOUSE_WIND*windInput + POWER_RANDOM_WIND*Math.random() - POWER_RANDOM_WIND/2);
      windInput = 0;
      world.SetGravity(new B2Vec2(wind, -10));

      physicalObjects.forEach(function(obj) { if (obj.update) obj.update(time); });
      world.Step(1/60, 8, 3);
      world.ClearForces();

      context.clearRect(0, 0, context.canvas.width, context.canvas.height);
      context.save();
      context.translate(context.canvas.width/2, context.canvas.height/2);
      context.scale(context.canvas.width/20, -context.canvas.width/20);
      grass.forEach(function (o) { o.draw(context); });
      context.restore();
    }

    document.getElementsByTagName('body')[0].addEventListener("mousemove", function (e) {
      windInput = Math.abs(lastX - e.x) < 200? 0.2*(e.x - lastX) : 0;
      lastX = e.x;
    });

    var W = 8;
    for (var i = 0; i < STRAW_COUNT; i++) {
      grass.push(new Grass(new B2Vec2(W*(i/(STRAW_COUNT-1))-W/2, -1)));
    }

    window.requestAnimationFrame(updateGraphics);
})();

这篇关于草像贝兹曲线平滑的动画?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆