【问题标题】:P5 try to factorize Graphics and Canvas codeP5 尝试分解图形和画布代码
【发布时间】:2020-10-30 23:47:04
【问题描述】:

我想分解用于在图形或标准画布中绘制相同内容的代码。
(在我的真实程序中,我希望在构建时给出的某些上下文中绘制自己的自治类)
我无法从画布中找到一些可以匹配除线条之外的图形指令的等效项。
在下文中,我尝试将画布或图形对象赋予绘图方法 someDraw ,但画布上只出现线条,而整个绘图出现在图形中。


let canvas;
let myGraph;

function setup() {
    canvas = createCanvas(200,300,WEBGL);
    canvas.parent('sketch-div');
    myGraph = createGraphics(200,300,WEBGL);
    stroke('red');
    noFill();
    noLoop();
}

function draw(){
    // direct draw on canvas / doesn't work correctly
    someDraw(canvas);
    // indirect draw on graphics, then show image 
    someDraw(myGraph);
    // show result
    image(myGraph,100,100);
}

function someDraw(pg){
 pg.clear();
 pg.background(color(0,0,200));

  // as webgl set 0,0 upper left 
 pg.translate(-pg.width/2, -pg.height/2);
 pg.stroke('red');
 pg.line(0,0,100,50);
 pg.rect(0,0,60,60);
 pg.ellipse (25,50,50,100);
}

您可以看到画布中绘制的(红色)线,但看不到矩形或椭圆。图形是正确的。

另一个效果:如果这个小程序循环(参见设置中的 noLoop()),图形第一次出现转瞬即逝,然后不再显示。

所以,画布和图形不在同一个层次结构中,但是有没有一种通用的方法可以在不复制所有代码的情况下在两者上进行绘制?

【问题讨论】:

    标签: javascript canvas processing p5.js


    【解决方案1】:

    使用Instantiation:

    var sketch = function( p ) {
        
        let canvas;
        let myGraph;
    
        p.setup = function() {
            canvas = p.createCanvas(200,300, p.WEBGL);
            canvas.parent('sketch-div');
            myGraph = p.createGraphics(200,300,p.WEBGL);        
            p.noLoop();
        }
    
        p.draw = function(){
            // [...]
        }
    }
    
    var test_3d = new p5(sketch);
    

    将 p5 实例传递给someDraw

    someDraw(p);
    

    或 p5.Renderer 对象:

    someDraw(myGraph);
    

    完整示例:

    var sketch = function( p ) {
        let canvas;
        let myGraph;
    
        p.setup = function() {
            canvas = p.createCanvas(200,300,p.WEBGL);
            canvas.parent('sketch-div');
            myGraph = p.createGraphics(200,300,p.WEBGL);        
            p.noLoop();
        }
    
        p.draw = function(){
            // direct draw on canvas / doesn't work correctly
            someDraw(p);
            // indirect draw on graphics, then show image 
            someDraw(myGraph);
            // show result
            p.image(myGraph,100,100);
        }
    
        function someDraw(pg){
            pg.clear();
            pg.background(pg.color(0,0,200));
            // as webgl set 0,0 upper left 
            pg.translate(-pg.width/2, -pg.height/2);
            pg.stroke('red');
            pg.noFill();
            pg.line(0,0,100,50);
            pg.rect(0,0,60,60);
            pg.ellipse (25,50,50,100);
        }
    }
    
    var test_3d = new p5(sketch);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.0.0/p5.min.js"></script>
    <div id="sketch-div"></div>

    【讨论】:

    • 感谢样品。它与 noLoop() 一起工作得很好: 两个奇怪的事情: 1) 如果 loop() 图形只是一次正常并且没有出现。这可以通过if (p.frameCount == 1 ) someDraw(myGraph); 2) 进行验证,如果您评论 //someDraw(p),图形将不起作用,这似乎意味着两者之间存在一些依赖关系。 ??????
    • @pirla 为什么大家觉得问题可以在评论区展开。这不是聊天 - 1 个问题和 1 个或多个答案。我已经很好地回答了你的问题。这是一个新问题,所以Ask a new public question。无论如何,您必须创建一个新的 p5.Renderer 对象。将myGraph = p.createGraphics(200,300,p.WEBGL); 移动到draw 即可。
    【解决方案2】:

    在探索了以前的解决方案之后,我学到了两件事:

    • 不强制执行实例化(尽管这可能是一个很好的做法):默认是当前窗口,可通过“this”访问。
    • 如果循环时第一次尝试没有出现图形,这是因为图形中的每个循环都没有重置坐标原点。(参见source core\p5.Graphics.js function draw())

    下面给出了一个从前面派生的解决方案。看看push()/pop()围绕图形的调用

    let myGraph;
    
    function setup() {
      myGraph = createGraphics(100, 100, WEBGL);
      canvas = createCanvas(200, 200, WEBGL);
      frameRate(0.5);
    }
    
    function draw() {
      // coordinates of window are reset at each draw.   
      translate(-width / 2, -height / 2);
      someDraw(this);
      // graphics coordinates cumulate at each draw.Protect:
      myGraph.push();
        myGraph.translate(-myGraph.width / 2, -myGraph.height / 2);
        someDraw(myGraph);
      myGraph.pop();
    
      // draw myGraph on canvas
      image(myGraph, 100, 100);
    }
    
    function someDraw(pg) {
      pg.clear();
      pg.background('blue');
      // origin will be now restored in main draw
      translate(10, 10);
      pg.stroke('red');
      pg.noFill();
      pg.line(0, 0, 100, 100);
      pg.rect(0, 0, 60, 60);
      pg.ellipse(25, 50, 50, 50);
    }
    

    【讨论】:

      猜你喜欢
      • 2023-01-19
      • 2021-09-12
      • 2021-08-24
      • 2022-01-10
      • 1970-01-01
      • 1970-01-01
      • 2018-03-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多