according to this question
i want div to be float up not just fix dynamic height!
jquery masonry use float left and right but i want it look like newspaper columns!
any idea?
its my html:
`<div class="paper">
<div class="ticket" style="height: 116px;background-color: rgb(121,89,118);">1</div>
<div class="ticket" style="height: 75px;background-color: rgb(121,89,118);">2</div>
....
</div>`
and js is:
var $grid = $('.paper').masonry({
// options
itemSelector: '.ticket',
columnWidth: '.ticket',
percentPosition: true,
isOriginLeft: false
});
$grid.imagesLoaded().progress( function() {
$grid.masonry('layout');
});
and it's final result:
You could work with display: flex; note that older browsers do not support this completly
<div class="box">
<div class="stuff" style="background-color: cyan; height: 100px;">1</div>
<div class="stuff" style="background-color: red; height: 200px;">2</div>
<div class="stuff" style="background-color: lime; height: 150px;">3</div>
<div class="stuff" style="background-color: orange; height: 50px;">4</div>
<div class="stuff" style="background-color: yellow; height: 300px;">5</div>
<div class="stuff" style="background-color: pink; height: 200px;">6</div>
</div>
.box{
display: flex;
flex-flow: column wrap;
width: 220px;
height: 600px;
}
.stuff{
width: 100px;
margin: 4px;
}
Fiddle
You could calculate the heights using jQuery, and then set the appropriate margins: https://jsfiddle.net/6u8jypmr/1/
It works for a dynamic width and height.
var heightdiv1 = $("#div1").css("height");
var heightdiv2 = $("#div2").css("height");
var margindiv2 = parseInt(heightdiv1) + parseInt(8);
var margindiv3 = parseInt(margindiv2) + parseInt(heightdiv2) + parseInt(8);
var heightdiv4 = $("#div4").css("height");
var heightdiv5 = $("#div5").css("height");
var margindiv5 = parseInt(heightdiv4) + parseInt(8);
var margindiv6 = parseInt(margindiv5) + parseInt(heightdiv5) + parseInt(8);
var widthdiv = $("#div1").css("width");
var marginleftdiv = parseInt(widthdiv) + parseInt(8);
$("#div2").css("margin-top", margindiv2);
$("#div3").css("margin-top", margindiv3);
$("#div5").css("margin-top", margindiv5);
$("#div6").css("margin-top", margindiv6);
$("#div4").css("margin-left", marginleftdiv);
$("#div5").css("margin-left", marginleftdiv);
$("#div6").css("margin-left", marginleftdiv);
Related
I've been trying to make use of html2canvas to take a screenshot of a element
I noticed an image inside the div element that uses the object-fit property becomes stretched after the html2canvas screenshot
Is there a walk around for this. Here is my code
<script>window.addEventListener('load', function () {
var bigCanvas = $("<div>").appendTo('body');
var scaledElement = $("#Element").clone()
.css({
'transform': 'scale(1,1)',
'transform-origin': '0 0'
})
.appendTo(bigCanvas);
var oldWidth = scaledElement.width();
var oldHeight = scaledElement.height();
var newWidth = oldWidth * 1;
var newHeight = oldHeight * 1;
bigCanvas.css({
'width': newWidth,
'height': newHeight
})
html2canvas(bigCanvas, {
onrendered: function(canvasq) {
var image = document.getElementById('image');
image.style.width='300px';
image.src = canvasq.toDataURL();
bigCanvas.remove() ;
}
});}) </script>
While html goes as
<div id="Element" class="container">
<div class="bg-light p-3 text-center">
<h3>iPhone 12 Pro Max</h3>
<div class="m-2 shadow" style="height:400px;width:100%;">
<img src="img/agency.jpeg" style="object-fit:cover;height:100%;width:100%;" />
</div>
<h4>Now available for free</h4>
</div>
</div>
<div class="container" style="width:100%;border:2px solid black;overflow:hidden">
<img src="" id="image" style="max-width:100%;"/>
</div>
I had the same issue, unfortunally it seems that html2cavas doesn't support the object-fit property but i resolve with flexbox and the result it's good, it's important to set the width and height for parent node:
.logo-preview-inner {
height: 200px;
width: 200px;
border-radius: 50%;
border: solid 1px #e6e6e6;
margin: 0 auto;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
position: relative;
img {
width: 100%;
}
where the class .logo-preview-inner is the parent node and the image is the child
i hope to help you!
I have a situation that I'm trying to do, and I need your help because I do not have much experience with JavaScript.
First please take a look at this code where I was through ajax, parse from xml file into html. I set the picture as background of #clickMapFlashContainer, and prepend hotspots clickable circles into #clickAreas which results to get 5 clickable circles, which look like this: (screenshot) http://prntscr.com/d3v97y (Currently when we get to the site, site looks like this)
You'll notice that I have 5 different clickable circles with _clickable id and class circle. Each circle with _clickable id have onclick="onclick(id)" and this function should be executed onclick.
Below I have divs with same id but without _clickable and all of 5 have display: none... Display none needs to be changed to display block when click on corresponding id with _clickable circle.
However, there is one thing I must mention, in a situation when the div with class clickMapItem text is display block, background image from #clickMapFlashContainer should be visible as it is, it is only necessary to change the text below the image, but in situation when the div with class clickMapItem multiImageText is display block, background image from #clickMapFlashContainer should be display none because clickMapItem multiImageText contains a gallery and background should not be seen.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="clickMap">
<div id="clickMapFlashContainer" style="background-image: url(../../../../../../linkableblob/internet_en/9492/image/steel_agg_bof_flash_en-image.jpg;); width: 560px; height: 560px; background-repeat: no-repeat;">
<div id="clickAreas">
<div id="clickMap_item_11024_clickable" class="circle" onclick="changeStyle(id);" style="background: #004593; position: absolute; top: 11px; left: 219px; width: 76px; height: 76px; opacity: 0.5; border-radius: 100%; cursor: pointer;"></div>
<div id="clickMap_item_11006_clickable" class="circle" onclick="changeStyle(id);" style="background: #004593; position: absolute; top: 388px; left:
250px; width: 66px; height: 66px; opacity: 0.5; border-radius: 100%; cursor: pointer;"></div>
<div id="clickMap_item_11004_clickable" class="circle" onclick="changeStyle(id);" style="background: #004593; position: absolute; top: 155px; left:
189px; width: 135px; height: 135px; opacity: 0.5; border-radius: 100%; cursor: pointer;"></div>
<div id="clickMap_item_10450_clickable" class="circle" onclick="changeStyle(id);" style="background: #004593; position: absolute; top: 208px; left:
436px; width: 105px; height: 105px; opacity: 0.5; border-radius: 100%; cursor: pointer;"></div>
<div id="clickMap_item_9510_clickable" class="circle" onclick="changeStyle(id);" style="background: #004593; position: absolute; top: 469px; left:
350px; width: 75px; height: 75px; opacity: 0.5; border-radius: 100%; cursor: pointer;">
</div>
<div id="clickMap_item_default" class="clickMapItem text">
<p>Due to long-standing contact with customers RHI has detailed knowledge of the requirements that steelworkers place on refractories. This is why RHI has been involved in the development of package and system solutions for many years und nowadays offers customized high-end solutions for basically all individual customer requirements.</p>
</div>
</div>
<!-- clickMap text -->
<div id="clickMap_item_9510" class="clickMapItem text" style="display: none;">
back
<p>text</p>
</div>
<!-- clickMap gallery -->
<div id="clickMap_item_10450" class="clickMapItem multiImageText" style="display: none;">
back
<p>text</p>
</div>
<!-- clickMap text -->
<div id="clickMap_item_11004" class="clickMapItem text" style="display: none;">
back
<p>text</p>
</div>
<!-- clickMap gallery -->
<div id="clickMap_item_11006" class="clickMapItem multiImageText" style="display: none;">
back
<p>text</p>
</div>
<!-- clickMap text -->
<div id="clickMap_item_11024" class="clickMapItem text" style="display: none;">
back
<p>text</p>
</div>
</div>
</div>
<script type="text/javascript">
jQuery(function ($) {
$.ajax({
type: "GET",
url: 'steel_agg_bof_flash_en.xml',
dataType: "xml",
success: xmlParser
});
function xmlParser(xml) {
$(xml).find("basics").each(function () {
var img = $(this).find('imgpath').text();
$('#clickMapFlashContainer').css({
'background-image' : 'url(' + img + ')',
'width' : '560px',
'height' : '560px',
'background-repeat' : 'no-repeat',
});
});
$(xml).find("hotspot").each(function () {
var position = $(this).find('position').text();
var arr = position.split(",");
var hotspotid = $(this).find('hsid').text();
$('#clickAreas').prepend('<div id="'+ hotspotid +'_clickable" class="circle" onclick="changeStyle(id);" style="background: #004593; position: absolute; top: ' + arr[1] + 'px' + '; left: ' + arr[0] + 'px' +'; width: ' + Math.floor(arr[2]/3.28148) + 'px; height: '+ Math.floor(arr[2]/3.28148) + 'px; opacity: 0.5; border-radius: 100%; cursor: pointer;"></div>');
});
}
});
</script>
I found a solution and working properly, but this is JavaScript newbie code as you can see, please take a look and suggest what can be changed, because I think it is a messy code. Whether it is a good idea to use Array.prototype.slice.call to convert NodeList to an Array and then check whether the div contains one of these classes?
function changeStyle(hotspotid) {
var hotspot = hotspotid.replace('_clickable', '');
var hotspots = document.querySelectorAll(".clickMapItem.text, .clickMapItem.multiImageText"); // Return a NodeList
var nodesArray = Array.prototype.slice.call(hotspots, 0); //Convert NodeList to an Array
nodesArray.forEach(function(item) {
console.log(item);
});
var i;
for (i = 0; i < hotspots.length; i++) {
hotspots[i].style.display = "none";
}
if (hotspotid == "clickMap_item_10450_clickable" || hotspotid == "clickMap_item_11006_clickable") {
document.getElementById('clickMapFlashContainer').style.display = "none";
}
if (hotspots[0].style.display == "") {
document.getElementById(hotspot).style.display = '';
document.getElementById("clickMap_item_default").style.display = "none";
} else if (hotspots[1].style.display == "") {
document.getElementById("clickMapFlashContainer").style.display = "none";
}
};
function backClose() {
var sections = document.getElementsByClassName("clickMapItem");
var i;
for (i = 0; i < sections.length; i++) {
sections[i].style.display = "none";
}
document.getElementById('clickMapFlashContainer').style.display = "";
document.getElementById("clickMap_item_default").style.display = "";
}
}
I am using CSS Flex in order to display three DIVs consequential in a wrapper.
The width dimension for the first DIV (item0) is to 50px.
I need to change the height of the wrapper and keep the original width for item0 and item1 DIVs inside the wrapper.
My current problem is that:
When re-sizing the wrapper, item for flex (item0) get a different width. size
Please click the two buttons in the example to see the change in dimension.
I would like to know:
Why the width size change?
How to maintain the width size for item0 and item2same as my original CSS settings?
Notes:
I understand scroll-bar appears taking space. How I could I keep item0 and item2 at a fix width and item1 stretching to fill up the remaining space? (I have tried to use % but I cannot get the result wanted).
var btn0 = document.getElementById('btn0');
var btn1 = document.getElementById('btn1');
var item0 = document.getElementById('item0');
var result = document.getElementById('result');
var wrapper = document.getElementById('wrapper');
btn0.addEventListener('click', function(event) {
wrapper.style.height = '25px';
result.value = item0.getBoundingClientRect().width;
});
btn1.addEventListener('click', function(event) {
wrapper.style.height = '350px';
result.value = item0.getBoundingClientRect().width;
});
#wrapper {
width: 250px;
height: 350px;
background-color: gray;
overflow: auto;
}
#flex-container {
display: flex;
}
#item0 {
width: 50px;
background-color: red;
height: 150px;
}
#item1 {
width: 150px;
background-color: orange;
height: 150px;
}
#item2 {
width: 50px;
background-color: pink;
height: 150px;
}
<div id="wrapper">
<div id="flex-container">
<div id="item0" class="item">a
</div>
<div id="item1" class="item">b
</div>
<div id="item2" class="item">c
</div>
</div>
</div>
<button id='btn0' type="button">Smaller wrapper</button>
<button id='btn1' type="button">Bigger wrapper</button>
item0 width is: <input id="result"type="text">
Use flex: 0 0 50px for the item0 style.
See jsfiddle
It tells the flexbox layout don't grow and don't shrink and give it a width of 50px.
It is always good to use the flex: property for flexbox items because the default value for it may be different from browser to browser.
(Actually your problem doesn't happen in firefox for example)
When the width of the container is reduced, all child elements are reduced proportionally too.
Add flex: 0 0 auto; to item0 and item2. It disallows element to shrink to its minimum when there is not enough space.
var btn0 = document.getElementById('btn0');
var btn1 = document.getElementById('btn1');
var item0 = document.getElementById('item0');
var result = document.getElementById('result');
var wrapper = document.getElementById('wrapper');
btn0.addEventListener('click', function(event) {
wrapper.style.height = '25px';
result.value = item0.getBoundingClientRect().width;
});
btn1.addEventListener('click', function(event) {
wrapper.style.height = '350px';
result.value = item0.getBoundingClientRect().width;
});
#wrapper {
width: 250px;
height: 350px;
background-color: gray;
overflow: auto;
}
#flex-container {
display: flex;
}
#item0 {
flex: 0 0 auto;
width: 50px;
background-color: red;
height: 150px;
}
#item1 {
width: 150px;
background-color: orange;
height: 150px;
}
#item2 {
flex: 0 0 auto;
width: 50px;
background-color: pink;
height: 150px;
}
<div id="wrapper">
<div id="flex-container">
<div id="item0" class="item">a
</div>
<div id="item1" class="item">b
</div>
<div id="item2" class="item">c
</div>
</div>
</div>
<button id='btn0' type="button">Smaller wrapper</button>
<button id='btn1' type="button">Bigger wrapper</button>
item0 width is: <input id="result"type="text">
I would like to scroll to the bottom of the div content-main, so that the button Button is displayed at the bottom of the window. I tried the following:
<div class="container">
<div class="content-main">
dynamic content dynamic content.....
<button>Button </button>
</div>
<div class ="footer"></div>
</div>
<script>
var mainContentHeight = $(".content-main").height();
var footerHeight = $(".content-footer").height();
window.scrollTo(0, mainContentHeight - footerHeight);
</script>
This works differently, when I test it in two monitors with different size. How to display the button at the bottom of the window?
Instead binding scrollTo to the window object, bind it to the element you want to scroll:
var container = $('.container')[0];
var contentMain = $('.content-main')[0];
var mainContentHeight = $(".content-main").height();
var footerHeight = $(".content-footer").height();
container.scrollTo(0, mainContentHeight - footerHeight);
.container {
overflow: auto;
height: 100px;
}
.content-main {
height: 100%;
position: relative;
border: 1px solid #000;
height: 1000px;
}
.content-footer {
height: 50px;
}
button {
position: absolute;
bottom: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="content-main">
dynamic content dynamic content.....
<button>Button </button>
</div>
<div class="content-footer"></div>
</div>
I'm making something similar to an iphone layout (a bunch of tiles with pictures/numbers that you can click on to get more information). After the layout has been set, I'd like a click-event to expand one of the tiles to be full screen. Right now, it moves the tiles so that the layout is re-adjusted. Is it possible to get masonry to stop rendering so that one tile get's enlarged over the other tiles?
The following is what I've tried (but unsuccessfully). Note: It uses d3.js to generate the div's for masonry to use.
function drawGrid(divname,orders)
{
var mydiv = d3.select(divname);
$(divname).masonry({
itemSelector: '.g1',
isAnimated: true,
//isResizable: true
});
var myd = mydiv.selectAll("div");
var mygs = myd.data(orders,function(d){ return d.orderid;})
.enter().append("div")
.attr("class","g1")
.append("g");
var x1 = mygs.append("div")
.attr("class","tickerdiv")
.text(function(d){ return d.ticker; });
var ActiveOrder = "1";
$(divname+' .g1').click(function() {
//$(this).show('maximised');
console.log("clicked")
$(this).animate({"display":"none","position": "absolute",
"top": "0",
"left": "0",
"width": "100%",
"height": "100%",
"z-index": 1000 }, 1000);
});
var x = [];
x.redraw = function(o)
{
x1.text(function(d){ return d.ticker; });
}
return x;
}
and from the css file:
.g1 { min-height:80px; width: 100px; margin: 15px; float: left; background-color: RGB(223,224,224); border-radius: 10px; vertical-align: middle; text-align: center; padding-top: 20px;}
EDIT Ok, my first answer was not useful here - absolute positioning won't work in case of masonry's/Isotope's relatively positioned container with absolute positioned elemens contained therein; the solution is rather to take the content of a masonry/Isotope element out of the DOM on click and append it temporarily to the body. You can see the basic idea in my dirty swedish sandbox
<!-- masonry/Isotope item large -->
<div class="item large">
<div class="header">
<p>Click here</p>
</div>
<div class="minimised">
<p>Preview</p>
</div>
<div class="maximised">
<p>Content</p>
<button id="screen-overlay-on">Screen overlay on</button>
<div id="screen-overlay-background"></div>
<div id="screen-overlay-content">
<p>Content</p>
<button id="screen-overlay-off">Screen overlay off</button>
</div>
</div>
</div>
<script type="text/javascript">
$(document).ready(function(){
$('#screen-overlay-on').click(function(){
var sob = $('#screen-overlay-background').detach();
var soc = $('#screen-overlay-content').detach();
sob.appendTo('body');
soc.appendTo('body');
$('#screen-overlay-background').toggleClass("active");
$('#screen-overlay-content').toggleClass("active");
});
$('#screen-overlay-background, #screen-overlay-off').click(function(){
$('#screen-overlay-background').toggleClass("active");
$('#screen-overlay-content').toggleClass("active");
});
});
</script>
With CSS like
#screen-overlay-background {
display: none;
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 100%;
background-color: #333;
zoom: 1;
filter: alpha(opacity=50);
opacity: 0.5;
z-index: 1000;
}
#screen-overlay-content {
display: none;
position: absolute;
top: 50%;
left: 50%;
height: 240px;
width: 320px;
margin: -120px 0 0 -160px;
background-color: #FFF;
z-index: 1000;
}
#screen-overlay-background.active, #screen-overlay-content.active {
display: block;
}
You can add a :hover to the element in css and change the z-index. You could easily change this on click with a class as well...
.item {
z-index:1
}
.item:hover{
z-index:2500;
}