Changing position of canvas element parent div in css distorts drawing - javascript

I have a simple canvas drawing program that works perfectly.
But when I want to use it on my webpage I have to position it. I need canvas element to be inside 1 div element and i need to position that div element in css. When I do change position of parent div element my canvas window moves regularly but when I try to draw, mouse position of my cursor is not matching line on the screen.
I would like to know how to solve this problem and how to position my canvas window correctly where I want.
Here is canvas program that works(color buttons are not positioned well but nevermind).
HjD7e -> jsfiddle id
And here is the one that is messed up(cursor position is not matching)
S6Dhe -> jsfiddle id

Since you are now offsetting multiple elements, you'll need to take the new positions into account. Seeing as you are positioning the parent container, it might be easier to put all your positioning there and remove the extra positioning from the canvas itself. Using:
#contain{
position:absolute;
top:300px;
left:500px;
width: 400px;
height: 400px
}
instead. From there, change the code getting the positions to:
contain = document.getElementById('contain');
currX = e.clientX - contain.offsetLeft + window.scrollX;
currY = e.clientY - contain.offsetTop + window.scrollY;
also accounting for scrolling in the window.
The working fiddle is here. (Caveat, only tested in Firefox)

Related

Google Charts: tooltips have wrong position when inside a scrolling container

I'm using Google Charts (the Timeline in particular) and I am facing a weird issue.
When the timeline is placed inside a container that can scroll vertically, the bars' tooltip's vertical position is wrong if the container is scrolled.
Basically, the more you scroll the more the tooltip "drifts down", I've taken some screenshot to illustrate this:
Here is the tooltip when the container is not scrolled, the position is correct:
Now, let's scroll a bit, the tooltip vertical position starts to drift:
...and the more we scroll, the more it drifts:
I've tried reproducing this in JSfiddle but with no success, unfortunately the original code is quite complex and difficult to replicate as a simple example, but any suggestion on how to even approach this is welcome.
Well, while waiting for answers I developed this workaround:
//This instruction selects the internal div that actually shows the scrollbar
//The div is generated automatically by the Google library when you put the Timeline inside
//an element (#maincontainer in our case) that has a fixed height too small to fit the entire timeline
//It unfortuantely has no classes to make a more specific selector
let scrollElem = $(`#maincontainer > div > div:nth-child(1) > div > div`);
//We then monitor mouse movement on the scrollable div
scrollElem.on('mousemove', function( event ) {
//When mouse moves, we determine how much the container is scrolled vertically
let scrollAmnt = scrollElem.scrollTop();
//then we update a CSS style tag that forces the tooltip to a specific position
//Y-axis position = level with mouse pointer (= mouse Y-position relative to scrolling container - scroll amount)
//X-axis position = just to the right of the mouse pointer
$('#tooltip-style').text(`.google-visualization-tooltip{
top: ${event.offsetY - scrollAmnt}px !important;
left: ${event.offsetX + 15}px !important;
}`);
});
maybe not the prettiest of solutions, but works great.
I'll leave the question open for a few days to see if someone has a more "proper" solution.

Image resizes when position is changed to fixed on scroll

I would like an image to become fixed where it is once it appears on screen during a scroll, but become unfixed if the user scrolls back up.
However, when I use a JS on scroll function to change the image position to fixed, it suddenly "jumps"/resizes, and I'm not sure why. My fix was to create variables that alter the width and left values of the image after it becomes fixed, but I want to do this will multiple images on a page and each one seems to require a different width and left adjustment. I'm not sure what is conceptually causing this issue. Simply resetting the width and left to their original values does not work. Does a fixed position resize and image.
Here is a jsfiddle of the issue. And here is the code. JS:
var sitckyImageWidth = "38.4%";
var normalImageWidth = "48%";
document.addEventListener("scroll", function(){
var windowTop = $(window).scrollTop();
var windowWidth = window.innerWidth;
var windowHeight = window.innerHeight;
//loop through each div and grab top/bottom/midpoint info and find id
$('.articles').each(function(i){
var top = $(this).offset().top;
var bottom = top+ $(this).height();
var midPoint = (bottom+top)/2;
var thisId = this.id;
var newId;
//use container div info to find media info
var newId = thisId+"Media";
var sectionImage=document.getElementById(newId);
var sectionImageTop = $(sectionImage).offset().top;
//if article is on the page, change position to fixed and set top position
if (top<=windowTop&&bottom>windowTop){
$(sectionImage).css("top","10px")
$(sectionImage).css("position","fixed")
//$(sectionImage).css("width",sitckyImageWidth)
}
//if container is not at top of the page, return to relative
if (bottom<=windowTop||(bottom>windowTop&&top>windowTop)){
$(sectionImage).css("position","relative")
}
})
}); //end scroll
Position fixed means that an element will have relative sizes and positioning in relation to the viewport, not their parent elements.
Specifically what is happening here is that your div with ID article1Media is set to have a width of 48%. When it has the CSS property of position: relative then that resolves as 48% of the width of it's containing element (the div with id article1) however when it is position fixed that resolves as 48% of the width of the viewport. Since there is an implicit 8px margin on the <body> element then these are different.
There are a few different solutions to this, and how you tackle it depends on how you want to build your site.
Example fix 1
A simple fix for your immediate example is to simply add the following CSS.
body{
margin:0px;
}
.image{
margin:8px;
}
https://jsfiddle.net/Chipmo/k56qkk5b/13/
This moves the implicit margin onto the image element. Of course you can set it to whatever you like, or omit it entirely.
Look into CSS resets for more information about overriding implicit default styles, though be warned that it is possible to cause problems with overzealous reset codes.
( Edit: To be clear the above code is definitely not a drop in code for this problem everywhere. It will only work on quite simple HTML pages like your jsFiddle. )
Example fix 2
Another technique you could consider is locking the width and height to it's initial values using jQuery .width() and .height() functions. This would be inflexible, and you would have to do extra work to make it responsive (for mobile etc), but could be appropriate in some circumstances.
Example fix 3
A more portable solution might be to eschew relative sizing in favour of fixed widths and then use CSS media queries for reponsivity. Something like this:
.image{
width:500px;
}
#media(min-width:800px){
width:300px;
}
Example fix 4
If you wish to preserve the 'fluid' nature of using percentages I would suggest looking into using calc along with an offset that gets applied when the position is fixed (so, you add a class when you make the image fixed) that adjusts the sizing appropriately.
.media.image-fixed{
position:fixed;
width:calc(48% - 8px);
}
See this example https://jsfiddle.net/Chipmo/6mu2Lt9g/2/
Above behavior is observed since because of applying the position property not because of the scroll.Please take a look at the following link Position Properties
Position Fixed : Fixed position elements relative to document not on
any parent container.Hence occupies the complete width available.
Position Relative: Relative positioned elements behaves relative to hosted
containers.And inner elements consumes the hosted parent width.

Generate Margin-Top size depending on page location - Fixed Off Canvas

I'd like to have an element follow the user down the page, like a fixed position div, however this is not possible with the foundation Off Canvas Menu.
Is there a way to capture the distance that the page has scrolled in pixels and output it as the margin-top: style on a specific div?
Use window.scrollY to get the scrolled distance, then you could use jQuery:
$("#myElement").css("margin-top", window.scrollY);
or use plain JavaScript
document.getElementById("myElement").style.marginTop = window.scrollY;

Scrollable div (css + js)

I basically have one smaller div with overflow set to auto. Inside I have another, big div of the size of the grid and inside this div I have canvas element, that should have the size of the first smaller div.
What I want to achieve is to have the canvas always shown in the smaller div, no matter where I scrolled.
I set the position of canvas to relative and the top and left attributes are set as scrollTop and scrollLeft in javascript whenever I scroll. This way my canvas will have always fixed size ( no performance issues) and in javascript I can compute the position in which I am scrolled in.
var s=document.getElementById("scrollable");
var c=document.getElementById("canvas");
c.width=400;
c.height=400;
var maxw = s.scrollWidth;
var maxh = s.scrollHeight;
s.onscroll = function(){
c.style.top = s.scrollTop + "px";
c.style.left = s.scrollLeft + "px";
}
The problem I am having is that when I reach the end of scrolling, canvas seems to overflow the big div (thanks to size of the scrollbars I believe) and thus the big div's size is increasing and scrolling continues while it shouldn't.
Link to simple example: http://jsfiddle.net/kwynt/1/
I think you are right about the scrollbars causing the problem. they shrink the viewable area of your div, so the canvas is always overflowing over the right and bottom (since you keep moving the canvas down, you can never scroll all the way there). You can add this to your "wrap" div to fix:
overflow:hidden
http://jsfiddle.net/a3XPB/

Position element relative to page

I have this element, and i want to position it to specific coordinates on the page. The problem is that it's inside another positioned element, so position:absolute places it relatively to this element, while i want it to be placed relatively to the page.
Is there some way i can place an element at specific coordinates on the page?
You can see what i have on this page: http://bit.ly/NkfJk7 when you mouse over that yellow exclamation icon, i want the pink box to appear near that, but instead it appears in double that distance.
I figured it out, i was doing it wrong.
toolTip.style.left = button.offsetLeft + "px";
toolTip.style.top = button.offsetTop + "px";
No need to go absolute :)
You can use position: fixed for this
https://developer.mozilla.org/en/CSS/position
Fixed
Do not leave space for the element. Instead, position it at a specified position relative to the screen's viewport and doesn't move when scrolled. When printing, position it at that fixed position on every page.
EDIT: Disregard this answer. Position-fixed positions relative to the screen, so it will follow around it the page scrolls.

Categories

Resources