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 element gets positioned 'absolute' and loses it predefined position. #15

Closed
ghost opened this issue Feb 24, 2011 · 9 comments
Closed

Comments

@ghost
Copy link

ghost commented Feb 24, 2011

I use this to create a new canvas element:
fabricCanvas = new fabric.Element('canvasHTMLElementId');

After initialization the canvas css style attribute 'position' is set to 'absolute' and its 'top' and 'left' attribute to 0. Why? The result is that my element is placed at the left-top corner of the document!

Further I'm confused about that you are wrapping the canvas element in an div container and adding TWO further identical elements. My code results in this:

<div class="canvas_container" style="width: 738px; height: 80px; -moz-user-select: none;">
     <canvas class="canvas-container" width="738" height="80" style="width: 738px; height: 80px; position: absolute; left: 0pt; top: 0pt; -moz-user-select: none;"></canvas>
     <canvas class="canvas-container" width="738" height="80" style="width: 738px; height: 80px; position: absolute; left: 0pt; top: 0pt; -moz-user-select: none;"></canvas>
     <canvas id="canvasHTMLElementId" width="738" height="80" style="position: absolute; width: 738px; height: 80px; left: 0pt; top: 0pt; cursor: default;"></canvas>
</div>

I've played around with firebug and found out that if you add a "position: relative;" to the style of the <div> container at least my canvas is positioned correctly and RELATIVE to the position of the <div>. It then is at the position I've defined in my CSS file.

Please fix this. I can't use fabric.js with this bug.
I'm using Ubuntu 10.10 and Firefox 4.0.

Thanks a lot!
Lufti

@ghost
Copy link
Author

ghost commented Feb 24, 2011

Same in current Chrome 9.0.597.94 (73967) Ubuntu 10.10

@ghost
Copy link
Author

ghost commented Feb 24, 2011

Why did you close this issue?

@ghost
Copy link
Author

ghost commented Feb 24, 2011

I don't understand how I can provide a patch, sry. So I do it on this way:

  1. Go to this line:
    https://github.com/kangax/fabric.js/blob/gh-pages/src/element.class.js#L311
  2. add following line as next line after the specified one:
    position: 'relative',

Now it's working in ff4 and chrome. Can't test in other browsers.

@kangax
Copy link
Member

kangax commented Mar 17, 2011

Thanks, this was part of some old cruft and I've been meaning to revamp it for a long time. Now fixed in 4046084

@nanodocumet
Copy link

Sorry to open an old discussion. I think the best way is to try to mimic whatever the original element was set for, thus, from latest source (https://github.com/kangax/fabric.js/blob/master/src/canvas.class.js#L318) change:

    position: 'relative'

to:

    position: this.upperCanvasEl.style.position || 'relative'

This way, if the original element had explicitly said to be 'absolute' or anything else it will take it from there and default to relative. In my case, I had my canvas element set to absolute, but when the object was created, my canvas was not displayed because it was out of my visible display (position was set to 'relative').

In addition, I think the div "canvas-container" should try to clone as much information as possible about the original canvas element with regards to style, however, thus probably an issue by itself.

Thanks,

Nano.

@kangax
Copy link
Member

kangax commented Nov 9, 2011

Yeah, that's definitely the issue. I've been thinking about this, and I see it as a general issue with DOM scripting/styling at the moment — you can't easily copy styles from one element onto another.

The use case is simple — and is exactly what's happening here — fabric needs to take existing canvas element and wrap it into a container. It does this because of another canvas element that's supposed to be positioned exactly at the same spot as original canvas element (as you know, there's lower canvas and upper canvas — for performance reasons).

So container serves as a relatively positioned wrapper, and it keeps both absolutely positioned canvas elements within it at the same spot, exactly on top of each other. If only we could tell one canvas element to always stay at the same position as another canvas element, or fully copy style of canvas element to its wrapper, the problem would be solved.

The reason I can't change that line as you suggest is because element has to be relative or absolute -positioned so that it would be a "containing block" of inner canvas elements. What if canvas element's style is "static"? And even if it's not static, what if it's defined in stylesheet (not in style attribute) and so is not retrievable from style alone?

Maybe something like:

var canvasPosition = getStyle(this.upperCanvasEl);
...
position: (canvasPosition === 'relative' || canvasPosition === 'absolute') 
  ? canvasPosition 
  : 'relative';
...

@nanodocumet
Copy link

I see what you are saying.

In this case is working for me because the style of the upperCanvasEl was explicitly set to absolute when the canvas was created, but I thought it was coming from my class definition. If we implement what I mentioned, everything will be back to absolute positioning.

The original position of the canvas element will need to be obtained before any styling is set to the upperCanvasEl, before this line:

https://github.com/kangax/fabric.js/blob/master/src/canvas.class.js#L99

Otherwise we will be getting the new values after the necessary canvas layers are created (which will be absolute position).

From your code, which getStyle function are you referring to? I only see fabric.util.setStyle and a function getStyle under the cufon part.

And as you said, the canvas-container should be either relative or absolute only.

Thanks!

@kangax
Copy link
Member

kangax commented Nov 9, 2011

I was talking about hypothetical getStyle :) There's none in fabric probably because there was no need for it until now. Shouldn't be hard to add one.

@nanodocumet
Copy link

You are the master! pretty sure can be done. I have been totally spoiled by jquery :). I created another issue with regards to the width and height for the canvas element, which probably can also take advantage of that.

BTW, thanks for the great library!

birdage pushed a commit to birdage/fabric.js that referenced this issue Jun 19, 2018
fixes issues
- issue fabricjs#9
- issue fabricjs#10
- issue fabricjs#15
birdage pushed a commit to birdage/fabric.js that referenced this issue Jun 19, 2018
**0.4.0** New Features and fixes
    - Fixes
    -- Upgraded to latest packages (thanks @fjogeleit)
    -- Fix for undo/redo (thanks @pomelyu)
    -- Issue fabricjs#9 fixed
    -- Issue fabricjs#10 and fabricjs#15 you can no longer give dataUrl as value only as background image and/or by adding the image as an object
    - Breaking Changes
    -- `data` and `dataType` properties have been replaced with `value` and `defaultValue`
    to be able to use the component as controlled component
    -- node support of 6,7 and 8
    - New Features
    -- ability to add an image as object
This issue was closed.
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

2 participants