Positioning overlapping canvas - javascript

I've got a page that is supposed to display a line graph. There is a title at the top, the graph in the middle, then a table below them. It is laid out roughly like this:
<div>
<h1>Title</h1>
</div>
<div>
<canvas1></canvas>
<canvas2></canvas>
</div>
<div>
<table></table>
</div>
Right now each of the 'div' blocks are staying separate from each other, which is good. However, the two canvas's, despite having different z-index values, are next to each other instead of stacking on top. I've read that their position values should both be set to absolute, but whenever I do this, the table immediately moves on top of the canvas.
What position and display values do I need to set to the div's and the elements inside them to get the canvasses on top of each other (both are the same dimensions) without anything else stacking on top of their div?
Edit: Here's a fiddle

HTML:
Wrap the 2 canvases inside a wrapper div.
<div id="wrapper">
<canvas id="canvasBottom" width=300 height=200></canvas>
<canvas id="canvasTop" width=300 height=200></canvas>
</div>
CSS:
Position the 2 canvases at the same top & left relative to the wrapper div.
#wrapper{
position:relative;
width:300px;
height:200px;
}
#canvasTop,#canvasBottom{
position:absolute; top:0px; left:0px;
width:300px;
height:200px;
}

If you set the "position" attribute of your two canvas to "absolute", then the two canvas would stick to the parent element, say, your div.
The reason why the table moves on top of your canvas is that the table, in a sense, "neglected" your canvas and was located as if there is no canvas.
What you should do is keep the absolute position value of the canvas and set the "top" value of table to the height of your canvas, then the table would be just beneath the canvas.
let me give you an example:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Animal World</title>
<style>
canvas {
width: 50%;
height: 100px;
position: absolute;
}
#dog {
z-index: 1;
}
#cat {
z-index: 0;
background-color: blue;
}
table{
background-color: rgb(196, 255, 216);
position: relative;
top: 100px;
border-collapse: collapse;
}
caption{
font-weight: bolder;
font-size: 2em;
background-color: rgb(196, 255, 216);
border: 1px groove lightblue;
}
td,th{
border: 1px groove lightblue;
}
</style>
</head>
<body>
<div>
<h1>Animal</h1>
</div>
<div id = "canvas">
<canvas id = "dog"></canvas>
<canvas id = "cat"></canvas>
</div>
<script>
var dog = document.getElementById('dog');
var cat = document.getElementById('cat');
var dog_ctx = dog.getContext('2d');
var cat_ctx = dog.getContext('2d');
dog_ctx.fillStyle = "red";
dog_ctx.fillRect(20, 20, 20, 20);
</script>
<div class = "table">
<table>
<caption>Animal</caption>
<tr>
<th>Dog</th>
<th>Panda</th>
<th>Cat</th>
</tr>
<tr>
<td>middle</td>
<td>large</td>
<td>small</td>
</tr>
</table>
</div>
</body>
</html>

Definitely use flex-box to float stacked canvases to perfection. Note: you'll need to use "display: flex" for the entire layout including HTML and BODY elements, plus any parent containers/ divs.
#canvasWrapper {
align-items: center;
display: flex;
height: 100%;
justify-content: center;
}
canvas {
position: absolute;
}

Related

Setting an element position according to another element (seems JS/CSS bug)

I have a div that will be set according to the hovered element position in window. At first I thought this was a JQuery bug, but after more investigating and changing to vanilla, it's still the same.
I have created a code snippet to demonstrate my problem. If you mouse enter white div from top, the position is correct and orange box cover entire white box, but if you enter it from other sides, it's incorrect by few pixel:
var inspector_rect2= document.getElementById('inspector_rect');
$(window).mouseover(function(event) {
inspector_rect2.style.left= event.target.getBoundingClientRect().x+'px';
inspector_rect2.style.top= event.target.getBoundingClientRect().y+'px';
inspector_rect2.style.width= event.target.getBoundingClientRect().width+'px';
inspector_rect2.style.height= event.target.getBoundingClientRect().height+'px';
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta charset="UTF-8">
</head>
<style>
html, body {
height : 100%;
margin : 0;
width : 100%;
}
.MyCSS {
background-color : silver;
}
.Container {
height : 100%;
margin : auto;
width : 50%;
}
.Header {
height : 5%;
padding : 2% 0;
width : 100%;
}
.MainContent {
background-color : white;
height : 70%;
width: 100%;
}
.inspector{
position: absolute;
pointer-events: none;
z-index: 999;
background: rgba(255, 166, 0, 0.5);
}
</style>
<body class="MyCSS">
<div class="Container" >
<div class="Header" ></div>
<div class="MainContent" ></div>
</div>
</body>
<div id=inspector_rect class=inspector></div>
It seems to be caused by an interaction between requesting .getBoundingClientRect() and setting width and height.
Generally, you should just make one request, store it, then re-use as needed.
$(window).mouseover(function(event) {
const rect = event.target.getBoundingClientRect();
inspector_rect2.style.left= rect.x+'px';
inspector_rect2.style.top= rect.y+'px';
inspector_rect2.style.width= rect.width+'px';
inspector_rect2.style.height= rect.height+'px';
});

How do I get text appear on the right side of the map when I click on a country using Javascript events?

This is the task:
Create a web page showing the map of Scandinavia on the left and a blank element on the right. Here it is a good idea to use the map as a background image in an element.
Add round - elements (Hint: border-radius) with each of the four flags and place them over the country to which they belong (Hint: position).
Add an effect when you hover the mouse pointer over a flag.
For example, you can change the arrow to a hand, and you can do something with the elements that make it clear that you are holding them over.
Add a click event to each of the flags. When a flag is clicked, a text about the country should appear in the element on the right. The text must contain information about the country, and must at least contain area, population, currency and capital.
All I have left is to get the text about the the clicked country to appear on the right side of the map.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*,*::before,*::after{
box-sizing: border-box;
}
.container{
display: flex;
}
.container>div:first-child{
position: relative;
height: 500px;
width:500px;
padding:1rem;
background-color: #eee;
background-image:url(./Oppgave2/Skandinavia.png);
background-position: center;
background-size:contain;
background-repeat:no-repeat;
}
.container>div:first-child .flag{
width: 32px;
height: 32px;
position:absolute;
border-radius: 50%;
background-color: #fff;
padding:0.1rem;
}
.container>div:first-child img{
width: 28px;
height: 28px;
border-radius: 50%;
}
.container>div:first-child img:hover{
cursor:pointer;
transform:scale(1.2);
}
.norway{
top: 300px;
left: 126px;
}
.finland{
top:234px;
left: 350px;
}
.sweden{
top:282px;
left: 203px;
}
.denmark{
top:447px;
left: 120px;
}
</style>
</head>
<body>
<div class="container">
<div>
<div class="flag norway" >
<img src="./Oppgave2/Norge.png" alt="Norway">
</div>
<div class="flag denmark">
<img src="./Oppgave2/Danmark.png" alt="Denmark">
</div>
<div class="flag sweden">
<img src="./Oppgave2/Sverige.png" alt="Sweden">
</div>
<div class="flag finland">
<img src="./Oppgave2/Finland.png" alt="Finland">
</div>
</div>
<div>
</div>
</div>
<script>
</script>
</body>
</html>
All I have left is to get the text about the country I want to click to appear on the right side of the map when I click the country. So if I want to click on Norway, it should appear a text containing information about Norway on the right side of the map. The same goes for Sweden, Denmark and Finland's flags.
you can use :focus pseudo to display details after click event. Also, you have to add tabindex attribute to elements you want to be clicked.

Flex box having 2 div inside it one having canvas inside it

Scenerio:
Here is my HTML.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div id='textbox'>
<div id="sibling"></div>
<div id='canvasParent'>
<canvas id="myCanvas" style="border:1px solid #000000">
</canvas>
</div>
</div>
</body>
</html>
Here is the js for the same.
function outputsize() {
console.log(canvasParent)
canvasParent.clientWidth = textbox.clientWidth - sibling.clientWidth;
myCanvas.width = canvasParent.clientWidth;
}
outputsize();
new ResizeObserver(outputsize).observe(textbox);
Here is the css for the same.
#textbox {
display:flex;
flex-direction:row;
border:1px solid green;
flex:1;
}
#sibling {
width:200px;
border:4px solid yellow;
}
#canvasParent {
border:2px solid red;
flex:1;
}
First div have 2 child divs namely sibling and canvasParent, sibling has fixed width, whereas canvasParent will take the remaining width.
Currently it is not behaving as expected once we decrease window width then the first div(sibling) is decreasing its width, and the width of other div is constant, whereas I want sibling div to remain at its fixed width once user decrease the window width and the other div to shrink/grow.
Here is the JSBIN for the same having css, js for the described scenerio.
Expectation:
Once we resize the window, the first div (sibling) will keep its fixed width and the other div having canvas inside it will shrink/grow based on window resizing, and the canvas inside it will take its parent width(logic for canvas to take its parent div is already written in js file.)
And resizing works fine, once I remove the canvas element from the second div.
Here is the JSBIN that show first div to remain at fixed width and other div to shrink/grow once user reduces windows width.
You can use CSS Grid to get the effect:
#textbox {
display: grid;
grid-template-columns: 200px 1fr;
grid-template-rows: 1fr;
grid-template-areas: ". .";
grid-column-gap: 10px;
}
#sibling {
background: red;
}
#canvasParent {
background: black;
}
#myCanvas {
width: 100%;
background: pink;
}
<div id="textbox">
<div id="sibling"></div>
<div id="canvasParent">
<canvas id="myCanvas"></canvas>
</div>
</div>
You can design CSS Grids here: https://grid.layoutit.com/?id=2NkZ4JY

How can i write text over a canvas animation

So i'm making a online profile for myself, and i was doing research on how to make the landing page as attractive as possible. Came across HTML5 Canvas, did some research and experimentation on making an interactive background, and this is the result (in codepen).
Now, i would like to write my name in the middle of the canvas with the text infront of the animation.
The animation gets called in a recursive loop and the initialization function gets called when the page is resized or refreshed.
Problem is, i can't get the text infront, and for some odd reason, my text shrinks when the page is resized.
Here is my pen
https://codepen.io/hamza-tariq-khan/pen/mzKMNd
<!doctype html5>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Canvas Resize</title>
<style>
canvas{
/* border: 1.5px solid black; */
/* background-color: red; */
display: block;
}
body{
margin: 0;
overflow-x: hidden;
}
.wrapper{
margin : 20px;
}
</style>
</head>
<body>
<canvas></canvas>
<script src="script.js"></script>
<div class="wrapper">
<h1>This is a sample sentence</h1>
</div>
</body>
</html>
and this is an idea of what i want to achieve. (the writing of Mathew williams infront of the moving background)
http://findmatthew.com
If I were you, I would skip rendering text in the canvas and apply some CSS rules to the div to make it show up on top instead. The CSS approach improves performance and also improves accessibility. A blind person using a screen reader will be able to figure out what's in the div, but reading text in the canvas is not supported. Most importantly, it's a lot easier to reason about HTML and CSS than it is to reason about text rendering in a canvas element. How often will you do that? When you come back to change the code in a month, six months, or a year, it will be easier to change the HTML/CSS than it will be to think through the canvas rendering logic all over again!
To do this, use the following CSS for div wrapper:
.wrapper{
position: absolute;
top: 0px;
color: red;
font-size: 60px;
margin : 20px;
}
position: absolute allows the div to overlap the canvas, and properties top, bottom, left and right allow you to control how far the div is offset from the edges of its parent (in this case wrapper is a child of body). I adjusted color and font-size just to make it obvious that it works.
And here is a link to a working example: https://codepen.io/anon/pen/LqoroR
var canvas = document.getElementById("dm_graphs");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "blue";
ctx.fillRect(0, 0, canvas.width, canvas.height);
<style>
body,
canvas,
html {
font: 24px sans-serif;
height: 100hv;
width: 100%;
margin: 0;
padding: 0;
background: #888;
color: #135;
overflow: hidden
}
#fs {
position: relative
}
#txt,
canvas {
position: absolute
}
#txt {
color: yellow;
margin: 50px;
font: 24px subpixel-antialiased Noto Sans Samaritan;
background: transparent
}
</style>
<body>
<div id="fs">
<canvas id="dm_graphs" width="400" height="300"></canvas>
<div id="txt">This is a text over a canvas.</div>
</div>
</body>

How to add border but no change to the content position

I am trying to add a border to a div element when the moust is hovering on the div, but I found after the border is aded, the boder will occupy some space and make the content move. See the snippet below. Is it possible to avoid move the content in this case when the border is displayed?
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style type="text/css">
</style>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/lib.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#test-id').hover(function() {
console.log("test-id");
$('#test-id').css('border', '5px dotted');
},
function() {
$('#test-id').css('border', 'none');
}
);
});
</script>
</head>
<body style="margin-bottom:0px;margin-top:0px;">
<div>
<div style="width: 300px;">
</div>
<div id="test-id">
jfdjkfjdsfjaldsjfsjf
</div>
</div>
</body>
</html
>
Use CSS 'outline' property instead of border. Which will not occupy element space.
Hope will help you.
Try maintaing the border all the time, and just change the color from transparent to whatever color you want it to have when its visible. You could also use a the background color as the "off" color, but that means it has to overly a solid colored element.
Bin ,
Yes border is also cacluated as part of width. So do one thing give a border before itselef with the same color as background , once you mouseover you can change the color , so that it won't push the other ones down.
This is the behavior how the css render.
You need to set the margin to prevent this.
$('#test-id').css('margin', '-5px');
1 Solution is that you make the with: on hover -2px or another one on normal state, with the border color seted to the box color (or background color of the body).
ex 1:
<body>
<div class="container"></div>
</body>
body { background: #ccc; }
.container { width: 200px; height: 200px; background: #fff; }
.container:hover { width: 198px; border: 1px solid #000; }
ex 2: (best solution)
<body>
<div class="container"></div>
</body>
body { background: #ccc; }
.container { width: 200px; height: 200px; background: #fff; border: 1px solid #fff; } // or #ccc
.container:hover { border: 1px solid #000; }

Categories

Resources