Making multiple p5js canvas responsive

I think a lot of people would have already encounter this problem but most of them were not able to solve this. Here, I am discussing a special case where canvas is some fixed size for example 300x200 and append to a div container with an Id of #mycanvas.

There are few things I want to be done in terms of making canvas responsive

  1. Make canvas fit into a div atleast width or height wise.
  2. Make canvas adjust to fit in the div as the div size grow smaller or larger based on the device screen size.

Right now the solution I have works perfectly when I run it on full screen canvas which I don't want. Other part is I am using multiple canvas in different divs and want to make all of them responsive according to the screen size.

For example, I have three rows with 4 column each where each column contains one canvas. These canvas need to be fit inside the divs so that when the screen changes they should just adjust themselves to fit in the div.

Answers

  • edited March 2017

    @GoToLoop Thanks for the reply man :) But as I have already mentioned that resizing full screen canvas is no problem. I have problem resizing the canvas that is residing inside a div which has the 20% height and 20% width of device display. WindowResize() and resizeCanvas() works only when you have full screen sketch.

    About the Element/size can you explain? There is no example as such to understand the usage.

    Let me try to explain it again - as you see in the picture below the whole webpage is divided into tiles each tile is div container with unique id. These div has width and height defined in percentage so that they can adjust to the full screen of different screen sizes, basically responsive layout.

    Now when we create sketch, we have to give it a size such as 300X300 which is fixed and they don't fit in these divs beautifully. On large screen they look smaller and small screen they float out of the div and messed up the layout. What I am trying to do is to make these canvas resize according to the divs as they change.

    I hope I have been cleared enough.

  • Answer ✓

    This post might help...

    If maintaining aspect ratio is a problem there are established CSS patterns for maintaining it with video that can be applied to canvas.

    What we can't help with is the performance impact of running that many sketches within a single browser window :P

  • edited March 2017

    @blindfish this is exactly I was looking for, Thanks Man. About running multiple sketches on the same page could bring performance issues but I read somewhere that when we use instance based canvas it helps optimizing the performance ...

  • edited March 2017

    ... when we use instance based canvas it helps optimizing the performance ...

    Nope, all instances are run by the same page thread! 3:-O
    In order to run on diff. threads we need <iframe> for each sketch: *-:)

    1. https://forum.Processing.org/two/discussion/17306/multiple-canvases-on-one-page
    2. https://forum.Processing.org/two/discussion/18859/running-p5-js-in-google-sites
    3. http://ThimbleProjects.org/gotoloop/127477/
  • @blindfish @GoToLoop can you tell me why this isn't working -

         el.windowResized = function() {
                var divW = $('#canvas_eight').width();
                var divH = $('#canvas_eight').height();
                console.log(divW + " " + divH);
                el.resizeCanvas(divW, divH);
                el.setup();
            };
    

    @GoToLoop thanks for clarifying the stuff :) :)

  • edited March 2017

    @GoToLoop @BlindFish

    Here is the demo project that you can download and run on your system. Files Do let me know if you are able to download.

    I would extend this question a little bit more to describe other problems that I am facing now.

    1. Inside setup I have used this but the canvas size is not according to the div size. How do I know this? Well, When I try to use my mouse to move the ellipse or rectangle on the screen on any sketch, they are off from the mouse cursor. It means the canvas is stretching which is clearly visible in case of ellipse. Why the canvas is not taking the size of the div?

      el.setup = function() {
              var divW = $('#canvas_one').width();
              var divH = $('#canvas_one').height();
              console.log(divW +  " " + divH);
              el.createCanvas(divW, divH);
        };
      
    2. On window resize it is also not taking div width or height. Please suggest what can be done.

      el.windowResized = function() {
             var divW = $('#canvas_eight').width();
             var divH = $('#canvas_eight').height();
             console.log(divW + " " + divH);
             el.resizeCanvas(divW, divH);
             el.setup();
         };
      

    @GoToLoop the original question was to make the div responsive inside the divs. The responsiveness works great when the sketch is full screen but when it comes to multiple divs, it didn't work which @BlindFish has solved the problem but now I have other problems which I have mentioned above. :) :) :)

    Below is the one demo sketch --

        var one = function(el) {
    
    
            el.setup = function() {
                var divW = $('#canvas_one').width();
                var divH = $('#canvas_one').height();
                console.log(divW +  " " + divH);
                el.createCanvas(divW, divH);
            };
    
            el.draw = function() {
                el.background(0);
                el.fill(255);
                el.ellipse(el.mouseX, el.mouseY, 50, 50);
            };
        };
    
        var myone = new p5(one, "canvas_one");
    
  • Answer ✓

    So here is the deal with your code -

    change the CSS to this -

        .col-md-3,
        .col-sm-3,
        .col-xs-3 {
            padding-left: 0px!important;
            padding-right: 0px!important;
        }
    
        .canvas {
            width: 100%;
            height: 100%;
        }
    
        .canvas canvas {
            /*    width: 100%!important;
            height: 100%!important;*/
            margin: auto;
            position: absolute;
            top: 0;
            left: 0;
            bottom: 0;
            right: 0;
            border-style: 1px solid black;
        }
    

    Your complete code - here

Sign In or Register to comment.