【问题标题】:Canvas alternating shapes with gravity画布与重力交替形状
【发布时间】:2018-01-13 17:17:40
【问题描述】:

我有这个画布功能。任务:让形状在圆形和三角形之间交替。

我尝试更改 Draw 方法以显示下降的三角形,但我只能显示一个纯黑色三角形。但是没有重力作用于它。只有一个静态三角形。但是在我编辑绘图函数之前,相同的代码给了我许多随机和随机速度下降的圆圈。我似乎无法弄清楚为什么重力也没有应用于三角形。我觉得很奇怪,如果我在 draw 方法中添加一个 ctx.arc ,它会显示圆圈再次下降。我不确定三角形有什么区别。

Codepen:https://codepen.io/stefanomartinengo/pen/XVqapL

代码:

var canvas, ctx;
class SuralinkApplicationFX
{    
constructor()
{
    this._frame = 0;
    this._canvasInitted = false;
    this._shapes = [];
    this.InitCanvas();
    this.Render();
}

InitCanvas()
{
    this._canvasInitted = true;
    canvas = document.getElementById('theCanvas'),
    ctx = canvas.getContext('2d');
    canvas.setAttribute('width', window.innerWidth);

    this.DropShapes();

    window.requestAnimationFrame(() => this.Render());
}

DropShapes()
{
    if(this._shapes.length <= 0) window.requestAnimationFrame(() => 
this.Render());

    var howManyToDrop = getRandomInt(1,12);

    for(var xIt=1; xIt<=howManyToDrop; xIt++)
    {
        var shape = new Circle(
             getRandomInt(0,parseInt(canvas.getAttribute('width'))),
             0,randomColors(),
             randomNumFrom(0.15,0.65),randomNumFrom(0.05,1.45),
             randomNumFrom(2,20));
        this._shapes.push(shape);

    }

    setTimeout(() => this.DropShapes(),getRandomInt(350,950));
}

Render()
{

    if(this._canvasInitted == true)
    {

        this._frame++;
        this._can_w = parseInt(canvas.getAttribute('width')),
        this._can_h = parseInt(canvas.getAttribute('height')),

        ctx.clearRect(0, 0, this._can_w, this._can_h);

        this.UpdateShapes();
        this.DrawShapes();
    }

    if(this._shapes.length > 0) window.requestAnimationFrame(() => 
this.Render());
}

DrawShapes()
{
    this._shapes.forEach(function(shape){
  shape.Draw();
    },this);
}

UpdateShapes()
{
    this._shapes.forEach(function(shape,idx){
        shape.ApplyGravity();
    },this);
}
}

class Shape
{
constructor(type,x,y,color,alpha,gravity)
{
    this._type = type;
    this._x = x;
    this._y = y;
    this._color = color;
this._gravity = gravity;
    this._alpha = alpha;
}

get type() { return this._type; }
get x() { return this._x; }
get y() { return this._y; }

ApplyGravity()
{
    this._y += this._gravity;
}

Draw() { 
}
}

class Circle extends Shape
{
constructor(x,y,color,alpha,gravity,radius)
{
    super("circle",x,y,color,alpha,gravity);
    this._radius = radius;      
 }

 Draw()
 {
  ctx.fillStyle = 'rgba('+this._color+','+this._alpha+')';
        ctx.beginPath();
        ctx.arc(this.x, this.y, this._radius, 0, Math.PI*2, true);
        ctx.closePath();
        ctx.fill();
}
}

function getRandomInt(min, max)
{
return Math.floor(Math.random() * (max - min + 1)) + min;
}

function randomNumFrom(min, max)
{
return Math.random()*(max - min) + min;
}

function randomColors() {
return 

`${Math.round(randomNumFrom(0,255))},
 ${Math.round(randomNumFrom(0,255))},
 ${Math.round(randomNumFrom(0,255))}`
 }

var suralinkAppFx = new SuralinkApplicationFX();

我尝试了什么:

 class Circle extends Shape
{
   constructor(x,y,color,alpha,gravity,radius)
{
    super("circle",x,y,color,alpha,gravity);
    this._radius = radius;      
}
 DrawT() {
  ctx.beginPath();
  ctx.moveTo(75, 50);
  ctx.lineTo(100, 75);
  ctx.lineTo(100, 25);
  ctx.fill();
}
}

【问题讨论】:

  • 您是否介意将提供的源代码转换为可工作的 sn-p 或 JsFiddle?谢谢。
  • 这里是:codepen.io/stefanomartinengo/pen/XVqapL @NewToJS

标签: javascript function object canvas constructor


【解决方案1】:

您没有使用形状位置。简单修复如下

  DrawT() {
    // set position via transform
    ctx.setTransform(1,0,0,1,this._x,this._y);
    ctx.beginPath();
    ctx.moveTo(-12, 0);
    ctx.lineTo(13, 25);
    ctx.lineTo(13, -25);
    ctx.fill();
    // reset the transform (or better yet after all drawn)
    ctx.setTransform(1,0,0,1,0,0);
  }

您在影响整体性能的代码风格方面也存在许多问题。如果没有适当的测试,感觉它的速度太慢了 10 倍。

【讨论】:

  • 成功了!但是,我不确定我是否了解 setTransforms 发生了什么。我的下一步是随机化下降的三角形的形状。你能解释一下 setTransform 相对于 moveTo、lineTo 和其他 lineTo 的作用吗? @盲人67
  • @GaelicLaic 设置转换很复杂,没有评论空间来充分解释。 developer.mozilla.org/en-US/docs/Web/API/… 可能会有所帮助,但就个人而言,这就像泥浆一样清澈。快速版setTransform(a,b,c,d,e,f) a,b 是像素顶部的方向和大小 (1,0),c,d 是像素左侧的方向和大小 (0,1)。 e,f 是原点 (0,0) 的像素位置。
  • 谢谢!超级有帮助。所以我尝试在三角形不同点的 x,y 上放置一个方法,它导致随机大小在它们下降时不断变化,而不是在创建时只变化一次。在什么时候呈现形状。我试图弄清楚在哪里设置新大小,而不是每毫秒重新渲染一个新的随机数,或者它渲染的频率有多高。 – Gaelic Laic 8 分钟前 @Blindman67
猜你喜欢
  • 1970-01-01
  • 2013-11-20
  • 2011-09-21
  • 2014-03-02
  • 2018-07-21
  • 2023-04-03
  • 1970-01-01
  • 2017-11-15
  • 2018-07-08
相关资源
最近更新 更多