jQuery/DOM does not update viewport after changing sizes - javascript

In a DIV I have inserted images that I always want to display in 60% width of the original size of the image file (so that the images are on the same scale). For this I use the following jQuery-Script:
var cont_slider_ori_width;
var cont_slider_ori_height;
$('.img-drawing').each(function(i) {
var img = $(this);
$("<img>").attr("src", $(img).attr("src")).load(function() {
cont_slider_ori_width = this.width; // to get the original width of the image-file
cont_slider_ori_height = this.height; // to get the original height of the image-file
});
img.width(cont_slider_ori_width * 0.6);
// alert($(this).attr('src')); // If I avtivate this alert command, the size-changes work as it should ...
});
The HTML-Markup:
<div class="cont-slider-item-img-wrapper">
<div class="cont-slider-item-drw">
<img class="img-drawing" src="image1.png" alt="" width="1042" height="412">
</div>
<div class="cont-slider-item-drw">
<img class="img-drawing" src="image2.png" alt="" width="1042" height="411">
</div>
</div>
SCSS:
.cont-slider-item-img-wrapper {
display: flex;
justify-content: center;
.cont-slider-item-drw {
img {
width: auto;
height: auto;
}
}
}
But unfortunately this does not work (the size is not changed). It's strange that when I activate the 'alert' command, the redraw for the respective elements works as expected after each confirmation of the alarm box.
What did I do wrong? Thanks in advance for any help!!

With the friendly help of Chris G (see comments above) I was able to solve the problem. This is the jQuery/Javascript code, which is working now:
var cont_slider_ori_width;
var cont_slider_ori_height;
$('.img-drawing').each(function(i) {
cont_slider_ori_width = $(this).get()[0].naturalWidth;
$(this).width(cont_slider_ori_width * 0.6);
});

Related

Make Gif file play when user scrolls over and and stop afterwards

I found this while browsing and this plays and stops gifts on hover:
http://docs.embed.ly/docs/tutorial-play-and-stop-gifs
I would like to maintain this functionality but by playing only once, when user scrolls over that section. I believe jQuery waypoints can be combined with this to achieve this, but my JS expertise fails to combine the two.
jQuery Waypoints
https://github.com/imakewebthings/waypoints
I believe an example HTML structure for this to start out would be something like this:
<div class="gifs row small-up-4">
<div class="column"> </div>
<div class="column"> </div>
<div class="column"> </div>
<div class="column"> </div>
<div class="column"> </div>
<div class="column"> </div>
<div class="column"> </div>
<div class="column"> </div>
<div class="column"> </div>
<div class="column"> </div>
<div class="column"> </div>
<div class="column"> </div>
<div class="column"> </div>
<div class="column"> </div>
<div class="column"> </div>
<div class="column"> </div>
</div>
.gifs a {
position: relative;
display: block;
}
.gif-preload {
display: none;
}
.gif-loading {
position: absolute;
width: 40px;
height: 40px;
font-size: 40px;
color: #fff;
top: 0;
left: 0;
}
$.embedly.defaults.key = '1d5c48f7edc34c54bdae4c37b681ea2b';
$('.gifs a').embedly({
display: function(obj) {
if (obj.type === 'photo') {
var $this = $(this);
// Create the static image src with Embedly Display.
var src = $.embedly.display.display(obj.url, {
query: {
animate: false
}
});
// Add static gif placeholder to the parent
$this.html('<img class="gif-holder" src="' + src + '" />');
// Start preloading the actually gif.
$this.append('<img class="gif-preload" src="' + obj.url + '" />');
// Create a promise so we can keep track of state.
$this.data('promise', $.Deferred());
// Get the element we added.
var elem = $this.find('.gif-preload').get(0);
// If the image is not in cache then onload will fire when it is.
elem.onload = function() {
$this.data('promise').resolve();
};
// If the image is already in the browsers cache call the handler.
if (elem.complete) {
$this.data('promise').resolve();
}
// Set the static gif url so we can use it later.
$(this).data('static_url', src);
} else {
// remove li if it's not an image.
$(this).parent().remove();
}
}
}).on('mouseenter', function() {
var $this = $(this);
// Set the hover state to true so that the load function knows to run.
$this.data('hover', true);
// Create a function to load the gif into the image.
var load = function() {
if ($this.data('hover') === true) {
// Remove the loading image if there is one
$this.find('.gif-loading').remove();
// Swap out the static src for the actually gif.
$this.find('img.gif-holder').attr('src', $this.data('embedly').url);
}
};
// Add the load function to the done callback. If it's already resolved
// this will fire immediately.
$this.data('promise').done(load);
// Add a spinner if it's not going to play right away.
if ($this.data('promise').state() === 'pending') {
// Add a loading spinner.
$this.append('<i class="gif-loading fa fa-spinner fa fa-spin"></i>');
// we need to center it over the image.
$this.find('.gif-loading').css({
top: $this.height() / 2 - 20,
left: $this.width() / 2 - 20
});
}
}).on('mouseleave', function() {
var $this = $(this);
// Make sure the load function knows we are no longer in a hover state.
$this.data('hover', false);
// Remove the spiner if it's there.
$this.find('.gif-loading').remove();
// Set the src to the static url.
$this.find('img.gif-holder').attr('src', $(this).data('static_url'));
});
This is not a perfect answer, but it will guide you a bit on how to implement.
Solution: everytime you scroll, check GIFS in screen an play them and stop those who aren't in screen.
1) everytime you scroll...
Simply using
$(document).scroll(onScroll);
onScroll function is gonna be called everytime you scroll.
2) check GIFS in screen an play them and stop those who aren't in screen
To know when a HTML element is in the screen, you can head to "Check if element is visible after scrolling" question.
So for example, based on this answer we could use:
/**
* Is element within visible region of a scrollable container
* #param {HTMLElement} el - element to test
* #returns {boolean} true if within visible region, otherwise false
*/
function isScrolledIntoView(el) {
var rect = el.getBoundingClientRect();
return (rect.top >= 0) && (rect.bottom <= window.innerHeight);
}
Final Solution
Combining your code, with the above, you can use this:
function isScrolledIntoView(el) {
var rect = el.getBoundingClientRect();
return (rect.top >= 0) && (rect.bottom <= window.innerHeight);
}
function animateGifsInScreen() {
$('.gifs a').each(function(index, el) {
if(isScrolledIntoView(el)) {
$(el).trigger('mouseenter');
} else {
$(el).trigger('mouseleave');
}
});
}
$(document).scroll(animateGifsInScreen);
What I'm doing: every time you scroll, I iterate over all gifs and play/stop them depending if they are on screen or not. For play/stop, I just trigger mouseenter/mouseleave respectively.
This may not be the ideal solution for your case but I'm pretty sure it will guide you to the correct answer.
There is a sample: https://jsfiddle.net/e8av59g2/ (it has a bug, you have to scroll at least once to made it work hehe).

Display/Load Different Background Image Depending on Device

I'd like to use a large background image for desktop users and a different smaller background image for mobile users.
I found this answer
.img-responsive.mobile {
display: none;
}
#media only screen and (max-device-width: 480px) {
.img-responsive {
display: none;
}
.img-responsive.mobile {
display: block;
}
}
<div class="row">
<img src="image\bannerimages\Career.png" class="img-responsive careerpage">
<img src="image\bannerimages\Career-mobile.png" class="img-responsive careerpage mobile">
<h2 class="careerbannertext">LIFE AT TEKNOTRAIT</h2>
...
</div>
how-to-display-different-images-in-mobile-and-desktop-devices
Problem with this solution is it loads two images - I'd like to only load the image necessary. How can this be done?
Using pure Javascript
javascript:
<script>
var screenWidth = screen.width;
var imgElement = document.createElement("img");
var imgUrl;
if(screenWidth < 480) {
// for mobile devices
imgUrl = document.createTextNode("url of img 1");
} else {
// otherwise
imgUrl = document.createTextNode("url of img 2");
}
var row = document.getElementByClassName("row");
row.insertBefore(imgElement, row.childNodes[0]);
</script>
html:
<div class="row">
<h2 class="careerbannertext">LIFE AT TEKNOTRAIT</h2>
...
</div>
I think html code is crystal clear so I just describe javascript code. first of all gets width of screen then checks whether it is a mobile device or others. then inserts url of proper image in created element and finally inserts it as the first element of div.row element.
Also you can do this easier using jQuery.
<div class="row">
<img id="img1" src="image\bannerimages\Career.png" class="img-responsive careerpage">
<img id="img2" src="image\bannerimages\Career-mobile.png" class="img-responsive careerpage mobile">
<h2 class="careerbannertext">LIFE AT TEKNOTRAIT</h2>
...
</div>
var w = window;
var x = w.innerWidth;
if(x<568){
document.getElementsById('img2');
}
else{
document.getElementsById('img1');
}
Not sure without a full syntax, try this way Hope it works)

JavaScript - Make an image turn white on click

I've got a bunch of images, on click I want the images to turn white emulating some kind of fade effect. So you click it and for 1 second it fades from the original image to just white. I also need it to turn back to the original image when the user clicks something else.
Is this possible with JavaScript? - If so what should I be looking at (I'm really bad with graphics).
I've had a go at trying this with opacity but I don't want the background to be visible behind the image
Psuedo-element Solution
You could use a wrapper with a pseudo-element to overlay what you're looking for -- and the animations are handled by a toggled CSS class (which is ideal for performance).
CodePen Demonstration
HTML
<div class="whiteclicker">
<img src="http://lorempixel.com/400/200" alt=""/>
</div>
SCSS
#import "compass/css3/transition";
body { background: gainsboro; text-align: center; }
.whiteclicker {
display: inline-block;
position: relative;
&::after {
content: "";
display: block;
position: absolute;
top:0; left:0; right:0; bottom:0;
background: white;
opacity: 0;
#include transition(opacity 1s ease);
}
&.active::after {
opacity: 1;
}
}
JS
$('.whiteclicker').click(function(){
$(this).toggleClass('active');
});
To ameliorate the Spencer Wieczorek solution (the way two seems to be the best solution on my opinion) :
What about creating the white div on the fly (and fade it in and out) instead of put it in the html code ?
See the fiddle.
$("#myImage").click(function(){
$(this)
.parent().css({position:'relative'}).end()
.after($('<div>')
.hide()
.css({position:'absolute'
, top: $(this).position().top
, left: $(this).position().left
, width: $(this).width()
, height: $(this).height()
, background: '#FFF'
})
.fadeIn('fast')
.on({
click : function(e){
$(this).fadeOut('fast', function(){ $(this).remove();});
}
})
);
});
Then, you don't have anything to add to the html code or in the css styles, Jquery does everything.
#Spencer Wieczorek : I did my own answer, because I did not agree with your way of designing the css style (the fixed position is really not good, especially if the page is scrolled for example...). Mine is more ... standalone-y ;)
You might want to try having two images stacked on each other.
See this:
<script type="text/javascript">
var image1 = '<img class="images" src="Image 1" onClick="switch();" />';
var image2 = '<img class="images" src="Image 2" onClick="switch();" />';
var currentImage = 1;
function switch(){
if(currentImage==1){
currentImage++;
document.getElementById("image").innerHTML = image2;
}
if(currentImage==2){
currentImage--;
document.getElementById("image").innerHTML = image1;
}
}
</script>
<style>
.images{ position:fixed; top: 0; left: 0; }
</style>
<img class="images" src="Black image" />
<div id="image"><img class="images" src="Image 1" onClick="switch();" /></div>
For the fade I'm just gonna see how you could do it.
EDIT:
<script type="text/javascript">
var fadecount = 100;
function fade() {
document.getElementById("imageToFade").style.opacity = fadecount;
fadecount--;
if(fadecount==0){
clearTimeout(fade);
}
}
function start_fade(){
var fade = setTimeout(fade(), 10);
}
</script>
With Base 64 you can just have the binary version of the picture and then an all white picture and based on the .click you reassign the src to the white base64...
document.getElementById("img").src = "data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAUA
AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
9TXL0Y4OHwAAAABJRU5ErkJggg=="
just change to the all white version after the click, technically js driven from click event, and doesn't involve two different elements existing just at different layers...

jQuery center multiple dynamic images in different sized containers

So I've found similar questions but none that answer all the questions I have and I know there must be a simple jQuery answer to this. I've got multiple images that are being dynamically placed in their own containing div that have overflow:hidden, they need to fill their containing divs and be centered(horizontally and vertically) also. The containing divs will be different sizes as well.
So in short:
multiple different sized images fill and center in containing div.
containing divs will be different sizes.
will be used multiple times on a page.
images fill box proportionally
Hopefully this image helps explain what I'm after.
Click here to view the image.
HTML I'm using but can be changed
<div class="imageHolder">
<div class="first SlideImage">
<img src="..." alt="..."/>
</div>
<div class="second SlideImage">
<img src="..." alt="..."/>
</div>
<div class="third SlideImage">
<img src="..." alt="..."/>
</div>
</div>
And the CSS
.imageHandler{
float:left;
width:764px;
height:70px;
margin:1px 0px 0px;
}
.imageHolder .SlideImage{
float:left;
position:relative;
overflow:hidden;
}
.imageHolder .SlideImage img{
position:absolute;
}
.imageHolder .first.SlideImage{
width:381px;
height:339px;
margin-right:1px;
}
.imageHolder .second.SlideImage{margin-bottom:1px;}
.imageHolder .second.SlideImage, .imageHolder .third.SlideImage {
width: 382px;
height: 169px;
}
Ask me anything if this doesn't make sense,
thanks in advance
Here's a JQuery alternative to my CSS solution:
JSFiddle: http://jsfiddle.net/yczPs/
$(".SlideImage").each(function () {
var container = $(this),
img = $(this).find("img"),
margin;
if (img.width() / container.width() < img.height() / container.height()) {
img.css("width", container.width());
margin = -(img.height() * img.width() / container.width() - container.height()) / 2;
img.css("margin-top", margin);
} else {
img.css("height", container.height());
margin = -(img.width() * img.height() / container.height() - container.width()) / 2;
img.css("margin-left", margin);
}
});
I just coded that on the fly and haven't done any extensive testing, but it seems to be working fine for the few test cases I threw at it. Let me know if it isn't working properly for you.
Here is a simplest solution I could come up with :)
Full working example on JSFiddle.
http://jsfiddle.net/L3HhX/1/
$(document).ready(function() {
$('.center-trigger').click(function() {
centerImageInTheContainers();
});
function centerImageInTheContainers() {
$('.container').each(function(i, v) {
var container = $(this);
var myImg = $(this).find('img');
myImg.css('top', calculatePosition(container.height(), myImg.height()));
myImg.css('left', calculatePosition(container.width(), myImg.width()));
});
}
function calculatePosition(containerSize, imageSize) {
return 0 - ((imageSize - containerSize) / 2);
}
});
If I understand correctly, this can be done with pure CSS, granted that you 1) are OK using background images instead of <img> elements, and 2) don't need to support IE8 and below.
JSFiddle: http://jsfiddle.net/6nKKX/
HTML:
<div class="imageHolder">
<div class="first SlideImage"></div>
<div class="second SlideImage"></div>
<div class="third SlideImage"></div>
</div>
CSS: (The parts relevant to the solution)
.imageHolder .SlideImage {
background-repeat: no-repeat;
background-position: center center;
background-size: cover;
}
.imageHolder .first.SlideImage {
background-image: url('...');
}
.imageHolder .second.SlideImage {
background-image: url('...');
}
etc.
Alternatively, you can set the background images inline in the HTML with <div class="first SlideImage" style="background-image: url('...');"></div>
Basically, background-size: cover; means scale the image until it covers the entire box (cropping whatever is outside of it), and background-position: center center; centers the image for you.

Center image on jQuery Slider in HTML

I have an jQuery Content Slider. But i have an problem, where tall images is stretch. Isn't it possible to center the image. Some says that i need to set the overflow to hidden. But it doesn't make any differences.
Best regard Morten Starck
The html code:
<ul class="bxslider">
<li>
<img id="propImageSliderLarge" src="http://billeder.edc.dk/edcmedia/2012/04-April/04/4fac343a-5d4b-4aab-8205-f57f165bc484_Size687x458.jpg"/></li>
<li>
<img id="propImageSliderLarge" src="http://billeder.edc.dk/edcmedia/2012/04-April/04/7bdfb0cc-47ec-4afa-9fc7-aa2cbb9d43a0_Size687x458.jpg"/></li>
<li>
<img id="propImageSliderLarge" src="http://billeder.edc.dk/edcmedia/2012/04-April/04/aad1d457-285d-42e3-8e68-e243bd2988d4_Size687x458.jpg"/></li>
<li>
<img id="propImageSliderLarge" src="http://billeder.edc.dk/edcmedia/2012/04-April/04/768fda69-af61-4322-a60b-012040d78384_Size687x458.jpg"/></li>
<li>
<img id="propImageSliderLarge" onload="FixImages(true)" src="http://www.blog.designsquish.com/images/uploads/victorian-flatbush-old-hous_thumb.jpg" /></li>
And the Javascript:
<script type="text/javascript">
$('.bxslider').bxSlider({
pagerCustom: '#bx-pager'
});
</script>
and the CSS code:
#propImageSliderLarge {
width: 530px;
height: 400px;
overflow: hidden;
position: relative;
}
There're two things you're doing wrong here. First, you're using the same ID for multiple elements, this isn't valid. I think you intended to use CSS classes. Second, you're setting the width and height attributes of the IMG tag, when in fact you should set these attributes on the container (in this case the LI). Try the following:
Change your markup to this
<li class="propImageSliderLarge">
<img src="http://billeder.edc.dk/edcmedia/2012/04-April/04/4fac343a-5d4b-4aab-8205-f57f165bc484_Size687x458.jpg"/>
</li>
Change your CSS to this
.propImageSliderLarge {
width: 530px;
height: 400px;
overflow: hidden;
position: relative;
text-align: center; /* this will centre your image in the LI */
}
Update the image dimension if larger than LI container
This script assumes variables set for containerWidth and containerHeight so just set these to whatever your LI container size is and it'll resize the images to the max constraints of the container so you can see the entire image.
function resizeImage(img) {
var imgWidth = parseInt($(img).width());
var imgHeight = parseInt($(img).height());
if (imgWidth > containerWidth || imgHeight > containerHeight) {
$(img).width(containerWidth);
$(img).height(containerHeight);
}
}​
First, change the attribute id to attribute class. Id means Identifier, and as the name goes, two things cannot have same identifier. To center the images, give an id to ul tag and add following css:
text-align: center;
Try this...not sure if it'll work.
you can run the slider in onload and check it out.
<script type="text/javascript">
$(document).ready(function(){
$('.bxslider').bxSlider({
mode: 'fade',
captions: true
});
});
</script>
otherwise, you can use anyone suitable slider in http://bxslider.com/examples

Categories

Resources