Compare images with JS - javascript

I'm currently working on a site and there will be an image in the background with the following dimensions: 100vw, 100vh – But of course I want the page to be responsive and this is my plan:
It is ok, to distort this background-image a bit, but I should never be distorted to much, so I want to create multiple different images, for different aspect-ratios and sizes and whenever the page is being loaded, or resized, I would like to have a script that looks at the viewport: aspect-ratio and size, then looks at all the images and finds the one that is most similar to the viewport and then sets that image as the background-images of: div class="bg-overlay"
This is what I have so far:
HTML:
<div class="bg-overlay"></div>
CSS:
bg-overlay {
position: fixed;
width: 100vw;
height: 100vh;
background-image: url("resources/Test-Screens/RZ_BG_1920x1080_16-9.png");
background-size: 100vw 100vh;
}
JS:
var bgOverlayDiv = document.querySelector(".bg-overlay");
// Image-Library START
var bg_1280x720 = {
name: 'RZ_BG_1280x720_16-9.png',
width: '1280',
height: '720'
};
bg_1280x720.ratio = bg_1280x720.width / bg_1280x720.height;
var bg_1920x1080 = {
name: 'RZ_BG_1920x1080_16-9.png',
width: '1920',
height: '1080'
};
bg_1920x1080.ratio = bg_1920x1080.width / bg_1920x1080.height;
var bg_3840x2160 = {
name: 'RZ_BG_3840x2160_16-9.png',
width: '3840',
height: '2160'
};
bg_3840x2160.ratio = bg_3840x2160.width / bg_3840x2160.height;
var bg_4000x4000 = {
name: 'RZ_BG_4000x4000_1-1.png',
width: '4000',
height: '4000'
};
bg_4000x4000.ratio = bg_4000x4000.width / bg_4000x4000.height;
var bg_2000x2000 = {
name: 'RZ_BG_2000x2000_1-1.png',
width: '2000',
height: '2000'
};
bg_2000x2000.ratio = bg_2000x2000.width / bg_2000x2000.height;
var bg_1000x1000 = {
name: 'RZ_BG_1000x1000_1-1.png',
width: '1000',
height: '1000'
};
bg_1000x1000.ratio = bg_1000x1000.width / bg_1000x1000.height;
var bg_1080x1920 = {
name: 'RZ_BG_1080x1920_9-16.png',
width: '1080',
height: '1920'
};
bg_1080x1920.ratio = bg_1080x1920.width / bg_1080x1920.height;
// Image-Library END
var viewportRatio = undefined;
var chosenImage = undefined;
function changeBgOverlay() {
// Calculate viewport aspect-ratio. START
viewportRatio = window.innerWidth / window.innerHeight;
console.log(viewportRatio);
// Calculate viewport aspect-ratio. END
chosenImage = bg_1080x1920; // Add: Choose most suitable image.
bgOverlayDiv.style.backgroundImage = "url('resources/Test-Screens/" + chosenImage.name + "')";
}
changeBgOverlay();
window.addEventListener('resize', changeBgOverlay);
^- I can't really share a fiddle, because there are images involved, I hope it's clear what this script is doing, if not, please tell me, I can also just send someone the folder-structure that I have on my computer, with all the images, but this is basically what's happening right now:
First I'm creating multiple objects for every image in my folder-structure, these objects have properties: name, width, height, (aspact-)ratio – Then I calculate the viewport-aspect-ratio (var viewportRatio) – Then there is a line that, right now, says: chosenImage = bg_1080x1920; (This is where the script should look for the most suitable image, right now, I'm just manually telling it to use the object called: bg_1080x1920) – Then it replaces the image.
Screenshot of the folder containing the images:
I already played around with this for a while, but I don't really now how to do this, I would very much appreciate any sort of input. Thank You! – Simon

Related

How do I have a background image change within a div using JS?

My issue is I am trying to get a background image to change every second within the first div of a travel blog I have been working on using JS. I am also having text display on top of the image. There are couple tutorials on YouTube but they just arent working for me.
my css is:
#title{
background-image: url("../images/Nature5.jpg");
background-size: cover;
padding-top: 350px;
padding-bottom: 350px;
}
And my Javascript is:
var changingImages = document.querySelector('title');
var images = [
"url('../images/Nature1.jpg')",
"url('../images/Nature2.jpg')",
"url('../images/Nature3.jpg')",
"url('../images/Nature4.jpg')",
"url('../images/Nature5.jpg')",
"url('../images/Nature6.jpg')"
]
setInterval( function () {
var bg = images[Math.floor(Math.random() * images.length)]
title.style.backgroundImage = bg;
},1000)
Perhaps the images are too large or maybe I'm just too new to JS.
Any help is appreciated!
I tried placing the variabule "changingImages" within the function also changing the "title.style.backgroundImage = bg;" to be more spacific.
please try this one
add class selector in query selector argument '.title'
var changingImages = document.querySelector('.title'); // the change
var images = [
"url('../images/Nature1.jpg')",
"url('../images/Nature2.jpg')",
"url('../images/Nature3.jpg')",
"url('../images/Nature4.jpg')",
"url('../images/Nature5.jpg')",
"url('../images/Nature6.jpg')"
]
setInterval( function () {
var bg = images[Math.floor(Math.random() * images.length) + 1] // the change
changingImages.style.backgroundImage = bg; // the change
},1000)
hope this work

Using clientHeight causes JavaScript function to fail

I set the following CSS at the top of my file:
#img1, #img2, #img3 {
background: url("bates-sprite.jpeg");
background-repeat: no-repeat;
object-fit: none;
}
#img1 {object-position: 0 0;
width: 816px; // full size 3264
height: 612px; // full size 2448
}
This is the relevant part of my JavaScript:
var tempDiv = document.createElement('div');
tempDiv.setAttribute("id", "bigImg" + figNum);
// Make tempDiv High enough to hold the scaled up image.
// This line is causing a problem
let imgHeight = document.getElementById("img1").clientHeight;
// let imgHeight = "1224px";
tempDiv.style.height = parseInt(imgHeight) + parseInt("400px") + "px";
If I set imgHeight explicitly to 1224 pixels, the function works perfectly. If instead I use clientHeight, it fails. How can I fix it?
Client height will only give a number, but you need to add the type of that, also like (px, %, rem), to make it work.

Full screen background image minus flexible top-nav bar

This is my first post here and I haven't been able to find the answer to my question.
I am building a page and I want a picture to fill the entire screen, from the bottom of the top-nav bar (menu etc..) to the bottom of the screen. Only issue I have... the bar is responsive : it's taller on very large screen and much smaller on mobiles, which of course impacts my background image differently on different screens.
Here's my css :
.backgroundimage{
background-image: url(https://file...);
background-repeat: no-repeat;
background-size: cover;
width: 100%;
min-height: 100vh;
background-position: center center;
position: relative;
}
</style>
So I've tried multiples things for hours, playing around with the "vh" property.
For example :
min-height:calc(100vh - 17vh)
That gives decent result on my laptop, but not on a larger screen. So I've been trying to find the fonction or class that represents the navHeight, but I can't find a proper way to do it and nothing is working so far. I've tried stuff like :
min-height:calc(100vh - $headerHeight)
And so on... This is a shopify store and I have no knowledge in js, which may explain why I'm struggling. Here's some js code that revolves around the header, but nowhere can I find a way to remove the height of the header. Any idea or direction to give me ? Thanks.
JS code (not in proper order):
theme.headerNav = (function() {
var selectors = {
siteNav: '#SiteNav',
siteNavCompressed: '#SiteNavCompressed',
siteNavParent: '#SiteNavParent',
siteNavItem: '.site-nav__item',
stickyNavWrapper: '#StickNavWrapper',
stickyNav: '#StickyNav'
};
function init() {
sizeNav();
initMegaNavs();
initHeaderSearch();
$(window).on('resize.headernav', $.debounce(250, sizeNav));
}
window.Meganav = (function() {
var Meganav = function(options) {
this.cache = {
$document: $(document),
$page: $('.page-element')
};
var defaults = {
$meganavs: $('.meganav'),
$megaNav: $('.meganav__nav'),
$meganavToggle: $('.meganav-toggle'),
$meganavDropdownContainers: $('.site-nav__dropdown-container'),
$meganavToggleThirdLevel: $('.meganav__link-toggle'),
$meganavLinkSecondLevel: $('.meganav__link--second-level'),
$meganavLinkThirdLevel: $('.meganav__link--third-level'),
$meganavDropdownThirdLevel: $('.site-nav__dropdown--third-level'),
isOpen: false,
preventDuplicates: false,
closeOnPageClick: false,
closeThirdLevelOnBlur: false,
activeClass: 'meganav--active',
drawerClass: 'meganav--drawer',
meganavDropdown: '.site-nav__dropdown',
meganavLinkClass: 'meganav__link',
drawerToggleClass: 'drawer__nav-toggle-btn',
drawerNavItem: '.drawer__nav-item',
navCollectionClass: 'meganav__nav--collection',
secondLevelClass: 'meganav__link--second-level',
thirdLevelClass: 'meganav__link-toggle',
thirdLevelContainerClass: 'site-nav__dropdown--third-level',
noAnimationClass: 'meganav--no-animation'
};
theme.HeaderSection = (function() {
function Header() {
theme.stickyHeader.init();
theme.headerNav.init();
theme.Notify = new window.Notify();
theme.NavDrawer = new window.Drawers('NavDrawer', 'left');
drawerSearch();
}

Changing Div Width via Javascript

I'm making a website for my art gallery. Part of what I need to do is display images to the viewers in a way in which they can view them. And I want to do this without reducing the quality of the images, or having to save all of my images in many different sizes to cater to every user.
So, I've made a Javascript function to resize my images to fit completely on the viewer's screen. My code looks like
<img src="[image.png]" onload="setGoodHeight(this);">
where the function setGoodHeight(element) is defined as:
function setGoodHeight (element) {
if(window.innerHeight-50 < element.height) {
var h = element.height;
var w = element.width;
element.height = window.innerHeight - 50;
element.width = w * element.height / h;
}
if (window.innerWidth-100 < element.width) {
var h = element.height;
var w = element.width;
element.width = window.innerWidth - 100;
element.height = h * element.width / w;
}
}
In shorthand, this first checks whether the image is higher than the screen it's trying to be displayed on, and if it is (it usually is) the image is resized to fit comfortably on the screen. Then it checks if, after this, the image is wider than the screen, and if so it shrinks it further. I have verified that this code works.
However, the image is contained within a class called .post I want the post area to wrap to that of the image, at least in width, and so at the end of my javascript function, I added this code:
element.parentNode.width = element.width + 40;
But the post doesn't resize itself. For reference, the code on the actual webpage concerning this can be boiled down to
<div class="post">
<img src="[image.jpg]" onload="setGoodHeight(this);">
</div>
and if you need to look around it a little more it can be found at this link.
How about a pure CSS solution, it will also update magically if the user resizes their browser.
html, body, #fullscreen {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
#fullscreen {
background: url('http://www.nathanrouse.org/wp-content/uploads/2014/01/CrashTestDummy.jpg') center center no-repeat;
background-size: cover;
}
<div id="fullscreen"></div>
Check the doc for background-size. There are other values like "contain" that might suit you better.
I think you're looking for
item.naturalHeight
item.naturalWidth
I was using these in a function to set the max-height & max-width
function imageLoad(item) {
$(item).attr("max-height", item.naturalHeight);
$(item).attr("max-width", item.naturalWidth);
}

Setting div Background using Trianglify

I have some problems using the Trianglify plugin. I would like to use it to set the background of a div. How can I do this? I couldn't find a proper example.
Here's my sample code:
<script>
var pattern = Trianglify({
width: window.innerWidth,
height: window.innerHeight
});
document.body.appendChild(pattern.canvas())
</script>
Also, can I have divs with different backgrounds that come from Trianglify?
One DIV
Here is an example of setting a DIV background to a Trianglify pattern. It cheats a bit and sets the DIV child node to the pattern but it should work for you.
var something = document.getElementById('something');
var dimensions = something.getClientRects()[0];
var pattern = Trianglify({
width: dimensions.width,
height: dimensions.height
});
something.appendChild(pattern.canvas());
The DIV has an id of something and the CSS styles are set on the div for height and width.
Working example JSFiddle: http://jsfiddle.net/u55cn0fh/
Multiple DIVs
We can easily expand this for multiple DIVs like so:
function addTriangleTo(target) {
var dimensions = target.getClientRects()[0];
var pattern = Trianglify({
width: dimensions.width,
height: dimensions.height
});
target.appendChild(pattern.canvas());
}
JSFiddle: http://jsfiddle.net/u55cn0fh/1/
Multiple DIVs as a true background-image
The above are simply appending the pattern to the DIV as a child node instead of setting it as a background. The good news is that we can indeed use the background-image CSS property like so:
function addTriangleTo(target) {
var dimensions = target.getClientRects()[0];
var pattern = Trianglify({
width: dimensions.width,
height: dimensions.height
});
target.style['background-image'] = 'url(' + pattern.png() + ')';
}
JSFiddle: http://jsfiddle.net/abL2kc2q/
I'm pretty late to this answer, but I think it's still valuable:
If you aren't satisfied with using pattern.png() to generate a PNG version (like I wasn't), then you can also use pattern.svg() to set a SVG background with a little more work.
I always tend to lean towards using SVG backgrounds as typically they are crisper. In a test case I ran, using the SVG version also saved bits (although it's relative because sending a Trianglify background is a bit of a burden to begin with).
Characters in the base64 SVG encoding: 137284
Characters in the base64 PNG encoding: 195288
Converting the SVG to a base64 encoding then setting it as the background image can be achieved as follows:
// Create the Trianglify pattern
var pattern = Trianglify({
cell_size: 30,
variance: 0.75,
x_colors: 'random',
y_colors: 'match_x',
palette: Trianglify.colorbrewer,
stroke_width: 1.51,
});
// Serialize the SVG object to a String
var m = new XMLSerializer().serializeToString(pattern.svg());
// Perform the base64 encoding of the String
var k = window.btoa(m);
// Query the element to set the background image property
var element = document.getElementsByTagName('header')[0];
// Set the background image property, including the encoding type header
element.style.backgroundImage = 'url("data:image/svg+xml;base64,' + k + '")';
Hope this helps!
IN my case I had to use a class to use multiple instances of the same background image :
var obj = {
'trianglifiedlightblue': ['#a5cade', '#b7d5e5', '#d5e6f0', '#006ab4', '#e8f2f7', '#cee2ed'],
'trianglifiedbleu': ['#004e83', '#005f9f', '#004879', '#006ab4', '#004777', '#005f9f'],
'trianglifiedviolet': ['#680036', '#830447', '#e62f8e', '#c76c9b'],
'trianglifiedrouge': ['#5f0308', '#851117', '#cf363f', '#e86d74']
};
function addTriangle(classname) {
targets = document.getElementsByClassName(classname);
for (i = 0; i < targets.length; i++) {
target = targets[i];
if (target != null) {
var dimensions = target.getClientRects()[0];
var pattern = Trianglify({
width: dimensions.width,
height: dimensions.height,
x_colors: obj[classname],
cell_size: 100 + Math.random() * 200
});
target.style['background-image'] = 'url(' + pattern.png() + ')';
}
}
}
addTriangle('trianglifiedlightblue');
addTriangle('trianglifiedbleu');
addTriangle('trianglifiedviolet');
addTriangle('trianglifiedrouge');
div {
height: 100px;
width: 500px;
margin:10px;
float:left;
background:#efefef;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/trianglify/0.2.1/trianglify.min.js"></script>
<div class="trianglifiedlightblue"></div>
<div class="trianglifiedbleu"></div>
<div class="trianglifiedviolet"></div>
<div class="trianglifiedrouge"></div>
or if you prefer to keep an ID you can try this :
http://jsfiddle.net/thecpg/Lecdhce6/10/

Categories