I'm trying to make a slide show using multiple background-images and using the background-position property to animate them. Here is the code:
HTML:
<div class="slide_holder" id="slide_holder"></div>
CSS:
.slide_holder {
float: left;
width: 1440px;
height: 720px;
background-image: url("images/gc-h-s-01.jpg"), url("images/gc-h-s-02.jpg"), url("images/gc-h-s-03.jpg");
background-repeat: no-repeat;
background-size: 100%;
background-position: 0px, 1440px, 2880px;
transition: 1s;
}
JS:
var imageIndex = 1;
var x;
var PosValues = ["0px, 1440px, 2880px", "-1440px, 0px, 1440px", "-2880px, -1440px, 0px"]
startSlides();
function startSlides() {
x = setInterval(IncAndWrite, 1000);
}
function IncAndWrite() {
var i;
document.getElementById("slide_holder").style.backgroundPosition = PosValues[imageIndex];
imageIndex++;
if (imageIndex > 2) {imageIndex = 0;}
}
The concept is that the background-position values for each background-image change every 1s keeping only one image in the visible frame.
The above mentioned code works just fine, but I do not want to write individual position values for different screen sizes (as my website is responsive). So I wrote the following code:
JS:
var imageIndex = 1;
var x;
var UnitRes = 1440;
var PosValues = [
UnitRes*0 + "px, " + UnitRes*1 + "px, " + UnitRes*2 + "px;",
UnitRes*(-1) + "px, " + UnitRes*0 + "px, " + UnitRes*1 + "px;",
UnitRes*(-2) + "px, " + UnitRes*(-1) + "px, " + UnitRes*0 + "px;"]
startSlides();
function startSlides() {
x = setInterval(IncAndWrite, 1000);
}
function IncAndWrite() {
var i;
document.getElementById("slide_holder").style.backgroundPosition = PosValues[imageIndex];
imageIndex++;
if (imageIndex > 2) {imageIndex = 0;}
}
The basic concept is that you put the width of the container in UnitRes and then the values get calculated. But this does not seem to work. The background-position values don't change at all.
What I thought was causing the problem:
In the second case of js code I'm putting a variable value inside an array which I thought is not being converted to a string type while inputing it in the CSS syntax.
What I tried doing:
I used typeof but it is showing the type as string
Then I tried using:
document.getElementById("slide_holder").style.backgroundPosition = PosValues[imageIndex].valueOf();
but still it's not working. I also used alert(PosValues[imageIndex]); to check if the values are ok and they are.
Please help me.
The problem was that in first time you have defined parameters without semicolon ; and in second example you have placed it what broke the script.
Related
I don`t know how i can perform an image check in a block.
That hard to explain, just follow the link and see for yourself. If you scroll down to the cards, wait few seconds you will seen that image go outside from his start point, like this enter image description here
and leaves behind itself void.
I want to fix this in such a way that the image could not go beyond its own size.
My JavaScript code:
"use strict";
var imgArr = document.getElementsByClassName('imgArr');
[].forEach.call(imgArr, function(item, i, arr) {
// set variables
var randValWidth;
var randValHeight;
// take the width and height of each image
var size = {
'widthImg': arr[i].width,
'heightImg': arr[i].height
};
// set time
setInterval(function() {
// add arguments for tRand() and wRand()
var randW = tRand(-size.widthImg/4, size.widthImg/4);
var randH = wRand(-size.heightImg/4, size.heightImg/4);
// start animation
motionItem();
}, 2000);
// find a random value between min and max values
function tRand(min, max) {
randValWidth = Math.floor(Math.random() * (max - min) + min);
};
function wRand(min, max) {
randValHeight = Math.floor(Math.random() * (max - min) + min);
};
// animate elements
function motionItem() {
arr[i].style.transform = 'translate3d(' + randValWidth + 'px,' + randValHeight + 'px,' + 0 + ')';
};
});
How i can fix it?
It's just an image and CSS, no need for JavaScript for that. For example, the box contain that image have height 100px but the image have height 200px so they let image full in div and after that use translate the image to image to make it move up and down.
.box {
width:900px;
height:400px;
background-color:blue;
}
.img {
width:90%;
height:auto;
position:relative;
animation:4s movingUp infinite linear;
transition:4s;
}
#keyframes movingUp {
0%{
transform:translateY(0px);
}
25% {
transform:translateY(50px);
}
50%{
transform:translateY(100px);
}
75%{
transform:translateY(-50px);
}
100% {
transform:translateY(0px);
}
}
<div class="box">
<img class="img"src="http://res.cloudinary.com/dhue87np7/image/upload/v1508082124/sample.jpg" />
</div>
I'm trying to add two .height()'s together in order to get a responsive number for my onScroll event how do I add two of these together?
I'm general, I'm just trying to get the animation to fire after getting to the bottom of everything above the element. Is there any other way to do that besides just adding the heights of everything above?
window.addEventListener('load', function() {
$(window).scroll(function() {
var eventScroll = window.pageYOffset;
var eventScrollAmount = ($("#sectionOneImage").height() + $("#bannerOne").height());
if( eventScroll > eventScrollAmount) {
$("#sectionOneImage").addClass("animated slideInLeft ");
}
else {
$("#sectionOneImage").removeClass("animated slideInLeft ");
}
});
});
Here's an example of how to grab two heights using vanilla JS.
var sizeOfOne = document.getElementById('one').offsetHeight;
var sizeOfTwo = document.getElementById('two').offsetHeight;
document.getElementById('hook').innerHTML = 'The first div is ' + sizeOfOne + ' pixels in height, the second div is ' + sizeOfTwo + ' pixels in height. The total size of both div\'s are ' + (sizeOfOne + sizeOfTwo) + ' pixels.';
#one {
height: 50px;
background: red;
}
#two {
height: 75px;
background: blue;
}
<div id="hook"></div>
<div id="one"></div>
<div id="two"></div>
The script in this fiddle takes a long text and breaks it up in different divs. It does that by cloning the whole text in each div and incrementing the margin for each page so that only the required text is displayed. Like so:
for (var i = 2; i < page_no + 1; i++) {
$("#stuff").append("<div id='page" + i + "' class='mydiv'></div>");
var copy = $("#page1").clone().attr("id", "onecopy").css({
"margin-top": '-' + (214 * (i - 1)) + 'px',
"height": (214 * 2 * (i - 1)) + 'px'
});
$("#page" + (i)).append(copy);
}
The problem is that the text gets 'clipped' by the overflow/hidden property.
Is there a way so that the first line on a page is 'truncated' if clipped and that the last line is displayed fully if it is clipped?
Any workaround this most annoying of issues would be greatly appreciated.
You can prevent the clipping by adding a line-height style, which is a factor of mydiv's height.
To avoid problems with fractional point sizes, I've changed your code from 214px to 220px, and I set line-height as 22px:
.mydiv {
width: 200px;
height: 220px;
border:solid 1px black;
overflow:hidden;
line-height: 22px;
}
$(function () {
var page_no = Math.ceil($("#fullpage").height() / 220);
for (var i = 2; i < page_no + 1; i++) {
$("#stuff").append("<div id='page" + i + "' class='mydiv'></div>");
var copy = $("#page1").clone().attr("id", "onecopy").css({
"margin-top": '-' + (220 * (i - 1)) + 'px',
"height": (220 * 2 * (i - 1)) + 'px'
});
$("#page" + (i)).append(copy);
}
});
Fiddle
Update
Your method of cloning the text and offsetting it by a top margin is clever, but it can lead to the clipping problems you experienced. An alternative is to add only the text needed to each "page" div.
You can do so by adding the words one at a time until they overflow the div. You can test for the overflow condition by comparing the div's height to its scrollHeight.
The code below accomplishes this:
function newPage() {
pageNo++;
return $('<div id="page'+pageNo+'" class="mydiv">')
.appendTo('#stuff');
};
var words= $('#fullpage').text().split(' '),
pageNo= 0,
page= newPage(),
i,
len;
for(i = 0 ; i < words.length ; i++) {
len= page.text().length;
page.append(words[i]+' ');
if(page[0].scrollHeight > page.height()) {
page.html(page.text().substr(0,len));
i--;
page= newPage();
}
}
Fiddle
The following code creates the effect when one image goes to white and then white is changed with another image (demo):
HTML:
<body>
<div class="page-bg" id="page-background1"></div>
<!-- <div class="page-bg" id="page-background2"></div> -->
</body>
JavaScript:
url = "http://example.com/picture.png";
$("#page-background1")
.animate({
opacity: 0
}, 'slow', function () {
$("#page-background1")
.css({
'background-image': 'url(' + url + ')'
})
.animate({
opacity: 1
});
});
But I would like to change one image directly with another (without white color in between), but with fadeOut/fadeIn effect. How should I do it? Looks like usage of the second div should help, but I can not find working solution.
Updated, I tried to apply Stacking elements with Z-index to get the desired effect. I also created a kind of "stack" of images where z-index is changed for the image that was hidden; the most recently hidden element is changed for a smaller z-index value in comparison to other images in the "stack". The code supports multiple images in the photos array, because it creates an individual div for each image.
var photos = [{
url: 'https://drscdn.500px.org/photo/97037403/m=900/d924fc03d69a82a604129011300916be'
}, {
url: 'https://drscdn.500px.org/photo/97037259/m=900/030e1598b7822cd6c41beb4c7a4e466d'
}, {
url: 'https://drscdn.500px.org/photo/97158643/m=900/4ae40d67ef546341111a32f5176694c8'
}];
//z-index, start value -1
//z-index can be either positive or negative value
//based on this answer http://stackoverflow.com/a/491105/2048391
var zIndex = -1;
//first foto in the array shown/hidden first
var visibleIndex = 0;
//initialize
//by creating div for each image/url
for (i = 0; i < photos.length; i++) {
var div = document.createElement("div");
div.id = "page-background" + (i + 1);
div.setAttribute("class", "page-bg");
div.style.zIndex = zIndex;
var url = "url('" + photos[i].url + "')";
div.style.background = "#505D6E " + url + " no-repeat center center fixed";
document.body.appendChild(div);
zIndex = zIndex - 1;
//and add div id to the photos array
photos[i].id = "page-background" + (i + 1);
}
function changeBackground() {
var hideItemIndex = visibleIndex % photos.length;
var showItemIndex = (visibleIndex + 1) % photos.length;
var hideItemId = "#" + photos[hideItemIndex].id;
var showItemId = "#" + photos[showItemIndex].id;
//hide current image with animation
//after which show the next image with animation
$(hideItemId).animate({
opacity: 0
}, "slow", function() {
$(showItemId)
.animate({
opacity: 1
}, "slow");
//change z-index for the item that was hidden
//by moving it to the bottom of the stack
$(hideItemId).css("z-index", zIndex);
$(hideItemId).css("opacity", 1);
});
zIndex = zIndex - 1;
visibleIndex = visibleIndex + 1;
}
//make sure that there's at least 2 images in the array
if (photos.length > 1) {
setInterval(function() {
changeBackground();
}, 2000);
}
.page-bg {
border: 1px solid black;
height: 100%;
width: 100%;
position: absolute;
top: 0;
left: 0;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
Alternative way of doing the same thing as above. Below only visible and the next div element exist, and the hidden div is removed for performance reasons, like suggested by LA_
var photos = [{
url: 'https://drscdn.500px.org/photo/97037403/m=900/d924fc03d69a82a604129011300916be'
}, {
url: 'https://drscdn.500px.org/photo/97037259/m=900/030e1598b7822cd6c41beb4c7a4e466d'
}, {
url: 'https://drscdn.500px.org/photo/97158643/m=900/4ae40d67ef546341111a32f5176694c8'
}];
//z-index, start value 100000
//z-index could be a larger number
//based on this answer http://stackoverflow.com/a/491105/2048391
var zIndex = -1;
//first foto in the array shown/hidden first
var visibleIndex = 0;
//initialize
//by creating div for each image/url
for (i = 0; i < photos.length; i++) {
//only two images are created
if (i < 2)
createDiv(i, (i + 1) );
//and add div id to the photos array
photos[i].id = "page-background" + (i + 1);
}
function changeBackground() {
var hideItemIndex = visibleIndex % photos.length;
var showItemIndex = (visibleIndex + 1) % photos.length;
var hideItemId = "#" + photos[hideItemIndex].id;
var showItemId = "#" + photos[showItemIndex].id;
//hide current image with animation
//after which show the next image with animation
$(hideItemId).animate({
opacity: 0
}, "slow", function () {
$(showItemId)
.animate({
opacity: 1
}, "slow");
//remove the item that was hidden
$(hideItemId).remove();
});
var nextItemIndex = (visibleIndex + 2) % photos.length;
//create the next div with picture
createDiv(nextItemIndex, (nextItemIndex + 1) );
visibleIndex = visibleIndex + 1;
}
//make sure that there is at least 2 photos
if (photos.length > 1) {
setInterval(function () {
changeBackground();
}, 2000);
}
function createDiv(index, divIdNro) {
var div = document.createElement("div");
div.id = "page-background" + divIdNro;
div.setAttribute("class", "page-bg");
div.style.zIndex = zIndex;
var url = "url('" + photos[index].url + "')";
//div.style.backgroundImage = url;
div.style.background = "#505D6E " + url + " no-repeat center center fixed";
document.body.appendChild(div);
zIndex = zIndex - 1;
}
.page-bg {
border:1px solid black;
height:100%;
width: 100%;
position: absolute;
top: 0;
left: 0;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
here's a fiddle as snippets not working sat the mo, you can put the speed of the fade in milliseconds or keyword, it's at slow. I've left it on button click and not passed in the url but take out my button click function and put the code into your setinterval func, also set the url in jquery back to url variable
$('button').on('click',function(){
$("#page-background1").fadeOut( "slow", function() {
$("#page-background1")
.css({
'background-image': 'url(http://lorempixel.com/400/400/sports/2)'
});});
$("#page-background1").fadeIn('slow');
});
.page-bg{
min-width:500px;
min-height:500px;
}
#page-background1{
background-image: url(http://lorempixel.com/400/400/sports/1);
background-size:400px 400px;
background-repeat: no-repeat;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Click me to change the background</button>
<div class="page-bg" id="page-background1">;</div>
Change the javascript to:
url = "http://example.com/picture.png";
.animate({
opacity: 0.5
}, 'fast', function () {
$("#page-background1")
.css({
'background-image': 'url(' + url + ')'
})
.animate({
opacity: 1
});
});
when you reduce the browser window there will be a different iphone lay out...
When I put the js into one html sections its not working....
but if i put js in fiddle js section its working properly....
can you tell the reason....
the problem is my li tags are not getting values from js...
can you tell whats the reason....
providing my code below....
working code....
http://jsfiddle.net/YZYp5/7/
not working code....
http://jsfiddle.net/YZYp5/3/
<li style="display: table-cell; width: 417px; vertical-align: top; border: 1px solid red; left: -417px; -webkit-transition: 300ms; -webkit-transform: translate(0px, 0px) translateZ(0px);" data-index="1">
the problem is with this function
function translate(index, dist, speed) {
var slide = slides[index];
var style = slide && slide.style;
if (!style) return;
style.webkitTransitionDuration =
style.MozTransitionDuration =
style.msTransitionDuration =
style.OTransitionDuration =
style.transitionDuration = speed + 'ms';
style.webkitTransform = 'translate(' + dist + 'px,0)' + 'translateZ(0)';
style.msTransform =
style.MozTransform =
style.OTransform = 'translateX(' + dist + 'px)';
}
The problem seems to be here:
var style = slide && slide.style;
That will make style a boolean value, not an object. You're probably looking for something like this:
var style = slide && slide.style ? slide.style : {};