I have a div which is pretty overflowed. It basically includes a big organization chart. What I want to do is exporting whole content of div rather than visible part with html2canvas library but I couldn't achieve it so far. Following piece of code doesn't render full content. Is there a way to achieve it?
function export(){
html2canvas( [ document.getElementById('diagram') ], {
onrendered: function(canvas) {
var dataUrl = canvas.toDataURL();
window.open(dataUrl, "toDataURL() image", "width=800, height=800");
//Canvas2Image.saveAsPNG(canvas);
}
});
}
I am using BasicPrimitives library to generate organization charts. It takes a div and insert all elements to it. Since my chart is moderately big, it overflows from its container.
Xhtml code is as follows:
<rich:panel style="float: left; width: 100%;">
<div style="float: left; height:600px; margin-left: 1%; width: 19%; border-style: dotted; border-width:1px;">
Some irrelevant content
</div>
<div id="diagram" class='diagram' style="float: right; height:600px; width: 59%; border-style: dotted; border-width:1px;">
This is the div all charts are dynamically inserted
</div>
<div style="float: left; height:600px; margin-left: 1%; width: 19%; border-style: dotted; border-width:1px;">
Some more irrelevant content
</div>
</rich:panel>
I don't know if there's a straightforward option in html2canvas to do this (i.e. an option to set all overflow to visible) but a roundabout way might be to set the parent of the diagram element's overflow property to visible when your export function is called, then set it back to hidden again on html2canvas' onrendered callback so that the user has minimal time to perceive it:
function export(){
document.getElementById('diagram').parentNode.style.overflow = 'visible'; //might need to do this to grandparent nodes as well, possibly.
html2canvas( [ document.getElementById('diagram') ], {
onrendered: function(canvas) {
document.getElementById('diagram').parentNode.style.overflow = 'hidden';
var dataUrl = canvas.toDataURL();
window.open(dataUrl, "toDataURL() image", "width=800, height=800");
//Canvas2Image.saveAsPNG(canvas);
}
});
}
Give a try to dom-to-image, it works better for me since I have to set specific size, and show and element that hides for some screen size:
function convertCanvasAndSend(idElement, nameImage) {
var element = document.getElementById(idElement);
var styleOrig = element.getAttribute("style");
element.setAttribute("style", "width: 1400px; height: 480px;");
element.querySelector("ANY_HIDDEN_YOU NEED").setAttribute("style", "display: block;");
domtoimage.toBlob(element)
.then(function (blob) {
window.saveAs(blob, nameImage + '.png');
element.setAttribute("style", styleOrig);
element.querySelector("ANY_HIDDEN_YOU NEED").setAttribute("style", styleOrigInnDiv);
});
}
Related
I was following a solution in order to implement the html2canvas function. (How to show scrollable all contents of div in pdf using html2canvas)
The answer of one of the users is just working fine, when executing the respective function in jsfiddle.net (https://jsfiddle.net/dr4ewfa1/5/). However, after copying + pasting the same code in visual study, I don't receive any download files after clicking the button.
Do you have an idea, why this could be & how to solve this ?
My HTML file looks like this, the JS code is exactly the same as mentioned by the user #Nimitt Shah:
$(document).ready(function() {
$('#print').click(function() {
var currentPosition = document.getElementById("content").scrollTop;
var w = document.getElementById("content").offsetWidth;
var h = document.getElementById("content").offsetHeight;
document.getElementById("content").style.height="auto";
html2canvas(document.getElementById("content"), {
dpi: 300, // Set to 300 DPI
scale: 3, // Adjusts your resolution
onrendered: function(canvas) {
var img = canvas.toDataURL("image/jpeg", 1);
var doc = new jsPDF('L', 'px', [w, h]);
doc.addImage(img, 'JPEG', 0, 0, w, h);
doc.addPage();
doc.save('sample-file.pdf');
}
});
document.getElementById("content").style.height="100px";
document.getElementById("content").scrollTop = currentPosition;
});
});
body {
background: beige;
}
header {
background: red;
}
footer {
background: blue;
}
#content {
background: yellow;
width: 70%;
height: 100px;
margin: 50px auto;
border: 1px solid orange;
padding: 20px;
overflow-y:auto;
}
.html2canvas-container { width: 3000px !important; height: 3000px !important; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.4.1/jspdf.min.js">
</script>
<div id="content">
<p>This is the element you only want to capture</p>
<p>This is the element you only want to capture</p>
<p>This is the element you only want to capture</p>
<p>This is the element you only want to capture</p>
<p>This is the element you only want to capture</p>
</div>
<button id="print">Download Pdf</button>
<footer>This is the footer</footer>
I also executed the following statement in the console/terminal: npm install --save html2canvas
Unfortunately i still didn't get any file.
Thanks in advance.
Edit: I realized, that I'm also not able to execute the code in here. maybe it's the same reason ?
I'm trying to figure out if it's possible to read a div's margins with JavaScript if those margins are set in external css file.
So far I am able to read div's margin data when it is written as an inline style (not in CSS file but inside HTML):
(function() {
var banner = document.getElementById('banner');
var move = document.getElementById('box');
banner.onclick = function() {
alert(move.style.marginLeft);
};
})();
Here is JSFiddle:
https://jsfiddle.net/b0kaLk1f/
It works well but just remove style="margin-left: 500px" and it will stop working. I'd like to read CSS data from style.css file rather than from inline styles.
The Window.getComputedStyle() method gives the values of all the CSS properties of an element after applying the active stylesheets and resolving any basic computation those values may contain.
(function() {
var banner = document.getElementById('banner');
var move = document.getElementById('box');
banner.onclick = function() {
var style = window.getComputedStyle(move, null);
alert(style.marginLeft);
};
})();
#box {
margin-left: 500px;
-webkit-transition: 0.5s;
transition: 0.5s;
background: #af0000;
width: 500px;
height: 300px;
}
#banner {
border: solid 1px #000;
overflow: hidden;
width: 500px;
height: 300px;
}
<div id="banner">
<div id="box"></div>
</div>
Essentially you are trying to maintain state in the form of style properties, which is not a good idea. You will have to retrieve them and set them. Instead, use a class to move the extended banner back and forth. The code is shorter and simpler:
banner.onclick = function () {
ext.classList.toggle('hide_extended_banner');
};
See https://jsfiddle.net/b0kaLk1f/2/.
Currently I have a huge div that would collapse from the height it automatically generated to the height of the title of the div. (i.e. 32px). I have it start out collapsed and then when I click on the div it opens to its full size, displaying all its inner information, and then when I click again, it collapses again. Unfortunately, two things happen:
The div doesn't completely expand to its full height.
The first large img in the div gets resized.
Now I understand why the latter is happening. It has something to do with the height being a percentage instead of a discrete number, for when I change the number to something like 500px, it works just fine. But I don't want to do that. I need it to remain a percentage for when I need to use, yet resize, large pictures.
I also feel this same problem may coincide with the former problem as well, but I'm not sure.
Please help me with this.
HTML:
<!DOCTYPE html>
<html>
<head>
<title>This is the title</title>
</head>
<body>
<div class="example"> <span class="h2">DIV Example</span>
<br />
<img class="big" src="http://www.greenbookblog.org/wp-content/uploads/2012/03/big-data.jpg" />
<p>This is a big picture. It's here to show what this thing is supposed to be doing.
However, this picture has been squished so that it can fit within the div nicely. I am
writing a bit so that I can take up space.</p>
<img class="big" src="http://www.greenbookblog.org/wp-content/uploads/2012/03/big-data.jpg" />
<p>This is a big picture. It's here to show what this thing is supposed to be doing. However, this picture has been squished so that it can fit within the div nicely. I am writing a bit so that I can take up space.</p>
</div>
</body>
</html>
CSS:
div.example, div.example img {
border: 3px solid #402468;
border-radius: 6px;
}
div.example {
color: white;
margin: 0 15px;
background-color: #504689;
overflow: hidden;
}
img {
display: block;
margin: 0 auto;
}
img.big {
width: 85%;
height: 85%;
}
/*further formatting: pay no mind*/
div p {
text-indent: 15pt;
margin: 0 15px;
}
.h2 {
font: 32px"Times New Roman", serif;
color: #678900;
}
aaaand jQuery:
$(document).one("ready", function () {
$("div.example").each(function () {
$(this).data("height0", $(this).height());
$(this).height("32px");
});
});
$(document).ready(function () {
$("div.example").click(function () {
if ($(this).height() !== 32) {
$(this).animate({
height: '32px'
});
} else {
$(this).animate({
height: $(this).data("height0")
});
}
});
});
Here is the fiddle:
https://jsfiddle.net/AirStyle/rb95K/35/
Also this is what I get:
https://jsfiddle.net/AirStyle/rb95K/35/embedded/result/
CAUTION: I may not have made the percentages small enough for the picture used. Please lessen them if necessary.
Just remove the height setting altogether and it will keep aspect ratio
(Demo)
img.big {
width: 85%;
}
Also you should cache your jQuery objects. I've done this in the demo by caching $(this) to var self = $(this) and then referring to self therein. There is a lot of overhead in initializing jQuery objects, so if you're using the same selector more than once, cache it.
Edit:
Because you are setting the height of the div to a fixed height on expansion, if the user resizes the window the images will grow in width as well as height. As the container is a fixed height the contents will grow past the end of the container and get cut off. If you would like to fix that, add a "complete" function to the animation to remove the height setting and make it dynamic again.
(Demo)
self.animate({
height: self.data("height0")
},function() {
self.height('');
});
You can also add height: auto; to maintain the default aspect ratio.
img.big {
width: 85%;
height: auto;
}
This is my code :
HTML
<html>
<body>
<div id="id">
<div class="one">
<img>
</div>
<div class="two">
<img>
</div>
<div class="one">
<img>
</div>
</div>
</body>
</html>
CSS
div{
float : left;
width : 33,3%
height : 100%;
}
img{
max-width : 100%;
max-height : 100%;
}
div#id{
position : fixed;
top : 0;
bottom : 0;
left : 0;
right : 0;
}
I have been looking for this for ages and can't figure it out...
Unknown height of divs and images images can change.
How can I vertical align the images inside the divs class="one"?
as this is an adaptive layout, images must be scaled to prevent overflow.
table-cell or line-height = 100% doen't seem to work.
Do I realy need javascript here?
I have tried a jquery code but it is above my knowledge and ends up changing the margin of all the images in my website... here it is :
$(document).ready(function() {
$(".one").each(function(){
var wrapH = $(".one").outerHeight();
var imgH = $("img").outerHeight();
var padTop = (wrapH-(imgH))/2;
if (padTop>0){
$("img").css("margin-top", padTop + "px");
}
});
});
You can do this easily enough with the following HTML:
<div class="wrap">
<div class="image-panel">
<img src="http://placekitten.com/300/300">
</div>
<div class="image-panel">
<img src="http://placekitten.com/400/600">
</div>
<div class="image-panel">
<img src="http://placekitten.com/200/600">
</div>
</div>
and apply the following CSS styling:
.wrap {
border: 1px dotted blue;
display: table;
width: 100%;
}
.image-panel {
display: table-cell;
vertical-align: middle;
text-align: center;
border: 1px dashed blue;
width: 33.3333%;
padding: 10px;
}
.image-panel img {
width: 100%;
display: block;
}
In this particular layout, I assumed that each panel has 33.3% of the total width and that the images auto scale to fit the width of the table-cell div.
Demo Fiddle: http://jsfiddle.net/audetwebdesign/ZBNh7/
Ok I finaly found a solution using jquery thx to bdmoura in this post :
https://stackoverflow.com/users/2442497/bdmoura
He showed me how to set an adaptive margin to the images according to image and div height.
here is th jquery code :
$(document).ready(function() {
$(".one").each(function(){
var wrap = $(this),
wrapH = wrap.outerHeight(),
img = wrap.find('img'),
image = new Image(),
imgH = 0,
padTop = 0;
image.onload = function () {
imgH = img.outerHeight();
padTop = ( wrapH - ( imgH ) )/2;
if ( padTop > 0 ){
img.css("margin-top", padTop + "px");
}
}
image.src = img.attr('src');
});
});
thx to him!
Yes. I think at this point you'll need jQuery / javaScript.
You can only really align img's or inline / inline-block elements to one another.
.block img {
/* display: inline; (default) */
display: inline-block;
vertical-align: middle;
}
fiddle: HERE
It would be great if you figure it out! We all need this.
You could use table-cell as mentioned... but in a responsive setting, this isn't going to cut it - especially if these blocks are in a responsive grid. Once you need to float, which is pretty much always - things are going to get really messy. Mystery.
I want to add a simple flag that changes its color when clicked (e.i. transparent flag changes to red when flagged) for the web based exam I'm working on. Could someone help or give me a script on this.
Have a picture of a transparent flag and a flagged flag side-by-side in one picture (for example, the transparent one at {0, 0} and the red one at {0, 22} assuming a size of 22x22 pixels) and switch between them with JavaScript and CSS:
(In the CSS file)
.flag {
background-image: url('flag.png');
display: inline-block;
height: 22px;
width: 22px;
}
.flag.active {
background-position: 0 22px;
}
(In the JavaScript file)
function toggleFlag(flag) {
if(/\bactive\b/.test(flag.className)) {
flag.className = flag.className.replace(/(^|\s)active(\s|$)/g, "");
} else {
flag.className = flag.className ? flag.className + ' active' : 'active';
}
}
Just call toggleFlag with the flag when it should be toggled.
The simplest way is to use two images. When it's clicked, you hide one image and show the other. Working demo here: http://jsfiddle.net/jfriend00/yzYJ3/
HTML:
<div id="container">
<img src="http://photos.smugmug.com/photos/344287800_YL8Ha-Ti.jpg">
<img src="http://photos.smugmug.com/photos/344284440_68L2K-Ti.jpg" style="display: none;">
</div>
CSS:
#container {position: relative; height: 66px; width: 100px;}
#container img {position: absolute; top:0; left:0}
JS (jQuery):
var flagged = false;
$("#container").click(function() {
$(this).find("img").toggle();
flagged = !flagged;
});
Have you looked at jQuery and the examples at jQueryUI - http://jqueryui.com/