Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Canvas Size #9

Open
zolotas4 opened this issue Dec 11, 2013 · 14 comments
Open

Canvas Size #9

zolotas4 opened this issue Dec 11, 2013 · 14 comments

Comments

@zolotas4
Copy link

Right now the canvas width is explicitly set in source code. This should change and the canvas size should be set based on the width of the DIV element that contains it.

I've tried to make this change using Javascript, however, it doesn't work because the width of the DIV element is not explicitly set. The width of the DIV container is defined at runtime based on the span class that contains all the elements of the page (including the toolbox and the selected item properties). So, the following logic is not working:

theDiv = document.getElementById("divId");
theCanvas = document.getElementById("drawing");
theCanvas.width = theDiv.width;

If we explicitly set the DIV width then the above is working however, this is not what we want as again the width of the canvas will be hardcoded and not dynamically set based on the size of the client's screen.

@JoostvanPinxten
Copy link
Contributor

This is quite a common problem with web-pages and canvas based pages in specific; generally, i've found that the solution is something as follows:

  • Get the width of the window (on any resize event)
  • Subtract the static elements from it (e.g. the toolbar width, any padding inside the canvas div)

Also; have you tried to capture the calculated width (not the css-definition, like you are saying above) of the div with the width() method of jQuery? I.e.: $('#divId').width() should output the current (calculated) width in pixels.

@zolotas4
Copy link
Author

The first method you propose is what I've thought as the final solution. I think that this is a little bit of "hacking" so I'll will end up doing that if I can't find any other more straight solution.

I think that I tried the width() method but it didn't work. I'll try again because I am not sure.

@JoostvanPinxten
Copy link
Contributor

Does this fiddle work for you? It works for me in the latest Firefox on Windows!

@zolotas4
Copy link
Author

I can now get the width of the div dynamically but I can't assign it to the canvas width. What I am not sure about is when the "resizing" has to take place. e.g. onload or during any other event?

@JoostvanPinxten
Copy link
Contributor

Both, actually! Unless the resize event is triggered on rendering of the canvas div and element. I'd have to look up how the canvas inner size need to be changed to resize with, but it may also include setting some kind of parameters in the javascript; i.e. the paper.js canvas. Not sure about that, you could check out the paper.js demos and View reference!

@JoostvanPinxten
Copy link
Contributor

This concept shows how it works with a plain canvas, but it is slow somehow... There must be something I'm overlooking... It is, however, exactly as they have done in this (old?) tutorial

@zolotas4
Copy link
Author

I will read the old tutorial and I'll tell you if I have any progress...

@zolotas4
Copy link
Author

Just and update to that. I am not sure if this is correct programming, a hack or a workaround, but this is the only thing that works:

function fixSize() {
    //the 'drawing' in our project is the HTML5 canvas and the 'canvas' is the Div element
    theDrawing = document.getElementById("drawing");
    theDiv = document.getElementById("canvas");
    theDivInitHeight = $('#canvas').height();
    theDivInitWidth = $('#canvas').width();
    theDrawing.width = theDivInitWidth;
    theDrawing.height = theDivInitHeight;
    theDrawing.style.width = theDivInitWidth+"px";
    theDrawing.style.height = theDivInitHeight+"px";
}

I did that before but what I haven't done was to re-draw the canvas. So I thought that it didn't work. When I trigger the re-draw method (right now by drawing another element) the elements are shown resized. However, if I set the width and height properties of the 'drawing' only, the re-drawn elements appear stretched. I also have to set the CSS width and height values of the canvas to make the elements keep their initial ratio.

I face the following 2 problems right now:

  1. I don't know how to call the draw method from the views/drawing/show.eco file where all the above code is written. As I said, I tested it by drawing another element to force trigger the re-draw method.
  2. I can't add this function to the onload event of the views/drawing/show.eco template file. Inserting a tag doesn't work. Including a window.onload(fixSize()) in the script block is not working, too. I also tried writing $(fixSize()) which works but crashes the canvas.

@JoostvanPinxten
Copy link
Contributor

I'll try to setup Louis' new Grunt environment this weekend, I need to get back into my own code anyway. I'll also have a stab at it; there is a redraw mechanism, which I've added in my branch; Paper.js has one that can be easily called, but I cannot find it right now.

@zolotas4
Copy link
Author

Well I found it. It is as simple as that: paper.view.draw();
And it re-draws. Easy. Now, the only problem remaining is number 2...

@louismrose
Copy link
Owner

Hey chaps, thanks for your great work on this bug!

To answer your 2nd question Thanos, I think the best place for your code is in the render method of the Show class in controllers/drawings.coffee. From memory, I think it should work if you place it after the other code in render. You will want to convert it to coffeescript first (e.g., using http:https://js2coffee.org).

If that doesn't work, you might need to use window.setTimeout. We do this in palettes.coffee (see lines 113-122), because window on load and DOM ready don't work perfectly in Eugenia Live (because it's a single-page Javascript app).

HTH, and thanks again!

@JoostvanPinxten
Copy link
Contributor

@zolotas4 I agree with @louismrose on the 2nd solution
@louismrose I'd not classify this as a bug per sé, rather as a feature request ^^

@zolotas4
Copy link
Author

If I place it inside the render method the dynamic width of the div element is 0 and thus the width of the 'drawing' (the canvas is our case) is set to 0. The height which is not set dynamically, takes the correct value (400px). But if I implement it using the setTimeout Louis suggested, everything works fine. I've also finished the aesthetic part of this feature and I will upload the patch after some necessary testing that will reveal more problems....

@JoostvanPinxten
Copy link
Contributor

I've changed the constructor of the 'Show' controller class of the Drawings package.

  class Show extends Spine.Controller
    constructor: ->
      super
      # install our resize handler on the window:
      $(window).resize(@resize)
      @active @change

    resize: () =>
      containingDiv = $('#canvas');
      canvasHeight = containingDiv.height();
      canvasWidth = containingDiv.width();
      @log canvasHeight, canvasWidth
      if paper and paper.view
        paper.view.setViewSize(canvasWidth, canvasHeight)
        paper.view.draw()

And this works quite well, as far as I can see. One of the (possible) problems here, is that the updateDrawingCache will return images with different aspect ratios?

    updateDrawingCache: =>
      @drawing.cache = @canvas.toDataURL()
      @drawing.save()

As for @zolotas4 point 2, this has also popped up with this solution. I am not quite sure when the Bootstrap code adds the widths/percentages to the divs with the fluid classes, but that would be my guess for the source of this problem. @resize() at the end of @render does not get a calculated width yet...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants