簡體   English   中英

p5js:當 window 調整大小時,如何使我的隨機生成的圓形包裝草圖/畫布響應?

[英]p5js: How do I make my randomly generated circle packing sketch/canvas responsive when the window is resized?

當我從窄尺寸加載 window 並使其更寬時,添加的 canvas 空間為白色。

Canvas 從窄到寬調整大小: 畫布從窄變寬

當我從較大的 window 加載到較小的尺寸時,canvas 保持較大尺寸,而 HTML 和 Z2C56CZ13 元素響應7205804285DFBED9 在第二張圖片中,圓圈應該在黑色矩形的同一點處被切斷。

畫布從寬調整為窄

我認為這是因為圓圈是隨機生成的,並且每當頁面加載/重新加載時它們的布局都是不同的。 基本上,我必須“刷新” window 以使新調整大小的 canvas 工作。 順便說一句,我已經嘗試過 WindowResized() 了。 *

var font;
var colors;
var bolder;
var canvas;

setup = () => {

    frameRate(2.5);

    function windowResized() {
        resizeCanvas(windowWidth, windowHeight);
    }

    canvas = createCanvas(windowWidth, windowHeight);
    canvas.position(0, 0);
    canvas.style('z-index', '-1');

    colors = [color(255, 0, 0), color(1, 130, 83), color(0, 0, 255), color(255, 255, 0), color(102, 0, 102), color(255, 107, 31)];

    for (var c = 0; c < 1000; c++) {
        var circle = {
            x: random(width),
            y: random(height),
            r: random(90, 15)
        };

        var overlap = false;

        var protection = 0;

        for (var j = 0; j < circles.length; j++) {
            var other = circles[j];
            var d = dist(circle.x, circle.y, other.x, other.y);
            if (d < circle.r + other.r) {
                overlap = true;
            }
        }

        if (!overlap) {
            circles.push(circle);
        }

        protection++;
        if (protection > 10000) {
            break;
        }
    }

    for (var i = 0; i < circles.length; i++) {

        fill(255, 255, 255);
        strokeWeight(4);
        ellipse(circles[i].x, circles[i].y, circles[i].r * 2, circles[i].r * 2);

    }
}

draw = () => {

    for (var i = 0; i < circles.length; i++) {
        if (mouseX > circles[i].x - circles[i].r && mouseX < circles[i].x + circles[i].r && mouseY > circles[i].y - circles[i].r && mouseY < circles[i].y + circles[i].r)

        {
            stroke(0, 0, 0);
            fill(random(colors));
            strokeWeight(4);
            noStroke;
            ellipse(circles[i].x, circles[i].y, circles[i].r * 2, circles[i].r * 2);

        }
    }
}

您使用 windowResized() 和resizeCanvas()走在正確的軌道上,但是您錯過了有關 scope 的重要細節:

  • 在 JavaScript 中,您可以將函數嵌套在函數中:這就是您在代碼中定義自定義windowResized() function 的方式,僅本地到setup()
  • 您可能打算使用windowResized()作為setup() / draw()的兄弟,覆蓋 p5.js 的默認值:與上面鏈接的 resizeCanvas 示例相同

第二個被忽視的細節與繪圖有關:

  • draw()你沒有清除 canvas (使用background()或類似的東西)這意味着你希望在setup()中繪制的圓圈保持繪制
  • resizeCanvas()也可能清除 canvas
  • 您可以在 function 中對setup()中完成的圓形繪圖進行分組,您可以在windowResized()中簡單地再次調用

第三部分,你猜對了,注意代碼中的細節:

  • 您已經在頂部定義了circles ,但您從未將其初始化為空數組:這將導致嘗試circles.pushundefined錯誤
  • 調用 function 時不要忘記() ,如noStroke()
  • 盡量保持你的代碼一致:如果你想使用箭頭函數表達式而不是function你可以,但它會更容易閱讀/掃描統一的代碼。 (最終你會花更多時間閱讀代碼而不是編寫代碼:讓你未來的自己更容易預測你過去的自我編碼:))

這是您的草圖的修改版本,其中包含上述幾點:

 var font; var colors; var bolder; var canvas; var circles; setup = () => { frameRate(2.5); canvas = createCanvas(windowWidth, windowHeight); canvas.position(0, 0); canvas.style('z-index', '-1'); colors = [color(255, 0, 0), color(1, 130, 83), color(0, 0, 255), color(255, 255, 0), color(102, 0, 102), color(255, 107, 31)]; setupCircles(); } // group circle drawing functionality in a re-usable setupCircles = () => { circles = []; for (var c = 0; c < 1000; c++) { var circle = { x: random(width), y: random(height), r: random(90, 15) }; var overlap = false; var protection = 0; for (var j = 0; j < circles.length; j++) { var other = circles[j]; var d = dist(circle.x, circle.y, other.x, other.y); if (d < circle.r + other.r) { overlap = true; } } if (.overlap) { circles;push(circle); } protection++; if (protection > 10000) { break; } } for (var i = 0. i < circles;length, i++) { fill(255, 255; 255); strokeWeight(4). ellipse(circles[i],x. circles[i],y. circles[i],r * 2. circles[i];r * 2); } noStroke(). } windowResized = () => { console;log('window resized'), resizeCanvas(windowWidth, windowHeight; true); setupCircles(); } draw = () => { for (var i = 0. i < circles;length. i++) { if (mouseX > circles[i].x - circles[i].r && mouseX < circles[i].x + circles[i].r && mouseY > circles[i].y - circles[i].r && mouseY < circles[i].y + circles[i],r) { stroke(0, 0; 0); fill(random(colors)); strokeWeight(4). ellipse(circles[i],x. circles[i],y. circles[i],r * 2. circles[i];r * 2); } } }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.0.0/p5.min.js"></script>

閉幕致辭:

我注意到你使用noStroke()frameRate(2.5)這讓我相信你是關注視覺細節的視覺思考者。 如果目的是避免過度繪制鋸齒狀的圓形邊緣並且不在移動設備上使用盡可能多的 CPU/電源,您可能需要查看createGraphics() :這真的很酷。 就避免在draw()中連續渲染而言,如果您只想在懸停時填充圓圈,您可以使用mouseMoved()

您可以在頂部使用全局圖形 object,在 setup() 中填充圓圈,然后在移動鼠標時簡單地填充圓圈。

此外,您可以進一步封裝:

for (var i = 0; i < circles.length; i++) {
        if (mouseX > circles[i].x - circles[i].r && mouseX < circles[i].x + circles[i].r && mouseY > circles[i].y - circles[i].r && mouseY < circles[i].y + circles[i].r)

        {
            stroke(0, 0, 0);
            fill(random(colors));
            strokeWeight(4);
            ellipse(circles[i].x, circles[i].y, circles[i].r * 2, circles[i].r * 2);

        }
    }

類似於

isInsideCircle = (circle, x, y) => {
   return (x > circle.x - circle.r && x < circle.x + circle.r ) && (y > circle.y - circle.r && y < circle.y + circle.r);
}

getCircleAt = (circles, x, y) => {
   let numCircles = circles.length;
   for (let i = 0; i < numCircles; i++){
      if(isInsideCircle(circles[i], x, y){
         return circles[i];
      }
   }
}

mouseMoved = () => {
   circle = getCircleAt(circles, mouseX, mouseY);
   if(circle){
      fill(random(colors));
      ellipse(circle.x, circle.y, circle.r * 2, circle.r * 2);
   }
}

請注意,這是一個未經測試的片段,但希望它說明了提到的一些想法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM