#dom-to-image Export an off the screen div as image - javascript

I'm using the dom-to-image library (and downloadjs library) to take a snapshot of a div in my website.
I'm using this method:
domtoimage.toPng(document.getElementById('myDiv'))
.then(function (dataUrl) {
download(dataUrl, 'myDiv.png');
});
The problem is that the div I want to export, is off the screen, that is, it has these css properties:
.myDiv {
width: 100px;
height: 100px;
background: red;
position: absolute;
left: -100px;
top: 0;
}
and the method exports an empty image.
Do you have any ideas to solve this problem?
Are there any other ways of hiding a div from the screen that i can try?
I would like to avoid using z-index css property if it is possible ;)

You can apply a style that brings your div visible in the viewport before taking the snapshot.
domtoimage.toPng(document.getElementById('myDiv'), {
style: {
'left': '0px'
}
}).then(function(dataUrl) {
var img = new Image();
img.src = dataUrl;
document.getElementById('result').appendChild(img);
//download(dataUrl, 'myDiv.png');
});
.myDiv {
width: 100px;
height: 100px;
background: red;
position: absolute;
left: -100px;
top: 0;
}
#result {
position: absolute;
left: 200px;
top: 50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/dom-to-image/2.6.0/dom-to-image.js"></script>
<div id="myDiv" class="myDiv">
test
</div>
<div id="result">
</div>

Related

popup image with no html code only css and javascript

So I have a 360 Virtual tour using pannellum, I have this hotspot code desing in css
.custom-hotspot {
height: 30px;
width: 30px;
border-radius: 50%;
background: rgb(253, 253, 255);
}
I would like that when u click the hotspot popup an image but without using html tags only css and javascript, I try using this
.custom-hotspot:hover {
content: url(https://i.ibb.co/5c9zFfq/DCIM-100-MEDIA-DJI-0293-JPG.jpg); /* no need for qoutes */
width: 100px;
height: 100px;
border-radius: 20%;
}
but this is not a popup image and its not the same.
Does anyone know a solution for this?
If by popup you mean separate browser window then no..
But if you want to display the image next to the cursor on element hover you can display it as the background in a pseudo element.
.custom-hotspot:hover::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
border-radius: 20%;
background-image: url(https://i.ibb.co/5c9zFfq/DCIM-100-MEDIA-DJI-0293-JPG.jpg);
}
Make sure that the parent element has a defined position property like position: relative or absolute. Otherwise the image will be displayed at the top of the closest grandparent that has it defined.
edit..
.clicked::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
border-radius: 20%;
background-image: url(https://i.ibb.co/5c9zFfq/DCIM-100-MEDIA-DJI-0293-JPG.jpg);
}
Javascript:
// this gets HTML collection of all elements with the 'custom-hotspot' class
const elementCollection = document.getElementsByClassName('custom-hotspot');
// add a click listener to each element
elementCollection.forEach(e => {
e.addEventListener('click', handleClick, {passive: true});
});
/// here we toggle our 'clicked' class
function handleClick(event) {
// if '.target' does not work as expected try '.currentTarget'
event.target.classList.toggle('clicked');
}

How to prevent get over other divs?

I have a problem...In the following example i don't want that the div who is fixed get over the div with the background red.
Here is the example:
http://jsfiddle.net/HFjU6/3645/
#fixedContainer
{
background-color:#ddd;
position: fixed;
width: 200px;
height: 100px;
left: 50%;
top: 0%;
margin-left: -100px; /*half the width*/
}
Alright, I think I get what the OP wants. He wanted a container that stays fixed on the top of the viewport, but remains confined by a parent. This behaviour is known as a conditional sticky behaviour, and is actually implemented in both Firefox (without vendor prefix) and macOS/iOS Safari (with -webkit- prefix): see position: sticky.
Therefore the easiest (but also the least cross-browser compatible) way is simply to modify your markup, such that the sticky element stays within a parent, and you declare position: sticky on it:
* {
margin: 0;
padding: 0;
}
#fixedContainer {
background-color: #ddd;
position: -webkit-sticky;
position: sticky;
width: 200px;
height: 100px;
left: 50%;
top: 0%;
transform: translate(-50%, 0); /* Negative left margins do not work with sticky */
}
#div1 {
height: 200px;
background-color: #bbb;
}
#div1 .content {
position: relative;
top: -100px; /* Top offset must be manually calculated */
}
#div2 {
height: 500px;
background-color: red;
}
<div id="div1">
<div id="fixedContainer">I am a sticky container that stays within the sticky parent</div>
<div class="content">Sticky parent</div></div>
<div id="div2">Just another element</div>
An alternative would be to use a JS-based solution. In this case, you do not actually have to modify your markup. I have changed the IDs for easier identification of the elements, however.
The gist of the logic is this:
When the scroll position does not exceed the bottom of the parent minus the outer height of the sticky content, then we do not do anything.
When the scroll position exceeds the bottom of the parent minus the outer height of the sticky content, we dynamically calculate the top position of the sticky content so that it remains visually in the parent.
$(function() {
$(window).scroll(function() {
var $c = $('#sticky-container'),
$s = $('#sticky-content'),
$t = $(this); // Short reference to window object
if ($t.scrollTop() > $c.outerHeight() - $s.outerHeight()) {
$s.css('top', $c.offset().top + $c.outerHeight() - $t.scrollTop() - $s.outerHeight());
} else {
$s.css('top', 0);
}
});
});
* {
margin: 0;
padding: 0;
}
div {
height: 500px;
background-color: red;
}
#sticky-container {
background-color: #bbb;
height: 200px;
}
#sticky-content {
background-color: #ddd;
position: fixed;
width: 200px;
height: 100px;
margin-left: -100px;
left: 50%;
top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="sticky-content">Sticky content that stays within the bounds of #div1</div>
<div id="sticky-container">Sticky confinement area</div>
<div>Other content</div>
Old answer before OP clarified the question appropriately:
Just give them the appropriate z-index values. In this case, you want to:
Do not use static positioning. This can be done by using position: relative for the large elements, in conjunction with the originally position: fixed element.
Assign the appropriate stacking order. The grey <div> element to have the lowest z-index, followed by the position fixed element, and then by the red element.
There are some catchalls to stacking though: the stacking context is reset when you traverse up or down the node tree. For example, the example will not work if the elements are not siblings.
Here is a proof-of-concept example, modified from your fiddle so that inline CSS is removed.
* {
margin: 0;
padding: 0;
}
#fixedContainer {
background-color: #ddd;
position: fixed;
width: 200px;
height: 100px;
left: 50%;
top: 0%;
margin-left: -100px;
z-index: 2;
}
#div1 {
height: 200px;
background-color: #bbb;
position: relative;
z-index: 1;
}
#div2 {
height: 500px;
background-color: red;
position: relative;
z-index: 3;
}
<div id="fixedContainer">z-index: 2</div>
<div id="div1">z-index: 1</div>
<div id="div2">z-index: 3</div>
Just give the z-index.
Hope it helps...
http://jsfiddle.net/HFjU6/1/#run
#fixedContainer {
background-color:#ddd;
position: fixed;
width: 200px;
height: 100px;
left: 50%;
top: 0%;
margin-left: -100px; /*half the width*/
z-index: 2;
}
.div-red {
position: relative;
z-index: 5;
}
<div id="fixedContainer"></div>
<div style="height:200px;background-color:#bbb;"></div>
<div style="height:500px;background-color:red;" class="div-red"></div>

Javascript/Jquery - Increase padding percentage of div on click

I have a problem that I've spent the better part of half a day trying to solve with no real solution I'm happy with. I have a carousel which contains a placeholder image for a youtube video, and when you click on it the placeholder image is removed and is replaced by the youtube video, but as the aspect ratio of the placeholder image is different from the video, and I need this to work responsively, I need to increase the percentage of the padding of the div these sit in when the user clicks (or taps) on the div.
So, my HTML for this div looks as such:
<div class="youtube_video">
<img src="img/video_poster_carousel.jpg" width="986" height="308">
<!-- <iframe width="986" height="555" src="https://www.youtube.com/embed/Wt_Ruy_ejPY?enablejsapi=1&list=PL027E2B6D9900A88F&showinfo=0&controls=1" frameborder="0" allowfullscreen></iframe> -->
</div>
And the CSS:
/* video */
.youtube_video { position: relative; padding-bottom: 31.65%; height:0; }
.youtube_video img { position: absolute; display: block; top: 0; left: 0; /*width: 100%; height: 100%;*/ z-index: 20; cursor: pointer; }
.youtube_video:after { content: ""; position: absolute; display: block;
background: url(play-button.png) no-repeat 0 0;
top: 45%; left: 45%; width: 46px; height: 36px; z-index: 30; cursor: pointer; }
.youtube_video iframe { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
/* image poster clicked, player class added using js */
.youtube_video.player img { display: none; }
.youtube_video.player:after { display: none; }
And the Javascript being used right now:
$(function() {
var videos = $(".youtube_video");
videos.on("click", function(){
var elm = $(this),
conts = elm.contents(),
le = conts.length,
ifr = null;
for(var i = 0; i<le; i++){
if(conts[i].nodeType == 8) ifr = conts[i].textContent;
}
elm.addClass("player").html(ifr);
elm.off("click");
});
});
Basically, I need to increase the padding-bottom on .youtube_video from 31.65% to 56.25% (16:9 ratio) upon clicking on the div. I'm probably missing something obvious, but Javascript/jQuery isn't my strongest point. Any help would be appreciated.
Try adding this to your click function?
$('.youtube_video').css('padding-bottom','56.25%');
JQuery CSS
DEMO
If you have the width of the <iframe> you can allways set its size and animate it with jquery.
$('.video-container').animate({
width:'200px',
height:'200px',
});

.toggleClass not toggling a certain class, but is working on all others

So I have a page on my website that has some navigation elements that stick on the page when the user scrolls past a certain point. There are three of them, one on the top, one on the left, and one on the right. HTML and CSS is as follows:
<div id="nav" class="nav">
<!--STUFF CONTAINED IN TOP NAV BAR-->
</div>
<div class="right" id="right">
<!--STUFF CONTAINED IN RIGHT NAV-->
</div>
<div class="left" id="left">
<!--STUFF CONTAINED IN LEFT NAV BAR-->
</div>
.nav {
position: absolute;
top: 108px;
height: 45px;
width: 100%;
left: 0;
right: 0;
}
.nav_sticky {
position: fixed;
top: 0;
height: 45px;
left: 0;
right: 0;
background-image: url(images/backgrounds/stardust_#2X.png);
z-index: 10;
}
.right {
width: 200px;
height: 900px;
position: absolute;
right: 50%;
margin-right: -538px;
top: 153px;
}
.right_sticky {
width: 200px;
height: 900px;
position: fixed;
right: 50%;
margin-right: -538px;
top: 45px;
}
.left {
width: 200px;
height: 900px;
position: absolute;
left: 50%;
margin-left: -538px;
top: 153px;
}
.left_stick {
width: 200px;
height: 900px;
position: fixed;
left: 50%;
margin-left: -538px;
top: 45px;
}
I then use the follow JQuery to cause these elements to stick.
<script>
$(document).ready(function(){
var navPos = $('#nav').offset().top;
$(window).scroll(function () {
var scrollTop = $(this).scrollTop();
if (scrollTop >= navPos) {
var classNamee = $('#nav').attr('class');
console.log(classNamee);
if (classNamee === "nav") {
$("#nav").toggleClass('nav nav_sticky');
$("#right").toggleClass('right right_sticky');
$("#left").toggleClass('left left_stick');
}
}
if (scrollTop <= navPos) {
var className = $('#nav').attr('class');
console.log(className);
if (className === "nav_sticky") {
$("#nav").toggleClass('nav_sticky nav');
$("#right").toggleClass('right_sticky right');
$("#left").toggleClass('left left_stick');
}
}
});
});
</script>
Here's my problem. This works perfectly for the top and right navs, however no matter what I try, the left nav continues to scroll when the others have stopped. I thought it may have been a typo in the css class, but when I looked in the inspector, the .toggleClass function doesn't even change the class on the #left element when it does on the other two. Any ideas as to what could be causing this?
If I copy/paste your sample code as-is to jsFiddle and run it, when you scroll down far enough, it does correctly toggle everything to *_sticky classes, but something about the negative margin-right on the right class element seems to reset the scroll to the top (at least in Chrome) when it flips between .right and .right-stick. When the scroll gets reset, it also reruns your event handeler and changes all the classes back.
Try removing these lines from your CSS and see if the behavior works right (it does in Chrome in a jsFiddle)
.right {
...
/*margin-right: -538px;*/
.right-stick {
...
/*margin-right: -538px;*/

How to get the position of an element relative to another using jQuery?

Please have a look at this:
http://liveweave.com/5bhHAi
If you click the "Get Pos" link you will see the red div's position relative to the image.
Now say this image's size has changed at some point down the line. How can I get the new position for the red div based on the initial data?
HTML:
<div id="watermark"></div>
<img src="http://placekitten.com/g/320/270" class="small-img">
<div><br><br>Get Pos</div>
jQuery:
$(document).ready(function() {
var $watermark = $('#watermark');
$('.get-pos').on('click', function(e) {
e.preventDefault();
var watermark_position = {
top: $watermark.position().top - $('.small-img').position().top,
left: $watermark.position().left - $('.small-img').position().left
};
alert(watermark_position.top + 'px from the top');
alert(watermark_position.left + 'px from the left');
});
});
CSS:
#watermark { background: red; position: absolute; top: 215px; left: 265px; width: 50px; height: 50px; }
Here is a solution to what I understand you want from question/comments:
http://jsfiddle.net/tXT2d/
var imgPos = $(".image img").offset();
var wmPos_tmp = $(".watermark").offset();
var watermarkPosition = {
top: wmPos_tmp.top - imgPos.top,
left: wmPos_tmp.left - imgPos.left
}
You can accomplish your intended goal (placing the watermark at the right place even after size changes) without using javascript at all if you do just a little reworking. A working example of the following solution is here
(just change the width of the .img-container to see it function).:
.watermark {
background: red;
width: 50px;
height: 50px;
}
.img-container {
width: 295px;
height: auto;
position: relative;
}
.img-container img {
width: 100%;
}
.img-container .watermark {
position: absolute;
right: 10px;
bottom: 10px;
}
<div class="img-container">
<div class="watermark"></div>
<img src="http://placekitten.com/g/320/270" class="small-img">
</div>
Your html containing the image will look basically like this:
<div class="img-container">
<div class="watermark"></div>
<img src="http://placekitten.com/g/320/270" class="small-img">
</div>
And the css to get the placement to happen looks like this:
.watermark { background: red; width: 50px; height: 50px; }
.img-container {
width: 275px;
height: auto;
position: relative;
}
.img-container img {
width: 100%;
}
.img-container .watermark {
position: absolute;
right: 10px;
bottom: 10px;
}
Here, the image will always match the width of its container, and the watermark will always place itself ten pixels from the right and ten pixels from the bottom of the container.

Categories

Resources