【问题标题】:What is the best way to change p5.js canvas dynamically in the same webpage?在同一网页中动态更改 p5.js 画布的最佳方法是什么?
【发布时间】:2016-06-22 23:23:20
【问题描述】:

我正在尝试开发一个网页,让我只需从输入中选择一个选项即可更改 p5.js 画布和滑块配置。

这个想法是,每当我更改所选动画时,网页都会显示另一个在 html <head> 中定义的 skecth,在这种特殊情况下:

草图和草图 4 是有效的。

我还需要更改滑块的配置,因为 这取决于将要显示的不同滑块的草图。

现在。 我想到了两种方法

第一个是改变 src 属性使用另一个 javascript 文件 (sketchselector.js)。这是行不通的。它会更改 src,但页面不会重新加载以加载其他草图。

第二个是使用实例模式将每个草图定义为一个对象,我应该只在它更改选项时更改对象。实例模式的问题在于,如果我想制作大量动画,我将不得不每次都使用它,这让我的代码难以理解。

我想可能有很多方法可以做到这一点

因此我想知道最好的建议方法。

我期待收到你们的来信。

这是我一直试图让它工作的代码。

HTML

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title>Julito web page</title>
        
        <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
        <!-- jQuery library -->
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
        <!-- Latest compiled JavaScript -->
        <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
        
        
        
        <!-- P5.js !!!! -->
        <script src="libraries/p5.js" type="text/javascript"></script>
        <script src="libraries/p5.dom.js" type="text/javascript"></script>
        <script src="libraries/p5.sound.js" type="text/javascript" ></script>
        
        
        <script src="sketch.js" type="text/javascript" id='skecthselect'></script> 
        <script src="sketch4.js" type="text/javascript"></script> 
        <!--<script src="sketch5.js" type="text/javascript"></script> -->

        
        <!-- CSS -->
        <link rel="stylesheet" type="text/css" href="style.css"> 
    </head>
  
  
    <body>
        <div class="container-fluid"  >
            <div class="col-md-1 " style="background-color:blue"> </div>
            
            <div class="col-md-10 maincontent_jp" > 
                <div class="row header_jp" >
                
                    <div class="col-md-2"></div>
                    <div class="col-md-8 headertext_jp">
                        <h1 class="text-center"> Juli </h1>
                        <h3 class="text-center"> Multimedia explorer</h3>
                    </div>
                    <div class="col-md-2"></div>
                </div>
                
                <div class="row ">
                    <div class="col-md-1 "></div>
                    
                    <div class="col-md-10" id="sketchholder">
                    
                    
                        <div class="row" id="canvasholder" >
                        </div>

                        <div class="row" id="controladores" >
                            <div class="col-md-2"></div>
                            <div class="col-md-8">
                            
                                <div class="col-md-6" id="slid-controladores"></div>
                                <div class="col-md-6" id="slid-texto"></div>
                                
                            </div>
                            <div class="col-md-2"></div>
                        </div>
                    </div>
                    
                    <div class="col-md-1" ></div>
                </div>
                
                <select id='selector' onchange="ChangeSketch()" name="skecthselector" >
                                  <option value="skecth1.js">Animacion 1</option>
                                  <option value="skecth2.js">Animacion 2</option>
                                  <option value="skecth3.js">Animacion 3</option>
                                  <option value="skecth4.js">Animacion 4</option>
                </select>
                <p id='koko'> </p>
            </div>
            
            <div class="col-md-1 " > </div>
        </div>
        
        
        <script src="sketchselector.js" type="text/javascript" ></script> 
    </body>
</html>

草图 1

       //THIS IS A FUNCTION FOR DINAMYCALLY MAKE CANVAS FILL PAGE. 
        $( document ).ready(function() {
        
            var c=document.getElementById("cnv");
            var ctx=c.getContext("2d");
            ctx.beginPath();
            ctx.arc(95,50,40,0,2*Math.PI);
            ctx.stroke();
        });
    
    var RectOrEllipse = false;
    var boton ; 
    var cont = 0; 
    var pepito ; 
    var RedP;
    var GreenP;
    var BlueP;
    var OpacityP;
    var SizeP;
    var maxwidth;
    var canvheight = 500;
    
      function setup () {
          
      //CREATING THE CANVAS 
    maxwidth = document.getElementById('canvasholder').offsetWidth;
    var canvasDiv = document.getElementById('canvasholder');
    var sketchCanvas = createCanvas(maxwidth/1.2,canvheight);
    console.log(sketchCanvas);
    sketchCanvas.parent("canvasholder");
    
    slidred = createSlider(1,255,150);
    slidgreen = createSlider(1,255,150);
    slidblue = createSlider(1,255,150);
    slidopacity = createSlider(0,100,50);
    slidsize = createSlider(1,300,150);
    
    slidred.parent('slid-controladores');
    slidgreen.parent('slid-controladores');
    slidblue.parent('slid-controladores');
    slidopacity.parent('slid-controladores');
    slidsize.parent('slid-controladores');
    
    RedP = createP('Rojo:'+slidred.value());
    GreenP = createP('Verde: '+slidgreen.value());
    BlueP = createP('Azul: '+slidblue.value());
    OpacityP = createP('Opacidad:'+slidopacity.value())
    SizeP = createP('Tamaño: '+slidsize.value());
    pepe = createP('X'+ mouseX + 'Y' + mouseY);
    
    RedP.parent('slid-texto');
    GreenP.parent('slid-texto'); 
    BlueP.parent('slid-texto');
    OpacityP.parent('slid-texto');
    SizeP.parent('slid-texto');
    
  }

  function draw() {
    maxwidth = document.getElementById('canvasholder').offsetWidth;
    
   noStroke();
   
    
    col = color(slidred.value(),slidgreen.value(),slidblue.value(),slidopacity.value());
    fill(slidred.value(),slidgreen.value(),slidblue.value(),slidopacity.value());
    //boton.style("background-color", col);
    
    if ((mouseIsPressed) && (mouseY < canvheight)){
        
        ellipse(mouseX, mouseY, slidsize.value(),slidsize.value());
    }
    
    slidred.input(Actualizar);
    slidgreen.input(Actualizar);
    slidblue.input(Actualizar);
    slidopacity.input(Actualizar);
    slidsize.input(Actualizar);
    pepe.html('X'+ mouseX + 'Y' + mouseY + 'MAX WIDTH' + maxwidth);
  }
  
  function Actualizar() {
  
    RedP.html('Rojo:'+slidred.value());
    GreenP.html('Verde: '+slidgreen.value());
    BlueP.html('Azul: '+slidblue.value());
    OpacityP.html('Opacidad:'+slidopacity.value());
    SizeP.html('Tamaño: '+slidsize.value());
    
  }
  
$( document ).ready(function() {

    var c=document.getElementById("canvas");
    var ctx=c.getContext("2d");
    ctx.beginPath();
    ctx.arc(95,50,40,0,2*Math.PI);
    ctx.stroke();

});

草图 2

var ball = {
    x: 150,
    y: 150,
    xspeed:0.5,
    yspeed:-0.2,
    
    display: function(tamaño) {
        stroke(1);
        strokeWeight(1);
        noFill();
        ellipse(this.x,this.y,tamaño,tamaño);
    },
    
    bounce: function() {
        if (this.x > width || this.x < 0){
            this.xspeed = this.xspeed * -1;
        }
        if (this.y > height || this.y < 0){
            this.yspeed = this.yspeed * -1;
        }
    },
    
    move: function () {
    
    /*ball.xspeed = velocidad;
    ball.yspeed = velocidad;*/
    
    this.x = this.x + this.xspeed;
    this.y = this.y + this.yspeed;
    },
    
    createBall : function (){
        this.display();
        this.move();
       this.bounce();
    }
}
var i;  
function setup() {
    var sketchCanvas = createCanvas(300,300);
    sketchCanvas.parent("canvasholder");
}

function draw() {
    background('#F0F');
    
    //ball.createBall();
        ball.display(50);
        ball.move();
        ball.bounce();
}

添加:

嗯,我已经在实例模式下尝试过这个,但也无法正常工作。

我在一个 JavaScript 文件中定义了两个草图。当我打电话给他们时,他们工作得很好。问题是当我想选择一个而不是另一个。那是行不通的。

这里添加的代码:

function ChangeSketch() {
lala = document.getElementById('selector').value;
document.getElementById('koko').innerHTML = lala;  




/*new p5(sketch1, 'canv2');
    new p5(sketch1, 'canv1');*/
    
    function setup(){
    createP('TENGO MIEDO');
    new p5(sketch2);
    new p5(sketch1);
    }
     }

【问题讨论】:

    标签: javascript html canvas processing p5.js


    【解决方案1】:

    假设您有两个 JavaScript 文件:

    one.js

    function printOne(){
        console.log("one");
        setTimeout(printOne, 1000);
    }
    
    printOne();
    

    两个.js

    function printTwo(){
        console.log("two");
        setTimeout(printTwo, 1000);
    }
    
    printTwo();
    

    然后你在 index.html 中加载第一个:

    <!DOCTYPE html>
    <html>
        <head>
            <script id="MyJavaScript" src="one.js"></script>
        </head>
    
        <body>
        </body>
    </html>
    

    如果您保存这些文件,然后在网络浏览器中打开index.html,您会看到one 一遍又一遍地打印到控制台。

    现在我们希望能够将 JavaScript 从 one.js 更改为 two.js。所以让我们在 html 的body 中添加一个button

    <button onclick="changeMyJavaScript()">Click</button>
    

    我们可能会尝试通过简单地更改src 属性来更改它script 标签:

    function changeMyJavaScript(){
       var script = document.getElementById("MyJavaScript");
       console.log("old: " + script.src);
       script.src = "two.js";       
       console.log("new: " + script.src);
    }
    

    我们可能认为这是可行的,但one 只是一直打印到控制台!如果我们尝试手动调用printTwo(),我们会得到一个错误,说它没有定义。

    仅更改script 标记的src 属性不会运行新的src

    但是,我们可以改为创建一个新的script 标记并将其添加到DOM

    function changeMyJavaScript(){
        var newScript = document.createElement('script');
        newScript.type = 'text/javascript';
        newScript.src = "two.js"; 
        document.getElementsByTagName('head')[0].appendChild(newScript);
    }
    

    现在我们将看到two 开始打印到控制台。但是,我们仍然有一个问题:one 也继续打印到控制台。这是有道理的。我们实际上并没有告诉我们的代码停止打印one。请注意,从 DOM 中删除 script 标记不会执行任何操作。另请注意,如果我们多次单击按钮,我们会看到two 越来越频繁地打印到控制台。

    您如何处理这实际上取决于您的代码和 p5.js。我不确定 p5.js 是否提供“停止运行我的代码”功能,但我对此表示怀疑。您可能必须创建自己的停止函数,然后在激活新脚本之前调用它们。

    如果我是你,我会将所有代码保存在一个草图中,并在处理代码中切换。您还可以将 Processing 草图拆分为多个 JavaScript 文件并在开始时将它们全部加载,但仍然在 Processing 中进行所有切换。

    【讨论】:

    • 我将尝试在主程序中使用所有功能。我仍然没有找到一种方法来完成它的功能。但是当我完成后我会在这里发布。
    • 我已经做到了。我将每个动画创建为一个对象。然后我使用 Select html 元素来获取选项值。使用选项值,我告诉程序要在绘图函数中显示的对象
    • @Julián 你解决过这个问题吗?
    【解决方案2】:

    我有一个类似的问题,这个帖子启发我用这种方式解决它:

    sketch.js:

       var x, y;
        function setup() {
          createCanvas(400, 400);
          x = 0;
          y = 0;
        }
    
     function draw() {
          if(mouseIsPressed) {
            drawing1();
          } else {
            drawing2();
          }
        }
    

    drawing1.js:

    function drawing1() {
      fill(255, 0, 0);
      ellipse(x, y, 100, 100);
    }
    

    drawing2.js:

    function drawing2() {
      fill(0, 255, 0);
      ellipse(x, y, 50, 50);
    }
    

    然后在我的 index.html 中,只需在 sketch.js 的标签之前包含 draw1.js 和 drawing2.js 的 &lt;script&gt; 标签。我现在刚刚尝试过,效果很好——这是将大型 p5js 项目分解为较小部分的好方法。不错。

    【讨论】:

      【解决方案3】:

      除了现有的答案,您还可以查看p5.js overview 尤其是instantiation/namespace 部分。

      使用此处介绍的概念,您应该能够创建两个具有两个不同命名空间和容器的草图,并根据需要使用 loop()/noLoop() 暂停和恢复每个草图

      【讨论】:

        【解决方案4】:

        我一直在使用processing.js 将处理放入我的网络项目中,我想循环浏览不同的草图。 Processing.js 有一个 Processing.reload() 函数,这使得这非常容易。

        var sketches = ["sketchname1", "example", "test"];
        function nextSketch(){
                    var currentLoc = $.inArray($('#canvas').attr('name'), sketches);
                    currentLoc ++;
                    if(currentLoc >= sketches.length){
                      currentLoc = 0;
                    }
                    var htmlStr = '<canvas id="canvas" name="' + sketches[currentLoc] + '" data-processing-sources="' + sketches[currentLoc] + '.pde"></canvas>';
                    console.log(htmlStr);
            $('#canvas').replaceWith(htmlStr);
            Processing.reload();
        }
        

        这是我用来在草图之间交换的代码。我的 HTML 的相关部分看起来有点像这样:

        <canvas id="canvas" name="shape" data-processing-sources="sketch1.pde"></canvas>
        <button class="btn" onclick="nextSketch();"></button>
        

        【讨论】:

          猜你喜欢
          • 2022-08-23
          • 2017-02-13
          • 1970-01-01
          • 1970-01-01
          • 2012-01-10
          • 2016-09-17
          • 1970-01-01
          • 2016-01-13
          • 1970-01-01
          相关资源
          最近更新 更多