Append canvas with parent's height creates scrollbars - javascript

I have problem with canvas tag. I need to append it into parent div. But when I set precise dimensions of parent and embed canvas tag, I get scrollbars. When I do same think with div, it works good. Here is fiddle:
https://jsfiddle.net/57yovrkx/4/
and here is code:
$(function() {
var content1 = $('#content1');
var div = $('<div/>', {width: content1[0].clientWidth, height: content1[0].clientHeight});
content1.append(div);
var content2 = $('#content2');
var canvas = $('<canvas/>', {width: content2[0].clientWidth, height: content2[0].clientHeight});
content2.append(canvas);
})
* {
box-sizing: border-box;
border: 0;
margin: 0;
padding: 0;
}
#wrap1, #wrap2 {
display: flex;
flex-direction: column;
position: absolute;
left: 0;
right: 0;
overflow: auto;
}
#wrap1 {
top: 0;
bottom: 50%;
}
#wrap2 {
top: 50%;
bottom: 0;
}
.header {
flex: 0 0 2rem;
background: darkgrey;
}
#content1, #content2 {
flex: 1;
}
#content1 {
background: lightblue;
}
#content2 {
background: lightgreen;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrap1">
<div class="header">
Some header
</div>
<div id="content1">
</div>
</div>
<div id="wrap2">
<div class="header">
Some header
</div>
<div id="content2">
</div>
</div>
Does anybody knows why?

Setting canvas.style.height = '100%'; before you append the canvas seems to do the trick.
https://stackoverflow.com/a/10215724/1482623

Related

Infinite carousel with indicator and smooth transition

I'm struggling with infinite carousel below:
let $carousel = document.querySelector('.carousel');
let $ref_ribbon = document.querySelector('.carousel__ribbon');
let $ref_right = document.querySelector('.carousel__button--right');
let $ref_left = document.querySelector('.carousel__button--left');
let $ref_counter = 0;
let $direction;
const transfer = () => {
if ($direction === -1) {
$ref_ribbon.appendChild($ref_ribbon.firstElementChild);
} else if ($direction === 1) {
$ref_ribbon.prepend($ref_ribbon.lastElementChild);
}
$ref_ribbon.style.transition = "none";
$ref_ribbon.style.transform = "translateX(0px)";
setTimeout(function() {
$ref_ribbon.style.transition = "transform .7s ease-in-out";
})
}
const right_button = () => {
if ($direction === 1) {
$ref_ribbon.prepend($ref_ribbon.lastElementChild);
$direction = -1;
}
$direction = -1;
$carousel.style.justifyContent = 'flex-start';
$ref_ribbon.style.transform = `translateX(-${300}px)`;
}
const left_button = () => {
$ref_counter--;
if ($direction === -1) {
$ref_ribbon.appendChild($ref_ribbon.firstElementChild);
$direction = 1;
}
$direction = 1;
$carousel.style.justifyContent = 'flex-end';
$ref_ribbon.style.transform = `translateX(${300}px)`;
}
$ref_right.addEventListener('click', right_button);
$ref_left.addEventListener('click', left_button);
$ref_ribbon.addEventListener('transitionend', transfer)
.carousel {
display: flex;
margin: auto;
position: relative;
height: 200px;
width: 300px;
background-color: red;
justify-content: flex-start;
}
.carousel__button {
position: absolute;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
z-index: 100;
}
.carousel__button--left {
left: 0;
}
.carousel__button--right {
right: 0;
}
.carousel__ribbon {
display: flex;
flex-direction: row;
outline: 3px solid black;
height: 100%;
transition: transform .7s ease-in-out;
}
.carousel__pane {
display: flex;
background-color: skyblue;
height: 100%;
width: 300px;
flex-shrink: 0;
outline: 1px dashed navy;
}
.carousel__content {
text-align: center;
margin: auto;
}
.carousel__indicator {
display: flex;
gap: 10px;
left: 50%;
transform: translateX(-50%);
height: 30px;
position: absolute;
bottom: 0;
}
.carousel__circle {
height: 10px;
width: 10px;
background-color: gray;
border-radius: 50%;
cursor: pointer;
}
.carousel__circle--active {
background-color: black;
}
<div class="carousel">
<button class="carousel__button carousel__button--left"><</button>
<button class="carousel__button carousel__button--right">></button>
<div class="carousel__ribbon">
<div class="carousel__pane">
<p class="carousel__content">Pane 1</p>
</div>
<div class="carousel__pane">
<p class="carousel__content">Pane 2</p>
</div>
<div class="carousel__pane">
<p class="carousel__content">Pane 3</p>
</div>
<div class="carousel__pane">
<p class="carousel__content">Pane 4</p>
</div>
<div class="carousel__pane">
<p class="carousel__content">Pane 5</p>
</div>
</div>
<div class="carousel__indicator">
<div class="carousel__circle carousel__circle--active"></div>
<div class="carousel__circle"></div>
<div class="carousel__circle"></div>
<div class="carousel__circle"></div>
<div class="carousel__circle"></div>
</div>
</div>
I would like to connect indicator so when somebody click on proper circle then carousel will automatically slide to this particular panel. Also, I would like to set this circles that they will show which panel is currently active.
In addition, I would like to get such effect that carousel will jump to this particular panel immediately, ommiting other panels between.
So, if active one is first panel and I click fifth circle, then carousel will smoothly change panel like to the panel number two, but instead of number two I will see number five.
Sadly I always fail to get this effect. I would appriciate if somebody more experienced direct me how to deal with this problem.

How to create a border around a hovered element?

I want to display a border around an element, when it is hovered. Like this image:
The issue is that I don't want add to add border or outline on the element itself because I'm allowing user to change styles and it'll affect the added outline as well.
Here is what I've tried to counter this:
Created overlay div on top of the content using position: absolute
Added a div inside it to which is also set to absolute
Added onmouseover and onmouseout listener on overlay div to get the width, height, offsetLeft and offsetTop of the element
Now the issue is that because the overlay is on top, the events are not firing on elements underneath (as I want the nested element's info as well). I've also tried setting z-index but it doesn't seem to be working as well.
So, how to achieve this?
PS: The screenshot is taken from the visual builder of Webflow but I'm not sure how they are achieving this.
Here is the code:
var outlineContainer = document.querySelector('#content-container');
outlineContainer.onmouseover = outlineContainer.onmouseout = handler;
function handler(event) {
var hoverOutline = document.querySelector('.hover-outline');
if (event.type == 'mouseover') {
console.log(event.target.tagName);
var clientRects = event.target.getBoundingClientRect();
hoverOutline.style.width = `${clientRects.width}px`;
hoverOutline.style.height = `${clientRects.height}px`;
hoverOutline.style.transform = `translate(${event.target.offsetLeft}px,${event.target.offsetTop}px)`;
}
if (event.type == 'mouseout') {
hoverOutline.style.width = 0;
hoverOutline.style.height = 0;
hoverOutline.style.left = 0;
hoverOutline.style.top = 0;
}
}
#content-container {
border: 2px solid black;
background-color: white;
padding: 50px;
position: relative;
height: 100%;
}
.overlay {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
z-index: 2;
}
.hover-outline {
position: absolute;
border: 2px solid orange;
z-index: 6;
top: 0px;
left: 0px;
z-index: 3;
}
.content {
z-index: 4;
}
<div id="content-container">
<div class="overlay">
<div class="hover-outline"></div>
</div>
<div class="content">
<div class="component">
<label>Hi</label>
</div>
<div class="component">
<label>Text Field</label>
<span class="wrapper">
<input type="text" placeholder="Text Input Field" />
</span>
</div>
</div>
</div>
I may have misunderstood what is required, but could you just change the border color on hover? (And remove the JS).
#content-container {
border: 2px solid black;
background-color: white;
padding: 50px;
position: relative;
height: 100%;
}
#content-container:hover {
border: 2px solid red;
}
.overlay {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
z-index: 2;
}
.hover-outline {
position: absolute;
border: 2px solid orange;
z-index: 6;
top: 0px;
left: 0px;
z-index: 3;
}
.content {
z-index: 4;
}
<div id="content-container">
<div class="overlay">
<div class="hover-outline"></div>
</div>
<div class="content">
<div class="component">
<label>Hi</label>
</div>
<div class="component">
<label>Text Field</label>
<span class="wrapper">
<input type="text" placeholder="Text Input Field" />
</span>
</div>
</div>
</div>

Is it possible to make parent element (relative) fill the height of its absolute positioned content?

I'd like my parent div to expand the height of the content, as my content will be dynamic. However, the content must be (I think) positioned absolutely so they can overlap each other vertically.
I've concluded I'll have to use JS to find the offset from the top to the bottom of the last element in the container, then set the height to that.
I'm currently doing something like this:
var lastElement = document.getElementById('three');
var bounds = lastElement.getBoundingClientRect();
var bottomOffset = bounds.top + $("#three").height();
$("#container").height(bottomOffset);
However this is clunky within my application, and the application of the height is not instantaneous, leading to a sluggy site.
Is there a better way?
var lastElement = document.getElementById('three');
var bounds = lastElement.getBoundingClientRect();
var bottomOffset = bounds.top + $("#three").height();
$("#container").height(bottomOffset);
body,
html {
height: 100% padding: 0;
margin: 0;
}
.absolute {
display: inline-block;
position: absolute;
background-color: blue;
width: 100px;
height: 100px;
}
#two {
top: 80px;
left: 120px
}
#three {
top: 160px;
left: 240px;
}
#container {
position: relative;
width: 100%;
;
background-color: yellow;
;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<div class="absolute" id="one"></div>
<div class="absolute" id="two"></div>
<div class="absolute" id="three"></div>
</div>
View on JSFiddle
You can accomplish your result without any JS, but instead use CSS margin around the boxes to get the same result.
For the horizontal margin you can also use percentages (by request of OP).
For the vertical margins this will give unexpected results, since the percentage will still reference the width of the container (under "Property Values"), not the height.
html,body {height:100%; padding:0; margin:0;}
.container {
background-color: yellow;
}
.box {
display: inline-block;
width: 100px;
height: 100px;
margin-right: 2%;
background-color: blue;
}
.box.one {margin-top:0; margin-bottom:160px;}
.box.two {margin-top:80px; margin-bottom:80px;}
.box.three {margin-top:160px; margin-bottom:0;}
<div class="container">
<div class="box one"></div>
<div class="box two"></div>
<div class="box three"></div>
</div>
pixel-margin: https://jsfiddle.net/xzq64tsh/
percent-margin: https://jsfiddle.net/xzq64tsh/3/
Perhaps taking out the getBoundingClientRect() function, using jQuery instead might speed it up and simplify it a bit.
var lastElement = $('#three');
var bottomOffset = lastElement.offset().top + lastElement.height();
$("#container").height(bottomOffset);
body,
html {
height: 100% padding: 0;
margin: 0;
}
.absolute {
display: inline-block;
position: absolute;
background-color: blue;
width: 100px;
height: 100px;
}
#two {
top: 80px;
left: 120px
}
#three {
top: 160px;
left: 240px;
}
#container {
position: relative;
width: 100%;
;
background-color: yellow;
;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<div class="absolute" id="one"></div>
<div class="absolute" id="two"></div>
<div class="absolute" id="three"></div>
</div>

Transitions with overlaps

So I have two divs which are overlapping, set by my CSS as shown below.
HTML:
<body onLoad="present();">
<div class="pre-wrap">
<img src="images/logo.png" id="logo" alt="Pre Logo" style="display: table; margin: 0 auto;" />
</div>
<div class="wrap">
<p>Test</p>
</div>
</body>
CSS:
.pre-wrap {
height: 700px;
width: 900px;
opacity: 1.0;
bottom: 0;
left: 0;
margin: auto;
position: absolute;
top: 0;
right: 0;
background-color: red;
visibility: visible;
}
.wrap {
height: 700px;
width: 900px;
opacity: 1.0;
bottom: 0;
left: 0;
margin: auto;
position: absolute;
top: 0;
right: 0;
background-color: black;
visibility: hidden;
}
I would like, when the body has loaded, a function to load which does the following: Fades in the image found in the div .pre-wrap, after displaying it for a few seconds, it will fade the image out and the div .pre-wrap will have it's visibility set to hidden. The second div .wrap will then fade in all of its contents.
I tried some simple JS but didn't achieve what I was after.
This question I would say is unique because it has overlapping divs which need visibilities being changed. Please note the overlapping already works, it's just the javascript fading that needs doing.
I tried the following JS which is very simple and works on other projects I've done however it doesn't on this one.
function present() {
$("#logo").fadeIn(3000);
}
Here is my code. I removed the property visibility in the css. And set the display of #logo to none. The attribute onload in the body is no longer needed.
var fadeTime = 3000; // Time for fading
var waitingTime = 5000; // Time how long image is visible
$(window).ready(function(){
$("#logo").fadeIn(fadeTime);
setTimeout(function(){
$(".pre-wrap").fadeOut(fadeTime);
$(".wrap").delay(fadeTime).fadeIn(fadeTime);
},fadeTime+waitingTime);
});
.pre-wrap, .wrap{
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
height: 700px;
width: 900px;
opacity: 1.0;
margin: auto;
}
.pre-wrap {
background-color: red;
}
.wrap {
background-color: black;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="pre-wrap">
<img src="images/logo.png" id="logo" alt="Pre Logo" style="display: none; margin: 0 auto;" />
</div>
<div class="wrap">
<p>Test</p>
</div>

Closable div - Left div slides close, while right div width expands

I'm trying to make a div on the left side that can close by sliding to the left While the content in the right div expands to 100% filling the space of the closed div. image example
I found a demo here but its only for the closable div.
<div id="intro-wrap">
<div class="open-intro">+</div>
<div class="close-intro">-</div>
<div id="contentWrap">
<h1 class="main-header">Here is a Title</h1>
<p class="main-desc">You can write whatever you want about yourself here. You can say you're a superhuman alien ant, arrived from the nether regions of Dwarf-Ant-Dom.</p>
</div>
</div>
It has some work to do, but it'll get you started.
$(function() {
"use strict";
var isOpen = true;
$('#open-close').on('click', function() {
if (isOpen) {
animate(false);
isOpen = false;
} else {
animate(true);
isOpen = true;
}
});
});
function animate(action) {
if (action) {
$('#left').animate({ width: "30vw" }, 600);
$('#right').animate({width: "70vw",marginLeft: "-5px"}, 600);
} else {
$('#left').animate({width: "0px"}, 600);
$('#right').animate({width: "99vw" }, 600);
}
}
* {
padding: 0;
margin: 0;
}
#wrapper{
width: 100vw;
height: 100px;
border: 2px solid purple;
}
#wrapper > *{
display: inline-block;
}
#left {
position: relative;
width: 30vw;
height: 100px;
background: green;
}
#right {
position: relative;
width: 65vw;
height: 100px;
background: navy;
}
#open-close {
position: absolute;
width: 10px;
height: 10px;
margin-top: 5px;
margin-left: 5px;
background: red;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrapper">
<div id="left"></div>
<div id="right">
<div id="open-close"></div>
</div>
</div>

Categories