I have 3 tabs which should have different background and text color. I have created 3 classes in CSS with this styles (collor-pallet-1, 2, 3). I am currently doing this ugly thing which also does not work smoothly. Surely there must be a better way to do this? Thanks
$("#tab1").click(function() {
$(".resp-tab-content").addClass("color-pallet-1");
if ($(".resp-tab-content").hasClass("color-pallet-2")) {
$(".resp-tab-content").removeClass("color-pallet-2", 500);
}
if ($(".resp-tab-content").hasClass("color-pallet-3")) {
$(".resp-tab-content").removeClass("color-pallet-3", 500)
}
$(".tab-background").css("background-color", function() {
return $(".resp-tab-content").css("background-color");
console.log($(".resp-tab-content").css("background-color"));
});
});
$("#tab2").click(function() {
$(".resp-tab-content").addClass("color-pallet-2");
if ($(".resp-tab-content").hasClass("color-pallet-1")) {
$(".resp-tab-content").removeClass("color-pallet-1", 500);
}
if ($(".resp-tab-content").hasClass("color-pallet-3")) {
$(".resp-tab-content").removeClass("color-pallet-3", 500);
}
$(".tab-background").css("background-color", function() {
return $(".resp-tab-content").css("background-color");
console.log($(".resp-tab-content").css("background-color"));
});
});
$("#tab3").click(function() {
$(".resp-tab-content").addClass("color-pallet-3");
if ($(".resp-tab-content").hasClass("color-pallet-2")) {
$(".resp-tab-content").removeClass("color-pallet-2", 500);
}
if ($(".resp-tab-content").hasClass("color-pallet-1")) {
$(".resp-tab-content").removeClass("color-pallet-1", 500);
}
$(".tab-background").css("background-color", function() {
return $(".resp-tab-content").css("background-color");
console.log($(".resp-tab-content").css("background-color"));
});
});
It looks like you are trying to give a time parameter to .removeClass() but when you think about it, an element either has a class or doesn't, there is no transition. Luckily, with CSS3 you don't need javascript to animate colors! To accomplish a smooth transition, give your base class (something like .tab) a rule like transition: background-color 0.5s ease; (with appropriate browser prefixes) and the starting colors. Give your color-palette classes the colors you want to transition to. You can then use some simple javascript to just toggle the color-palette classnames. CSS Tricks has (as usual) a useful article on CSS3 transitions here: http://css-tricks.com/almanac/properties/t/transition/.
Try out this plugin
https://github.com/jquery/jquery-color
Sample code of color animation
jQuery("#go").click(function(){
jQuery("#block").animate({
backgroundColor: "#abcdef"
}, 1500 );
});
Related
I'm using the ScrollReveal library to animate in sections of my site.
I have a pretty complex vector which contains five groups. I'm trying to animate these five groups in separately using this library.
Here is my approach currently:
My SVG is a bit lengthy and Stack has a body count character limit, so I created a demo using JSFiddle here.
Each group has a class and as you can see from the demo, it initially loads, then disappears. None of the reveal effects are working? I have other divs with the same parameters which work, but it doesn't work with this SVG for some reason?
If we inspect the white space, I can see that the parts are not appearing because the opacity is 0. But, on scroll, this opacity isn't changing and I don't want to force opacity to 1 via CSS as this I want the part to fade in nicely, whereas setting it to 1 will just make it a static image.
I encountered this same issue. I could not figure out how to get the opacity to work using ScrollReveal directly, so I ended up using ScrollReveal to detect the scroll position and then trigger a callback function to toggle the class. It doesn't require much CSS, but it does require a little bit.
Here's a generic version of my code as an example:
#ease-out-expo: cubic-bezier(0.19, 1, 0.22, 1);
svg {
.class-one {
opacity: 0;
transition: opacity 8000ms #ease-out-expo;
&.visible {
opacity: 1;
}
}
.class-two {
opacity: 0;
transition: opacity 8000ms #ease-out-expo;
&.visible {
opacity: 1;
}
}
.class-three {
opacity: 0;
transition: opacity 8000ms #ease-out-expo;
&.visible {
opacity: 1;
}
}
}
(function($) {
// Reveal the block
ScrollReveal().reveal(".container", {beforeReveal: showGraphic, viewFactor: 0.3});
// Define the showGraphic function
function showGraphic() {
$(".container svg .class-one").addClass( "visible" );
setTimeout(function() {
$(".container svg .class-two").addClass( "visible" );
}, 1800);
setTimeout(function() {
$(".container svg .class-three").addClass( "visible" );
}, 3600);
}
}(jQuery))
I've been looking further into using maquette.js as a virtual DOM library.
Looking at the website the library has functionality to support animations when adding, removing, and updating DOM nodes.
But I cannot find any docs or API on what to do do achieve this.
To make it more concrete I have made a small sample below and here.
var isPopupShown = false;
var togglePopup = function(){
isPopupShown = !isPopupShown;
}
var renderMaquette = function () {
return h("div#container", [
h("button", {
onclick: togglePopup
}, ["Click me"]),
isPopupShown ? h("div#popup") : null
]);
}
In the example, clicking the button will open the popup.
What I would like is that the popup would animate a fade-in when the node is added to the DOM and a fade-out when the node is removed from the DOM.
The documentation how animations work is still in progress.
There are currently two ways to do the animation.
Velocity.js
The easiest way is to use a library like velocity.js. For this to work you need to:
Add the velocity.js script to the page
Change h("div#popup") to h("div#popup", {enterAnimation: fadeIn})
Add the following javascript function
Code:
var fadeIn = function(element) {
element.style.opacity = 0;
Velocity.animate(element, {opacity: 1}, 1500, "ease-out");
};
You can view the result here.
CSS Transitions
You can also use CSS transitions. They work the same as angularJS and react. You need to do the following:
Include the css-transitions.min.js script in your page. This
script is also provided by maquette.
Change h("div#popup") to h("div#popup", {enterAnimation: "fadeIn"})
Change the createProjector call to maquette.createProjector(document.body, renderMaquette, {transitions: cssTransitions});
Add the following style declarations to the stylesheet:
Stylesheet:
.fadeIn {
-webkit-transition: 0.5s ease-out opacity;
transition: 0.5s ease-out opacity;
opacity: 0;
}
.fadeIn.fadeIn-active {
opacity: 1;
}
You can view the result here
I'd like to add a slide & fade effect to a DIV, with purely Javascript, using "onclick".
The code is here: http://jsfiddle.net/TCUd5/
The DIV that has to slide has id="pulldown_contents_wrapper".
This DIV is contained in a SPAN, that also triggers it:
<span onclick="toggleUpdatesPulldown(event, this, '4');" style="display: inline-block;" class="updates_pulldown" >
<div class="pulldown_contents_wrapper" id="pulldown_contents_wrapper">
And I think the JS code that controls the SPAN onclick is:
var toggleUpdatesPulldown = function(event, element, user_id) {
if( element.className=='updates_pulldown' ) {
element.className= 'updates_pulldown_active';
showNotifications();
} else {
element.className='updates_pulldown';
}
}
If it is not possible to make it with pure JS, do you have an idea how could I do it with Mootools? (*I'd like to use only pure JS or the Mootols framework).
I have tried to implement the code from: why javascript onclick div slide not working? but with no results.
Thanks a lot.
I have managed to make it with Mootools, but I can't figure it out how to add a slide & fade effect, and a delay on mouseout
window.addEvent('domready', function() {
$('updates_pulldown').addEvents({
mouseenter: function(){
$('updates_pulldown').removeClass('updates_pulldown').addClass('updates_pulldown_active')
$('pulldown_contents_wrapper').set('tween', {
duration: 1000,
physics: 'pow:in:out',
transition: Fx.Transitions.Bounce.easeOut // This could have been also 'bounce:out'
}).show();
},
mouseleave: function(){
$('pulldown_contents_wrapper').set('tween', {
duration: 1000,
delay: 1000,
}).hide();
$('updates_pulldown').removeClass('updates_pulldown_active').addClass('updates_pulldown')
},
});
});
var toggleUpdatesPulldown = function(event, element, user_id) {
showNotifications();
}
Any idea?
jQuery is a lot easier, but with pure javascript you can do it.
In the CSS you'll need to use transitions
#thing { position:relative;
top: 0px;
opacity: 0.8;
-moz-transition: top 1s linear, opacity 1s linear;
-webkit-transition: top 1s linear, opacity 1s linear;
}
then in the javascript when you change the position of the element, it should change via the css transitions.
var toggleUpdatesPulldown = function(event, element, user_id) {
if( element.className=='updates_pulldown' ) {
element.style.top = someValue; //something like '100px' will slide it down 100px
element.style.opacity = '1.0'; //will fade the content in from 0.8 opacity to 1.0
element.className= 'updates_pulldown_active';
showNotifications();
EDIT - provided jQuery code
call the jQuery library, most easily done from the google hosting
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
make the hover function
$(document).ready(function() {
$('.updates_pulldown').hover( //first function is mouseon, second is mouseout
function() {
$(this).animate({top: '50px'}).animate({opacity: '1.0'});
},
function() { //delay 1000 milliseconds, animate both position and opacity
$(this).delay(1000).animate({top: '0px'}).animate({opacity: '0.5'});
}
)
})
the function timing will be the same as whatever you set it to in the css with transition tags. using 'this' instead of the class name again makes sure that the effect only occurs on the specific instance of the class that is hovered over. im not sure if this animation is exactly what you were asking for, but if i understand the question correctly then the main functionality will work for you. just change the numbers and such to fit your needs.
In this example; i am trying to create a jQuery animation with css3 rotate property. I can manage this animation with css3 transition and jQuery css() but i want to do this with jQuery animate() for rotating deg value according to my jQuery variatons.
Is it possible use animate with css3 property value with jQuery 1.8.0?
Here is jsFiddle to inspect.
jQuery:
var rotateVal = 90;
//this method isn't working
$('.red').animate({
'transform':'rotate('+rotateVal+'deg)'
},500);
//this way works but i don't want to do this with transitions
$('.black').css({
'transform':'rotate('+rotateVal+'deg)',
'transition':'1s'
});
html:
<span class="black"></span>
<span class="red"></span>
Edit: Vendor prefixes removed, like -webkit-. Thanks to Kevin B.
It is possible, but it isn't easy.
var red = $(".red"),
rotateVal = 90;
$("<div />").animate({
height: rotateVal
},{
duration: 500,
step: function(now){
red.css('transform','rotate('+now+'deg)');
}
});
This basically creates a fake animation of a detached div, then on each step, updates the rotation of the target div.
Edit: Oops! wrong argument order. Here's a demo. http://jsfiddle.net/qZRdZ/
note that in 1.8.0 i don't think you need to specify all the vendor prefixes.
Using this method, you can animate almost anything as long as you keep in mind that things like += and -= won't work properly unless coded for.
Update: Here's a combination of my solution and cuzzea's solution abstracted behind a function. http://jsfiddle.net/qZRdZ/206/
$.fn.rotate = function(start, end, duration) {
console.log(this);
var _this = this;
var fakeDiv = $("<div />");
_this.promise().done(function(){
_this.animate({"a":end},{duration:duration});
fakeDiv.css("height", start).animate({
height: end
}, {
duration: duration,
step: function(now) {
_this.css("transform", "rotate(" + now + "deg)");
},
complete: function() {
fakeDiv.remove();
}
});
});
return _this;
};
var red = $('.red');
red.click(function() {
if ( !$(this).is(':animated') ) {
red.rotate(45,135,500);
setTimeout(function(){
red.rotate(135,190,500);
},750);
setTimeout(function(){
red.rotate(190,45,500);
},1500);
}
});
});
Kevin is corect, almost. :)
Here is working jsFiddle.
You don't have to use another element and height, you can do something like:
var red = $('.red'),
max_rot = 45,
start_from = 90;
red.css({a:0}).animate(
{'a':1},
{ step: function(value,tweenEvent)
{
rotateVal = start_from + max_rot * value;
red.css({
'transform':'rotate('+rotateVal+'deg)',
});
}
},
1000);
The ideea is simple. First we create a bogus css property 'a' and set it to 0, and then we animate it to 1, so the step function will give you a value of 0 to 1 that you can use to set the custom transform.
An alternative method would be to use jQuery to change the dom to something that css would respond to.
We can set our css to look like this:
.object {
-webkit-transition:all .4s;
-moz-transform:all .4s;
-o-transform:all .4s;
-ms-transform:all .4s;
transform:all .4s;
}
.object[data-rotate="false"] {
-webkit-transform:rotate(0deg);
-moz-transform:rotate(0deg);
-o-transform:rotate(0deg);
-ms-transform:rotate(0deg);
transform:rotate(0deg);
}
.object[data-rotate="true"] {
-webkit-transform:rotate(90deg);
-moz-transform:rotate(90deg);
-o-transform:rotate(90deg);
-ms-transform:rotate(90deg);
transform:rotate(90deg);
}
Our jQuery would look like this:
$('#trigger').live('click',function(){
if($('.object').attr('data-rotate') = true) {
$('.object').attr('data-rotate',false);
}
else {
$('.object').attr('data-rotate', true);
}
});
Obviously, the browser has to support the ability to transform whatever animation you want to run, so its its hit or miss depending on the type of animation, but its nicer to work with if you have a ton of stuff going on or you have some children you want to animate concurrently.
Example fiddle:
http://jsfiddle.net/ddhboy/9DHDy/1/
I am currently working on my portfolio website which uses a very simple navigation.
However what I want to do is have the drop shadow beneath the type become stronger (read: higher opacity/ darker) when the type is being hovered on.
Right now my code looks as follows and does not generate any errors but simply does not do anything either.
For a good understanding of what I mean please have a look at the website with a live example.
/* Work | Play | About | Contact */
/* Shadow Opacity */
$(document).ready(function() {
$('#workShadow', '#playShadow', '#aboutShadow', '#contactShadow').fadeTo( 0, 0.1);
});
/* Shadow Hover effect */
$(document).ready(function() {
$('a#work').hover(function() {
$('#workShadow').fadeTo( 200, 0.5);
}, function() {
$('#workShadow').fadeTo( 400, 0.1);
});
});
/* Type movement on hovering */
$(document).ready(function() {
$('a.shift').hover(function() { //mouse in
$(this).animate({ paddingTop: 85, paddingBottom: 2 }, 200);
}, function() { //mouse out
$(this).stop().animate({ paddingTop: 75, paddingBottom: 12 }, 400);
});
});
Basically I need the opacity of the shadow elements (4 individual ones) to start at 10% opacity and while the user hovers, the type moves down (this part is working) and simultaneously the shadow becomes stronger, increases to 60% opacity. Then revert back to 10% when on mouseOut.
This line is wrong - it is passing a bunch of arguments to the $() function.
$('#workShadow', '#playShadow', '#aboutShadow', '#contactShadow').fadeTo( 0, 0.1);
As the documentation notes, jQuery doesn't expect N arguments as a selector, but 1:
$('#workShadow, #playShadow, #aboutShadow, #contactShadow').fadeTo( 0, 0.1);
It is common (and good) practice to give a set of objects that should do something a common class or to select them in a smarter than just listing all their IDs. Based on your current HTML, this selector gets all the shadow <div>s in the menu, and is much shorter - you won't have to modify your code if you add a new menu element later on, for example:
$('div','#navigationFrame').fadeTo(0, 0.1);
I also see you have this:
<li id="work"><a id="work" ...>
This is really, really, wrong. IDs should be unique in the document. By having more than 1 ID in the document not only are you breaking best practices, ID selection on jQuery will go crazy and won't work as expected. Like the fadeTo selector, you can change the shadow changing code to a cleaner:
$('a','#navigationFrame').hover(function() {
$(this).next('div').fadeTo(200, 0.5);
}, function() {
$(this).next('div').fadeTo(400, 0.1);
});
I tested the website with these changes and it works fine.
What the selectors in my examples are doing is taking advantage of jQuery's context. By doing this:
$('a','#navigationFrame');
Or this:
$('div','#navigationFrame');
We are telling jQuery "only give me the <a> (or <div>) elements inside #navigationFrame.
It is equivalent to this:
$('#navigationFrame').find('a');
It is a good idea to take advantage of this. I see you have a tendency to manually list the elements you're trying to do stuff to do even if they are all similar in some way. Try to shake this habit and let jQuery's powerful selectors get what you want from the document.
I use this:
$(".thumbs img").addClass('unselected_img');
$('.thumbs img').click(function() {
$(this).addClass('selected_img');
if ($(this).is('selected_img')) {
$(this).removeClass('selected_img');
} else {
$('.thumbs img').removeClass('selected_img');
$(this).addClass('selected_img');
}
});
// hover the lists
$('.thumbs img').hover(
function() {
$(this).addClass('selected_img_h');
},
function() {
$(this).removeClass('selected_img_h');
});`
and style:
.selected_img
{
opacity: 1; filter: alpha(opacity = 100);
border:none;
}
.selected_img_h{
opacity: 1; filter: alpha(opacity = 100);
border:none;
}
.unselected_img
{
opacity: 0.6; filter: alpha(opacity = 60);
border:none;
}