How to change Fancybox preloader image? - javascript

I want replace default Fancybox1.3.4 image preloader (fancy_loading.png) with another preloader.
The Fancybox preloader coded not only in css, but also in javascript itself.
Seems, there are two places in javascript, at least:
_animate_loading = function() {
if (!loading.is(':visible')){
clearInterval(loadingTimer);
return;
}
$('div', loading).css('top', (loadingFrame * -40) + 'px');
loadingFrame = (loadingFrame + 1) % 12;
};
and
$.fancybox.showActivity = function() {
clearInterval(loadingTimer);
loading.show();
loadingTimer = setInterval(_animate_loading, 66);
};
$.fancybox.hideActivity = function() {
loading.hide();
};
So customizing the preloader will require modifying javascript too.
How can I change fancybox-1.3.4 javascript to set custom preloader image?

The CSS declaration is here:
#fancybox-loading div {
position: absolute;
top: 0;
left: 0;
width: 40px;
height: 480px;
background-image: url('fancybox.png');
}
They are using a sprite for the background image and changing the background-position to animate it. If you're going to use a loading.gif image, then you won't need to animate it.
You need to change the background-image path, height, and width to cater to your new image. You may want to comment out their JS code for the animation so that it doesn't conflict.
The loading div is being declared here:
$('body').append(
tmp = $('<div id="fancybox-tmp"></div>'),
loading = $('<div id="fancybox-loading"><div></div></div>'),
overlay = $('<div id="fancybox-overlay"></div>'),
wrap = $('<div id="fancybox-wrap"></div>')
);
You can either piggyback on the loading variable or simply change the styling on #fancybox-loading. You'll then need to remove any reference to loadingTimer and loadingFrame. Comment out this entire function:
/*_animate_loading = function() {
if (!loading.is(':visible')){
clearInterval(loadingTimer);
return;
}
$('div', loading).css('top', (loadingFrame * -40) + 'px');
loadingFrame = (loadingFrame + 1) % 12;
};*/
Modify the following function:
$.fancybox.showActivity = function() {
//clearInterval(loadingTimer);
loading.show();
//loadingTimer = setInterval(_animate_loading, 66);
};
That should do it. You don't want loading to have any setInterval on it since you won't be animating it, but you do want it to hide/show conditionally.

There are two options -
1) Upgrade to v2 as it is now using animated gif
2) Ĺ–eplace showActivity and hideActivity methods with yours, e.g., after including js file -
$.fancybox.showActivity = function() {
/* Add your animated gif to page ... */
}

You dont need to change so much just in js file comment some lines:
$.fancybox.showActivity = function() {
//clearInterval(loadingTimer);
loading.show();
//loadingTimer = setInterval(_animate_loading, 66);
};
Thats all and it will work, but remember change in correct file because where are jquery.fancybox-1.3.4.js and jquery.fancybox-1.3.4.pack.js

Related

Use jQuery zoom on background image

I'd like to use the jQuery zoom on background images. The problem is, it works on images with img tags only. Is there any way to use it on background-images aswell?
I can't use img tag, because this value comes from javascript.
For example, I have this div:
<div class="main-image" style="background-image: url("image.jpg");"></div>
$(document).ready(function() {
$('.main-image').zoom();
});
(function() {
let gallerys = document.querySelectorAll('.gallery');
gallerys.forEach(gallery => {
updateGalleryPictures(gallery);
});
})();
function updateGalleryPictures(gallery) {
// Get gallery's thumbnail images
let thumbnails = gallery.querySelectorAll('.thumbnail');
// Change the background-image property on click
thumbnails.forEach(thumbnail => {
thumbnail.addEventListener('click', () => {
updateMainImage(gallery, thumbnail.src)
});
});
// Initialize background-image property using the 1st thumbnail image
let firstThumbnail = thumbnails[0];
if (firstThumbnail === null || firstThumbnail === undefined) return;
updateMainImage(gallery, firstThumbnail.src)
}
function updateMainImage(gallery, src) {
// Get main image and check if it exists
let mainImage = gallery.querySelector('.main-image');
if (mainImage === null) return;
mainImage.style.backgroundImage = 'url(' + src + ')';
}
The following is the source code of the plugin in question. https://github.com/jackmoore/zoom/blob/master/jquery.zoom.js - it is not designed to work on background images as you can see from lines https://github.com/jackmoore/zoom/blob/master/jquery.zoom.js#L117 and https://github.com/jackmoore/zoom/blob/master/jquery.zoom.js#L231 two properties which aren't available on divs.
You may get some mileage using pure CSS moving on mousemove something like:
$('.main-image').mousemove(function(e){
var amountMovedX = (e.pageX * -1 / 2);
var amountMovedY = (e.pageY * -1 / 2);
$(this).css({
'background-size': '200%',
'background-position': amountMovedX + 'px ' + amountMovedY + 'px'}
);
});
.main-image {
background-image:url('https://www.travelandleisure.com/sites/default/files/styles/tnl_redesign_article_landing_page/public/1453920892/DUBAI-554088081-ABOVE0116.jpg?itok=dcoZnCrc');
background-size: 100%;
display:block;
height:200px;
width:200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main-image">
</div>

Trying to transition background image after it's loaded

I'm trying to change the background of my site when a button is clicked with a smooth transition. I understand this requires a pre-load but I'm not sure how to do this.
transition: background-image 3s linear;
js
document.getElementById("loadBG").onclick = function () {
let randomInt = Math.floor(Math.random() * (100 - 1) + 1);
document.getElementById(
"main"
).style.backgroundImage = `url(https://source.unsplash.com/1920x1080/?finland?sig=${randomInt})`;
};
The background-image property you are trying to apply is invalid.
Similarly the nextImage.src source attribute you are trying to apply is invalid as well.
See the code snippet comments for details.
You don't need to create an image node if all you're doing is applying a background-image property.
The Math.random() method can be optimised too (not essential, just a nitpick).
The original code (with console.log feedback) and a working version have been included in the code snippet below:
document.getElementById("loadBG-error").onclick = function() {
const nextImage = new Image();
nextImage.src = `url("https://source.unsplash.com/1920x1080/?finland?sig=${Math.random()}")`;
setTimeout(function() {
document.getElementById("main").style.backgroundImage = nextImage.src;
}, 3000);
console.log('incorrect background-image property url:',nextImage.src);
};
/*
This happens because the image node's (nextImage) src attribute is being
declared with a background-image css property, it starts with "url(... )",
when you have a filepath that doesn't start with a protocol (https://)
the browser will assume it's relative and prepend the current site's domain
to the url, e.g: "https://stacksnippets.net/url(...)".
In addition, the double apostrophes in that string are being ASCII encoded to "%22".
*/
document.getElementById("loadBG-fix").onclick = function() {
let randomInt = Math.floor(Math.random() * (100 - 1) + 1);
setTimeout(function() {
document.getElementById("main").style.backgroundImage = `url(https://source.unsplash.com/1920x1080/?finland?sig=${randomInt})`;
}, 500);
};
/*
If you just need to declare a background-image property for an existing element,
there is no need to create an image node first.
The Math.random() method can be further improved to return a set range(1)
with no floating point value (decimal)(2)
(1) Math.random() * (max - min) + min
(2) Math.floor()
*/
#main {
height: 300px;
width: 100%;
}
<div id="main"></div>
<button id="loadBG-error">Load BG (see error)</button>
<hr>
<button id="loadBG-fix">Load BG (apply fix)</button>
In order to load the image as a backgorund image, the container in which it is located must have a specific height and width. I set a height and width for the # main div.
And you don't need definitions like new image(If you have no other purpose with using new Image) because the src in the img and background url image are different from each other. You can't even those two. Because they work differently.
document.getElementById("loadBG").onclick = function() {
let url = `url("https://source.unsplash.com/1920x1080/?finland?sig=${Math.random()}")`;
setTimeout(function() {
document.getElementById("main").style.backgroundImage = url;
console.log("work")
}, 1000);
};
#main {
width: 100%;
height: 400px;
background-position: center;
background-size: cover;
}
<button type="button" id="loadBG">Click me</button>
<div id="main"></div>

How to refresh offsetHeight of div after changing img src on child using pure javascript?

I need to change an image in a div and then immediately centre it on the screen by calculating its height and width and then setting its left and top values. But when I change the img src and then try to get the div's offsetHeight and clientHeight, both the values are wrong. Strangely the offsetWidth and clientWidth values are correct.
Is there a way to refresh the div and get the correct value?
Edit: It appears that changing the image src makes everything after that not work. The change to the onclick event imageObj.onclick = function() {contractImageView(imageId);}; isn't working now either. If I comment out the if statement it all starts working again.
Below is the code...
// Get the page dimensions
var pageBody = document.getElementById(currentBody);
// If you couldn't get the page body, abort.
if (!pageBody) {
return;
}
var pageBodyHeight = window.innerHeight;
var pageBodyWidth = pageBody.offsetWidth;
var imageDiv = document.getElementById(imageId);
var imageObj = imageDiv.children[0];
var paraObj = imageDiv.children[1];
// If you can't get the div or its image, then abort.
if (!imageDiv || !imageObj) {
return;
}
// Check whether the image has been loaded yet, and load if needed
if (imageObj.src.indexOf('lazy_placeholder.gif') !== -1) {
for (item in photoLazyData) {
if (item === imageDiv.parentElement.id) {
imageObj.src = photoLazyData[item][imageDiv.id];
}
}
}
// Change the images class.
imageDiv.className = 'active_design_div';
imageDiv.style.visibility = 'visible';
imageDiv.style.opacity = 1;
// Set the objects new onclick method to collapse the image
imageObj.onclick = function() {contractImageView(imageId);};
// Calculate the right size
imageDiv.style.maxHeight = pageBodyHeight + 'px';
imageDiv.style.maxWidth = pageBodyWidth + 'px';
imageObj.style.maxHeight = pageBodyHeight + 'px';
imageObj.style.maxWidth = pageBodyWidth + 'px';
// Calculate the margins.
var imageDivWidth = imageDiv.offsetWidth || imageDiv.clientWidth;
// ## THIS IS WRONG IF THE ABOVE IF STATEMENT CHANGES THE SRC ##
var imageDivHeight = imageDiv.offsetHeight || imageDiv.clientHeight;
console.log(imageDiv.offsetHeight + ' : ' + imageDiv.clientHeight);
console.log(imageDiv.offsetWidth + ' : ' + imageDiv.clientWidth);
var leftOffset = (pageBodyWidth - imageDivWidth) / 2;
var topOffset = (pageBodyHeight - imageDivHeight) /2;
// Adjust styling to make the div visible and centred.
imageDiv.style.left = String(leftOffset) + 'px';
imageDiv.style.top = String(topOffset) + 'px';
currentId = imageId;
toggleBlackDiv();
Edit: I got this working in the end using Joonas89's answer. I basically moved the if statement that changes the src value to another function that is called prior to the one above. This solved the onclick problem mentioned above. I then changed the divs left/top from calculated values to 50% as detailed by Joonas89 (but on the container div rather than the img element), along with the new transform property. The div and img already had a position value of fixed so didn't need to change that.
Are you sure u want to calculate top and left positions? Wouldent it be better to add a class like this, that always centers it
.parentDiv{
position: relative;
}
.imageElement{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}

Preload images during scroll

I am using Jquery to alter the source of an image as the page scrolls. However, currently they are loading as they are displayed and i would like to have them preload several images prior to being shown.
HTML
<img src="/img/1.jpg" />
JQuery
$(window).load(function(){
// Array of images to swap between
var images = [/img/1.jpg, /img/2.jpg, /img/3.jpg, /img/4.jpg];
var totalImages = images.length;
var documentHeight = $(document).height();
// Work out how often we should change image (i.e. how far we scroll between changes)
var scrollInterval = Math.floor(documentHeight / totalImages);
$(document).scroll(function () {
// Which one should we show at this scroll point?
i = Math.floor($(this).scrollTop() / scrollInterval);
// Show the corresponding image from the array
$('img').attr('src', images[i]);
});
});//]]>
css
img {
position: fixed;
top: 0;
left: 0;
height: 100%;
}
body {
height: 5000px;
}
Attempt.
I would like to add something similar to this to,
$(document).scroll(function () {
function preload(arrayOfImages) {
$(arrayOfImages).each(function(){
(new Image()).src = this;
});
}
i = Math.floor([i]+'1');
preload([[i]]);
}
But cannot figure how to code it... (New to JS)
Inside your loop.
var nextTenImages = images.slice(i, i+10);
// preload the next image
preload(nextTenImages);
JSFiddle: http://jsfiddle.net/gvee/ygkWH/8/
EDIT: Credit to the following SO topic for preloading images: Preloading images with jQuery

How to show animated image from PNG image using javascript? [ like gmail ]

First of all,check out this image
Gmail uses this image to display the animated emoticon.
How can we show such animation using a png image?
I leave you a rough example so you can get a starting point:
I will use a simple div element, with the width and height that the animated image will have, the png sprite as background-image and background-repeat set to no-repeat
CSS Needed:
#anim {
width: 14px; height: 14px;
background-image: url(https://ssl.gstatic.com/ui/v1/icons/mail/im/emotisprites/wink2.png);
background-repeat: no-repeat;
}
Markup needed:
<div id="anim"></div>
The trick is basically to scroll the background image sprite up, using the background-position CSS property.
We need to know the height of the animated image (to know how much we will scroll up each time) and how many times to scroll (how many frames will have the animation).
JavaScript implementation:
var scrollUp = (function () {
var timerId; // stored timer in case you want to use clearInterval later
return function (height, times, element) {
var i = 0; // a simple counter
timerId = setInterval(function () {
if (i > times) // if the last frame is reached, set counter to zero
i = 0;
element.style.backgroundPosition = "0px -" + i * height + 'px'; //scroll up
i++;
}, 100); // every 100 milliseconds
};
})();
// start animation:
scrollUp(14, 42, document.getElementById('anim'))
EDIT: You can also set the CSS properties programmatically so you don't have to define any style on your page, and make a constructor function from the above example, that will allow you to show multiple sprite animations simultaneously:
Usage:
var wink = new SpriteAnim({
width: 14,
height: 14,
frames: 42,
sprite: "https://ssl.gstatic.com/ui/v1/icons/mail/im/emotisprites/wink2.png",
elementId : "anim1"
});
var monkey = new SpriteAnim({
width: 18,
height: 14,
frames: 90,
sprite: "https://ssl.gstatic.com/ui/v1/icons/mail/im/emotisprites/monkey1.png",
elementId : "anim4"
});
Implementation:
function SpriteAnim (options) {
var timerId, i = 0,
element = document.getElementById(options.elementId);
element.style.width = options.width + "px";
element.style.height = options.height + "px";
element.style.backgroundRepeat = "no-repeat";
element.style.backgroundImage = "url(" + options.sprite + ")";
timerId = setInterval(function () {
if (i >= options.frames) {
i = 0;
}
element.style.backgroundPosition = "0px -" + i * options.height + "px";
i++;
}, 100);
this.stopAnimation = function () {
clearInterval(timerId);
};
}
Notice that I added a stopAnimation method, so you can later stop a specified animation just by calling it, for example:
monkey.stopAnimation();
Check the above example here.
Take a look at this:
http://www.otanistudio.com/swt/sprite_explosions/
and http://www.alistapart.com/articles/sprites
The answer lies within.
CMS's answer is fine, but there's also the APNG (animated PNG) format that you may want to use instead. Of course the first frame (the one displayed even by browsers that don't support APNG) should be the "ending" frame and just specify to skip the first frame in the file.
Set the background image of an element to the first image, then use javascript to change the image by altering the style every x milliseconds.
You can do it with TweenMax and steppedEase easing : http://codepen.io/burnandbass/pen/FfeAa or http://codepen.io/burnandbass/pen/qAhpj whatever you choose :)
CSS #keyframes can be used in this case
#keyframes smile {
0% { background-postiion: 0 -16px;}
5% { background-postiion: 0 -32px;}
10% { background-postiion: 0 -48px;}
/*...etc*/
}

Categories

Resources