Can I do image orientation detection with html or css? - html

If I have an image on html page, can I use html or css do the following?
When width of the image is greater than height, set height to a fixed value and auto stretch width; when height is greater than width, set width and auto stretch height?
Thanks a lot!

No, this is not possible - conditional statements cannot be handled with HTML or CSS, but you have to do it with JS.
An example would be calculating (and perhaps storing for future use) the aspect ratio of an image to determine whether is it in landscape or portrait mode:
$(document).ready(function() {
$("img").each(function() {
// Calculate aspect ratio and store it in HTML data- attribute
var aspectRatio = $(this).width()/$(this).height();
$(this).data("aspect-ratio", aspectRatio);
// Conditional statement
if(aspectRatio > 1) {
// Image is landscape
$(this).css({
width: "100%",
height: "auto"
});
} else if (aspectRatio < 1) {
// Image is portrait
$(this).css({
maxWidth: "100%"
});
} else {
// Image is square
$(this).css({
maxWidth: "100%",
height: "auto"
});
}
});
});
See fiddle here - http://jsfiddle.net/teddyrised/PkgJG/
2019 update: As ES6 is becoming the defacto standard, the above jQuery code can be easily refactored into vanilla JS:
const images = document.querySelectorAll('img');
Array.from(images).forEach(image => {
image.addEventListener('load', () => fitImage(image));
if (image.complete && image.naturalWidth !== 0)
fitImage(image);
});
function fitImage(image) {
const aspectRatio = image.naturalWidth / image.naturalHeight;
// If image is landscape
if (aspectRatio > 1) {
image.style.width = '100%';
image.style.height = 'auto';
}
// If image is portrait
else if (aspectRatio < 1) {
image.style.width = 'auto';
image.style.maxHeight = '100%';
}
// Otherwise, image is square
else {
image.style.maxWidth = '100%';
image.style.height = 'auto';
}
}
div.wrapper {
background-color: #999;
border: 1px solid #333;
float: left;
margin: 10px;
width: 200px;
height: 250px;
}
<div class="wrapper">
<img src="http://placehold.it/500x350" />
</div>
<div class="wrapper">
<img src="http://placehold.it/350x500" />
</div>
<div class="wrapper">
<img src="http://placehold.it/500x500" />
</div>
However, if all you want is to ensure the image fits within an arbitrary sized container, using simple CSS will work:
div.wrapper {
background-color: #999;
border: 1px solid #333;
float: left;
margin: 10px;
width: 400px;
height: 400px;
}
div.wrapper img {
width: auto
height: auto;
max-width: 100%;
max-height: 100%;
}
<div class="wrapper">
<img src="http://placehold.it/500x350" />
</div>
<div class="wrapper">
<img src="http://placehold.it/350x500" />
</div>
<div class="wrapper">
<img src="http://placehold.it/500x500" />
</div>

Related

Display a Search bar on header on scroll HTML/CSS

I have a search bar which would like to display onto the header on scroll, a great example is like the one on this site: https://www.indiamart.com/
Approach 1 - A simple way to do this would be to detect a scroll & add and remove a class that contains display: none;
You can have an event listener -
window.addEventListener('scroll', function() {
if( window.scrollY !== 0) {
document.getElementById('searchBar').classList.add('scrolled');
} else {
document.getElementById('searchBar').classList.remove('scrolled');
}
});
With the CSS -
.noScroll
{
background: yellow;
position:fixed;
height: 50px; /*Whatever you want*/
width: 100%; /*Whatever you want*/
top:0;
left:0;
display:none;
}
/*Use this class when you want your content to be shown after some scroll*/
.scrolled
{
display: block !important;
}
.parent {
/* something to ensure that the parent container is scrollable */
height: 200vh;
}
And the html would be -
<div class="parent">
<div class ='noScroll' id='searchBar'>Content you want to show on scroll</div>
</div>
Here's a JSFiddle of the same - https://jsfiddle.net/kecnrh3g/
Approach 2 -
Another simple approach would be
<script>
let prevScrollpos = window.pageYOffset;
window.onscroll = function() {
let currentScrollPos = window.pageYOffset;
if (prevScrollpos > currentScrollPos) {
document.getElementById('searchBar').style.top = '-50px';
} else {
document.getElementById('searchBar').style.top = '0';
}
prevScrollpos = currentScrollPos;
}
</script>
with the html -
<div class="parent">
<div id ='searchBar'>Content you want to show on scroll</div>
</div>
and css
#searchBar {
background: yellow;
position: fixed;
top: 0;
left: 0;
height: 50px;
width: 100%;
display: block;
transition: top 0.3s;
}
.parent {
height: 200vh;
}
Here's a JSFiddle of the same - https://jsfiddle.net/0tkedcns/1/
From the same example, the idea is only to show/hide once user scroll the page using inline css display property, you can do the same or at least provide a code sample so we can help you!
HTML
<div class="search-bar">
<div class="sticky-search">
Sticky Search: <input type="text" value="search" />
</div>
</div>
CSS
.sticky-search {
display:none;
position:fixed;
top:0px;
left:0px;
right:0px;
background:blue;
padding:10px;
}
JS
var searchHeight = $(".search-bar").outerHeight();
var offset = $(".search-bar").offset().top;
var totalHeight = searchHeight + offset;
console.log(totalHeight);
$(window).scroll(function(){
if($(document).scrollTop() >= totalHeight) {
$('.sticky-search').show();
} else {
$('.sticky-search').hide();
}
});

rotated image is going out of parent div

I want to rotate the image, but it is going out of parent div.
<div>
<img src="https://cdn.eso.org/images/thumb300y/eso1907a.jpg">
<button class="rotate-button">rotate image</button>
</div>
jquery code
$('.rotate-button').on('click', function() {
var image = $(this).prev('img');
image.className = "rotated_90deg";
});
unrotated state:
rotated state:
how can I keep the image smaller in rotated state, so that it does not go out of parent div?
Try using the solution with scale property
$('.rotate-button').on('click', function() {
var image = $(this).prev('img');
image.className = "rotated_90deg";
});
.rotated_90deg {
transform: rotate(90deg) scale(0.5, 1);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<img src="https://cdn.eso.org/images/thumb300y/eso1907a.jpg">
<button class="rotate-button">rotate image</button>
</div>
"tranform rotate" does just that. It retains its original height, and the forging is done in a separate visual layer.
the best thing you can do is set the height of the area where the image rotates equal to the largest side of the image
const img = document.querySelector('img');
const {offsetHeight, offsetWidth} = img;
if(offsetWidth >= offsetHeight) {
img.parentElement.style.height = offsetWidth + 'px';
}
const rotations = [];
const rotateImage = () => {
rotations.push('rotate(45deg)');
img.style.transform = rotations.join(' ');
}
div { display: flex; }
img { transition: .3s; margin: auto; }
button { display: block; margin: auto; position: relative }
<div>
<img src="http://placekitten.com/300/200">
</div>
<button onclick=rotateImage()>Rotate</button>
hmm ... maybe I hastened to answer.
As a solution, "position: relative;" on the button
Put the image inside a container div, give it an id or class and set the overflow to hidden:
.imgContainer{
overflow: hidden;
}
Or if you want the picture to scale so it fits within the div, set max width and height:
.imgContainer img{
max-width: 100%;
max-height: 100%;
}

how can I make slideshow images scale proportionately at different viewport sizes?

I found code for a slideshow of images that I really like but that didn’t resize at different browser sizes. I tried using the vh property to make that happen but it didn’t work – I couldn’t get the images to scale proportionately. So I tried adding the properties max-width: 100% and height: auto which makes images scale proportionately. But the following occurs:
Only the widest image will scale proportionately at all points when resizing the browser window as you make it smaller; the others will remain static until the point where the browser window is equal to the image’s width as defined by the indicated width and height properties.
Images center in the resized browser window as long as it is 1732 px wide (the width of the widest image and of the “stage” id which contains the images) or greater.
Is there a way to make all of the images scale smaller at all browser sizes?
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
#stage {
margin: 1em auto;
width: 1732px;
height: 1080px;
}
#stage img {
position: absolute;
max-width: 100%;
height: auto;
}
#stage img {
padding: 10px;
border: ;
background: #fff;
}
#stage img:nth-of-type(1) {
animation-name: fader;
animation-delay: 4s;
animation-duration: 1s;
z-index: 20;
}
#stage img:nth-of-type(2) {
z-index: 10;
}
#stage img:nth-of-type(n+3) {
display: none;
}
#keyframes fader {
from { opacity: 1.0; }
to { opacity: 0.0; }
}
</style>
</head>
<div id="stage">
<img src="http://www.bartonlewisfilm.com/cf_spring_&_thompson_east_v_1080.jpg" width="1394" height="1080">
<img src="http://www.bartonlewisfilm.com/cf_suffolk_btw_rivington_&_stanton_v_1080.jpg" width="1732" height="1080">
<img src="http://www.bartonlewisfilm.com/dr_chrystie_93_v_1080.jpg" width="1165" height="1080">
<img src="http://www.bartonlewisfilm.com/cf_franklin_&_w_bway_v_1080.jpg" width="726" height="1080">
</div>
<script type="text/javascript">
// Original JavaScript code by Chirp Internet: www.chirp.com.au
// Please acknowledge use of this code by including this header.
window.addEventListener("DOMContentLoaded", function(e) {
var maxW = 0;
var maxH = 0;
var stage = document.getElementById("stage");
var fadeComplete = function(e) { stage.appendChild(arr[0]); };
var arr = stage.getElementsByTagName("img");
for(var i=0; i < arr.length; i++) {
if(arr[i].width > maxW) maxW = arr[i].width;
if(arr[i].height > maxH) maxH = arr[i].height;
}
for(var i=0; i < arr.length; i++) {
if(arr[i].width < maxW) {
arr[i].style.paddingLeft = 10 + (maxW - arr[i].width)/2 + "px";
arr[i].style.paddingRight = 10 + (maxW - arr[i].width)/2 + "px";
}
if(arr[i].height < maxH) {
arr[i].style.paddingTop = 10 + (maxH - arr[i].height)/2 + "px";
arr[i].style.paddingBottom = 10 + (maxH - arr[i].height)/2 + "px";
}
arr[i].addEventListener("animationend", fadeComplete, false);
}
}, false);
</script>
</html>
Just add max-width to #stage
#stage{
max-width: 100%;
}
and put !important to images max-width
#stage img {
max-width: 100% !important
}

Dynamically Scaling SVG

I'm working on a site where users can manipulate an SVG image through a couple of textboxes.
I would like to have the SVG scale to fit the container div.
For example, if the SVG was exactly the container's height and 10 pixels wide, then doubling the height would cause the apparent width to be 5 pixels.
My page is split roughly in half, with the numbers on the left and the image on the right. Resizing the browser thus causes the SVG's container element to change shape, meaning that I can't hardcode the container's dimensions in the SVG.
Every solution I've found online uses the viewBox attribute; however, I can't find a way to apply that without having a hard-coded container size.
Here is a fiddle with my editor setup:
https://jsfiddle.net/xyjs5b63/
Adjusting viewBox sounds like what you want. I'm not sure what you were doing that made it not work.
var svg = document.querySelector('svg');
var inputs = document.querySelectorAll('input');
var height_elem = inputs[0];
var width_elem = inputs[1];
height_elem.value = '100';
width_elem.value = '100';
height_elem.addEventListener("change", valueChange);
width_elem.addEventListener("change", valueChange);
function valueChange() {
svg.setAttribute('viewBox', "0 0 "+width_elem.value+" "+height_elem.value);
}
valueChange();
#out {
width: 100px;
height: 100px;
background-color: honeydew;
}
svg {
width: 100%;
height: 100%;
}
<div id="main">
<div id="in">
<input type="number"><br>
<input type="number">
</div>
<div id="out">
<svg>
<rect width="100%" height="100%"></rect>
</svg>
</div>
</div>
var rect = document.querySelector('rect');
var svg = document.querySelector('svg');
var inputs = document.querySelectorAll('input');
var height_elem = inputs[0];
var width_elem = inputs[1];
height_elem.value = '100';
width_elem.value = '100';
height_elem.addEventListener("change", valueChange);
width_elem.addEventListener("change", valueChange);
function valueChange() {
max = parseInt(height_elem.value) >= parseInt(width_elem.value) ? 'h' : 'w';
if (max == 'h') {
rect.setAttribute('height', "100%");
rect.setAttribute('width', (width_elem.value * 100 / height_elem.value)+"%");
}
else {
rect.setAttribute('width', "100%");
rect.setAttribute('height', (height_elem.value * 100 / width_elem.value)+"%");
}
}
valueChange();
#main {
width: 100%;
padding: 0;
}
#in {
float: left;
width: 40%;
height: 100%
}
#out {
margin: 10%;
width: 20vw;
height: 20vw;
}
svg {
width: 100%;
height: 100%;
}
<div id="main">
<div id="in">
Height: <input type="number"><br>
Width: <input type="number">
</div>
<br>
<div id="out">
<svg height="auto">
<rect></rect></svg>
</div>
</div>
Does this solve your problem?

HTML5 Canvas is not responsive

I have a main div, inside it are two div's each having a canvass. My problem is the canvass is not responsive, it overlaps when I resize the browser. please see below image.
Here is my HTML code:
<div id="mainContainer">
<div id="leftcolumn">
<h2>
Canvass Graph1
</h2>
<canvas id="Canvass_One"></canvas>
</div>
<div id="rightcolumn">
<h2>Canvass Graph2</h2>
<canvas id="Canvass_Two"></canvas>
</div>
</div>
CSS Code:
#mainContainer
{
width:100%;
height: 100%;
}
#leftcolumn
{
float:left;
display:inline-block;
width: -moz-calc(100% - 50%);
width: -webkit-calc(100% - 50%);
width: calc(100% - 50%);
height: 100%;
background: blue;
}
#rightcolumn {
float:left;
display:inline-block;
width: -moz-calc(100% - 50%);
width: -webkit-calc(100% - 50%);
width: calc(100% - 50%);
height: 100%;
background-color : red;
}
JS to set height and width of Canvass
var ctx2 = $("#Canvass_One").get(0).getContext('2d');
ctx2.canvas.height = 300; // setting height of canvas
ctx2.canvas.width = 560; // setting width of canvas
var ctx1 = $("#Canvass_Two").get(0).getContext('2d');
ctx1.canvas.height = 300; // setting height of canvas
ctx1.canvas.width = 560; // setting width of canvas
Canvas:
Again, my problem is when I minimized/resize the browser window , the canvass overlaps. thank you for any help. My case is that I'm not using image within my div, it's just a pure canvass with chart js framework to create a graph.
Sample data:
var barData = {
labels: ['CityA', 'CityB', 'CityC', 'CityD', 'CityF', 'CityG'],
datasets: [
{
label: '2010 customers #',
fillColor: '#382765',
data: [2500, 1902, 1041, 610, 1245, 952]
},
{
label: '2014 customers #',
fillColor: '#7BC225',
data: [3104, 1689, 1318, 589, 1199, 1436]
}
]
};
The trick is to set the style width/height in combination with the attribute width/height, as the style controls display and attribute controls image.
#Canvass_One, #Canvass_Two
{
width: 100%;
height: 100%;
}
Note: Chart.js appears to have its own setting do deal with responsiveness like this, Chart.defaults.global.responsive = true;, so one might need to combine the two.
Here is a sample to show how it works.
Chart.defaults.global.responsive = true;
var barData = {
labels: ['CityA', 'CityB', 'CityC', 'CityD', 'CityF', 'CityG'],
datasets: [
{
label: '2010 customers #',
fillColor: '#382765',
data: [2500, 1902, 1041, 610, 1245, 952]
},
{
label: '2014 customers #',
fillColor: '#7BC225',
data: [3104, 1689, 1318, 589, 1199, 1436]
}
]
};
var ctx2 = $("#Canvass_One").get(0).getContext('2d');
ctx2.canvas.height = 300; // setting height of canvas
ctx2.canvas.width = 560; // setting width of canvas
//ctx2.fillStyle = "#FF0000";
//ctx2.fillRect(10,0,450,75);
var clientsChart = new Chart(ctx2).Bar(barData);
var ctx1 = $("#Canvass_Two").get(0).getContext('2d');
ctx1.canvas.height = 300; // setting height of canvas
ctx1.canvas.width = 560; // setting width of canvas
ctx1.fillStyle = "#0000FF";
ctx1.fillRect(10,0,450,75);
#mainContainer
{
width:100%;
height: 100%;
}
#leftcolumn
{
float:left;
display:inline-block;
width: 50%;
height: 100%;
background: blue;
}
#rightcolumn
{
float:left;
display:inline-block;
width: 50%;
height: 100%;
background-color : red;
}
#Canvass_One, #Canvass_Two
{
width: 100%;
height: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js"></script>
<div id="mainContainer">
<div id="leftcolumn">
<h2>Canvass Graph1</h2>
<canvas id="Canvass_One"></canvas>
</div>
<div id="rightcolumn">
<h2>Canvass Graph2</h2>
<canvas id="Canvass_Two"></canvas>
</div>
</div>