folks I want to make a demo design of this and I got confused how to achieve this. should I go for parallax scrolling or should I prefer skrollr or scrollmagic or just simple css with few jquery code? suggest the simplest way to achieve this.
Thanks :)
Here is working example;
Html
<div class="rotate"></div>
Css
body{
height: 1000px;
background: yellow;
}
.rotate{
background: url("http://i.imgur.com/zZ3fMuh.png");
width: 101px;
height: 102px;
position: fixed;
}
Js
$(function() {
var rotation = 0,
scrollLoc = $(document).scrollTop();
$(window).scroll(function() {
var newLoc = $(document).scrollTop();
var diff = scrollLoc - newLoc;
rotation += diff, scrollLoc = newLoc;
var rotationStr = "rotate(" + rotation + "deg)";
$(".rotate").css({
"-webkit-transform": rotationStr,
"-moz-transform": rotationStr,
"transform": rotationStr
});
});
})
In this particular case they used CSS with the help of JavaScript but the part what you are watching at is CSS (really fluent) and it get executed my an scroll handler.
In this specific case they used the transform: translate3d() property to rotate the yellow background.
If you want to rotate the background when scrolling, look this: https://codepen.io/sarkiroka/pen/gByRmd
In nutshell it uses the sidebar elements for this effect. This elements has :before property with background setting, and a little javascript calculate the rotating degree from the scrollTop. And this javascript overwrite the defined css rule transform property.
Related
I have 4 images connected to each other which form a big image. My task is to rotate the big image to a certain angle that is entered by the user.
Now, to rotate the full image, I need to rotate the smaller connected images and then translate them accordingly so that the full images seems to be rotated.
But can't get the translation coordinates properly. Please help me out with that.
Also, if there is any other way to do this, you can tell me that as well.
The code can be found here -
https://jsfiddle.net/e4qp6btx/1/
document.getElementById("img1").style.transform = "translate(" + x + "px," + y + "px) rotate(" + angle + "deg)" ;
Edit -
I actually want to rotate and translate individual images rather than rotating the whole container.
I would just target and rotate the container instead. When trying on Mac Firefox, however, the smaller images seemed to get small spaces between them.
rotateImage() {
var angle = document.getElementById('angle').value || 0; //angle to be rotated by
angle = angle % 360 + 'deg';
document.querySelector('.container').style.transform = `rotate(${angle})`;
}
I would also use a CSS variable to set the angle, and then update the variable, instead of using inline style to change the transform: rotate value.
Finally, I would give the container a unique id.
Second solution.
Rotation originates from the center of the image by default. You can change this by setting transform-orgin. The following CSS will make the images rotate like they should, so you don't need to translate them. You should probably frankenstein together my two answers, because you barely need any code for your rotateImage() to work.
#img1 {
transform-origin: bottom right;
}
#img2 {
transform-origin: bottom left;
}
#img4 {
transform-origin: top right;
}
#img3 {
transform-origin: top left;
}
Do note: you mixed up the positions of #img4 and #img3, where #img4 comes before #img3, hence these images having the transform-origins switched around.
An added bonus:
I feel it's kinda wasteful to set the same value on four different elements, so I would suggest to use a CSS variable on .container to store the rotation value on all images. It would be easier to test different values in the Inspector if you do it like that.
CSS
.container {
--image-rotation: 0deg;
width:500px;
height:500px;
padding: 50px;
}
img {
width:100%;
height:100%;
transform: rotate(var(--image-rotation));
}
Javascript
rotateImage() {
const imgContainer = document.querySelector('.container');
let angle = document.getElementById('angle').value || 0; //angle to be rotated by
angle = angle % 360 + 'deg';
imgContainer.style.setProperty('--image-rotation', angle);
}
https://jsfiddle.net/mg46dz7h/
so far (with the help of this comm :)) I created a full viewport background, thats able to switch on click.
Since I'm a beginner I have two questions:
1) Is the code "good", or did I wrote it to complicated?
and the Mainquestion:
How can I put a fade effect into my code? Now it's kinda ugly, because the images are loading slow (stuttering). I imagine something like this:
Image--Click--Fading black--Fading in new Image--Click--Fading black---Fading in new Image--..
Here is the code I wrote:
HTML:
<div class="t1">
</div>
CSS:
.t1 {
background: url(pics/homescreen.JPG) no-repeat center center fixed ;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
width: 100%;
height: 100%;
}
jQuery:
$(function () {
var y = 1;
$('.t1').click(function () {
var x = ['url(pics/screen1.jpg) no-repeat center center fixed',
'url(pics/screen2.jpg) no-repeat center center fixed',
'url(pics/schild.jpg) no-repeat center center fixed'
]
$('.t1').css('background', x[y]);
$('.t1').css('background-size', 'cover');
if (y == 2) {
y = 0;
} else {
y = y + 1;
}
});
})
Demo: http://jsfiddle.net/bSAm2/
This doesn't include preloading, but the effect is quite nice.
If you are interested in a preloader, you probably want to preload images one at a time, when they are needed: loading all images upfront or worse in the head of your document, will likely slow down page loading beyond what's an acceptable UX.
Also, transition won't work on older browsers (see here)
To animate CSS properties, you can use http://api.jquery.com/animate/
In particular, you can fade out the current image by animating its opacity (to 0), then, when this animation is completed change the image source (while it is not visible) and start the fade-in animation.
For best appearance, you can preload images "Just in Time", for example you can preload the next image to show, so there won't be any latency
EDIT
This example works, and uses closure so that you can have multiple images rotating independently:
$(function () {
var images = ['url(http://lorempixel.com/output/people-q-c-640-480-8.jpg) no-repeat center center fixed',
'url(http://lorempixel.com/output/nature-q-c-640-480-8.jpg) no-repeat center center fixed',
'url(http://lorempixel.com/output/fashion-q-c-640-480-9.jpg) no-repeat center center fixed'
];
function bindSwitcher (elem) {
var imageIndex = 0;
return function switchImage () {
elem.fadeOut(function (){
elem.css('background', images[imageIndex]);
if (imageIndex == images.length - 1) {
imageIndex = 0;
} else {
imageIndex += 1;
}
elem.css('background-size', 'cover');
elem.fadeIn();
});
};
}
var imageSwitcher = bindSwitcher($('#t1'));
$('#t1').click(imageSwitcher);
$('#t2').click(bindSwitcher($('#t2')));
});
And the HTML, with a little change to show the difference:
<div id="t1" class="t1" style="position: absolute; left:0%">
</div>
<div id="t2" class="t1" style="position: absolute; left:50%">
</div>
Demo: http://jsfiddle.net/abhitalks/FNUx8/8/
Is the code "good", or did I wrote it to complicated?
A couple of things which you could do is:
Take your image array outside of click handler. You woudn't want to create that array every time a click happens.
Reduce the code to cycle the array by using a modulus.
Refer to the element using this.
Use an id instead of class to target the element directly if that is unique.
So, effectively your code reduces to:
var x = ['url(...1.jpg) no-repeat center center fixed',
'url(...2.jpg) no-repeat center center fixed',
'url(..3.jpg) no-repeat center center fixed'
];
var index = 0;
$('#t1').click(function () {
index = (index + 1) % x.length;
$(this).css('background', x[index]);
});
How can I put a fade effect into my code? Now it's kinda ugly, because
the images are loading slow (stuttering)
(1.) You can put a fade effect using CSS3 transition:
#t1 {
...
transition: 1s;
}
(2.) There is stuttering because the images are loaded at runtime. You could avoid that by pre-loading images:
One way could be like this:
var d = []; // create an array for holding dummy elements
for (var i = 0; i < x.length; i++) {
d[i] = $("<img>"); // create an img and add to the array
d[i].attr('src', x[i]).hide(); // add src to img and hide it
$("body").append(d[i]); // add the img to body to start load
}
Ideally wrap this code in the head so that this is done by the time DOM is ready. Put rest of your code either wrapped in body at the end or in .ready.
Edit:
Changed the preloading code to use img. Updated the fiddle.
The code is not complicated, in time you'll learn to write cleaner (good) code. Here is my suggestions:
1. move the x definition outside the click event, put it right after y and y should be 0 initially;
2. if(y == 2) is too static, beter take the length of the array if(y == x.length);
3. remove background-size from script, it's set in css;
4. For fade effect you can do something like this:
$('.t1').fadeOut(300, function() {
$(this).css('background', x[y]).fadeIn(300);
});
I haven't tested it, but should do the job.
I'm trying to achieve this:
When users scroll page, i need a header that will be fixed, but before to stick it, this div should shrink to a certain height, and after that this div become fixed.
This is my attempt
As you can see, there are some strange behavior on shrinking, i think that my approach is not so right.
header.css("height", "-=" + (Math.abs(start - scrollTop)));
spacer.css("height", "-=" + (Math.abs(start - scrollTop)));
So, what is the best way to do it?
UPDATE:
Now i'm at this point, but i need to make it more smooth
jsFiddle
Try this
$(document).ready(function(){
var headerElement = //Select header element here,
scrollTopToLookoutFor = //Put value you want to check for here,
if($("body").scrollTop() > scrollTopToLookoutFor || $("html").scrollTop() > scrollTopToLookoutFor){
headerElement.addClass("fix-header");
}
else{
headerElement.removeClass("fix-header");
}
});
Have a css class here with required styles
.fix-header{
height: 400px;
position: fixed;
top: 0px;
}
I am trying get this background to fade in on click. I found one tutorial that was helpful, and I ended up created the code so it has two images, and they fade in and out on click to bring up the picture.
Here's the work: http://www.mccraymusic.com/bgchangetest.html
Only a couple of issues though:
How do I make this work without the images getting selected at random? I'd like it to just switch from the plain black image to the image with the drum set. (And cross-fade to if possible, but not necessary)
How do I center the image on the page, so the image of the drums are centered?
I'm guessing this is what you're after:
$(function() {
var images = ["black.jpg","bg.jpg"];
$('<img>').attr({'src':'http://www.mccraymusic.com/assets/images/'+images[0],'id':'bg','alt':''}).appendTo('#bg-wrapper').parent().fadeIn(0);
$('.entersite').click(function(e) {
e.preventDefault();
var image = images[1];
$('#bg').parent().fadeOut(200, function() {
$('#bg').attr('src', 'http://www.mccraymusic.com/assets/images/'+image);
$(this).fadeIn(1000);
});
$(this).fadeOut(1000, function() {
$(this).remove();
});
});
});
DEMONSTRATION
Also added :
display: block;
margin-left: auto;
margin-right: auto;
to your #bg element to center the image.
Alright, assuming you use JQuery
You have #backgroundid and #imageid
Begin by setting
$('#backgroundid').css('opacity',1);
$('#imageid').css('opacity',0); // setting opacity (transparency) to 0, invisible
Now you have #buttonid.
Set up a jquery event so that when it's clicked, you fade out the background, and fade in the image using JQuery's animate.
$('#buttonid').click(function() {
$('#backgroundid').animate(function() {
opacity : 0 // fade it to 0 opacity, invisible
}, 1000); // animation will take 1000ms, 1second
$('#imageid').animate(function() {
opacity : 1 // fade it to full opacity, solid
}, 1000);
});
Now about that image centering.
You can either let css manage it with
body { /* Body or #imageid parent */
text-align : center;
}
#imageid {
margin: 0px auto;
}
Or you can stick to a JQuery solution, using absolute/fixed positioning.
First, use some css to fix the position of your image
#imageid {
position: absolute; // or fixed, if you want
}
Now use JQuery to reposition it
function positionImage() {
var imagewidth = $('#imageid').width();
var imageheight = $('#imageid').height();
$('#imageid').css('left', ($(window).width() - imagewidth) / 2);
$('#imageid').css('top', ($(window).height() - imageheight) / 2);
}
$(document).ready(positionImage); // bind the ready event to reposition
$(window).resize(positionImage); // on window resize, reposition image too
if you keep a div element with height and width as 100% and bgcolor as black. And then change the opacity of the div as desired to get the fade in/out effect, that should generate the same effect. I guess..
You are better off using any available jQuery plugin as they would have optimized and fixed bugs for multiple browsers.
Try lightBoxMe plugin
http://buckwilson.me/lightboxme/
This is the simplest plugin available!
In my project I have a webpage which has 2 div areas right and left. The left div takes almost 60% of the whole page width and the right one takes around 36% of the page. I wanted to resize the both div areas in a proper ratio when I shrink the browser from the right side or left side. The UI is getting generated from Javascript. This is the code.
boardHolderPadding = $board.outerHeight() - $board.height();
$board.height(viewportHeight - siblingsHeight - boardHolderPadding);
this.$('#board .droptarget').setWidthAsRatioOfHeight(this.options.ratio);
$('#sidebar').width($(window).width() - $board.find('#board').width() - 50);
I tried with JQuery resize plugin but couldnt get the proper result I'm looking for. Anyone have suggestion?
Thanks
See jsfiddle example but I think you just need to set your widths as percentages rather than trying to calculate them - note display is set to inline-block
<div>
<div class="small-left-column">this is the left column</div>
<div class="large-right-column">this is the right column</div>
</div>
<style>
.small-left-column {
width: 30%;
background-color: #aeaeae;
display: inline-block;
}
.large-right-column {
width: 60%;
background-color: #aeaeae;
display: inline-block;
}
</style>
So I think for your example your would have something like this
$(document).ready(function () {
$('#sidebar').addClass('small-left-column');
$('#board').addClass('large-right-column');
});
Maybe you're looking for the pure-Javascript version of the above:
$(document).ready(function () {
$('#sidebar').css( {
width: '30%'
backgroundColor: '#aeaeae',
display: 'inline-block'
});
$('#board').css({
width: '60%',
backgroundColor: '#aeaeae',
display: 'inline-block'
});
});
I did it in a different way in Javascript and I hope this will help someone to fix if they come across an issue like that
relativeSize : function(width, height){
var boardWidth = this.$("#board").width(),
boardHeight = this.$("#board").height(),
newcard = this.$("#newCard").width(),
space = width - boardWidth - newcard;
ratio = space / width * 3; //used to increment the ratio with 3 as the ratio is very tiny value, this will help to increase minimizing size
bheight = boardHeight - 25; // used to reduce the height by 25px, u can use any amount to match ur ratio
var relHeight = (space < ratio) ? bheight : height;
return relHeight;
}
Thanks