I want to animate an image input when the user click the image, I'm using animate.css with Bootstrap and Angular, I've seen some examples to add the animate class when the image is click but nothing happens, when I console.log the element in the function I can see that the animate class is added but didnt work, also I got an error message in the console.
html code
<input type="image" src="../../../assets/img/as-logo-150dpi-05.png" class="d-block animate__animated animate__slideInLeft" id="offMenu" (click)="animateLogo()">
TS code
animateLogo(){
const element = document.querySelector('#offMenu');
if(element) {
element.classList.add('animate__animated', 'animate__bounceOutRight');
console.log(element)
}
}
As you can see in the input class, the aniimate class "animate__bounceOutRight" is added but nothing happens in my project, any advice on this?
So after the answer I found out the error message is because of bootstrap, nothing to do with the animation, and the problem was because the input already have an animation, when the function added another this overlaps and didint make it work so I need to disable the first one to make the second works but now the input disappear because of the second animation
HTML
<input type="image" src="../../../assets/img/as-logo-150dpi-05.png" class="d-block animate__animated animate__slideInLeft" id="offMenu" [ngClass]="{'animate__slideInLeft ': firstAnimation , 'animate__bounceOutRight': secondAnimation }" (click)="animateLogo()">
TS
firstAnimation: boolean; //This is true
secondAnimation: boolean; //This is false
animateLogo(){
this.firstAnimation = false
this.secondAnimation = true
}
Did you add the animate.css styles in your
angular.json
"styles": [
"node_modules/animate.css/animate.css"
],
OR
styles.css:
#import '~animate.css/animate.min'
Also just for a better approach let's try to do tackle your problem the Angular way
In your .ts create a boolean field named activateAnimation and we'll set it as true when the user clicks the image so your .ts code will look something like this:
activateAnimation: boolean;
animateLogo(): void {
this.activateAnimation = true
}
and then in your HTML we can conditionally add the animate.css classes that you want to add using the [ngClass] directive of Angular.
<input type="image" src="../../../assets/img/as-logo-150dpi-05.png"
class="d-block animate__animated animate__slideInLeft"
[ngClass]="{'animate__animated ': activateAnimation , 'animate__bounceOutRight': activateAnimation }" id="offMenu"
(click)="animateLogo()">```
Ok so after a little research I found a video that explains how to use Animate.css using jQuery and using the function that he explains with the click event I managed to take out the first animation class, add the second one and once the animations ends, take out the second animation class and add again the first animation class, all of this in the TS file, have some problems coding the jQuery in the TS file but the framework helps me out with the correct form of the code
So first in my <input> I added the class offMenu to identify my input, also I leave the animate__animated so I dont have to add it every time I take out or add an animation class and also I leave the animate__slideInLeft because I want to animate the input the first time ther page loads.
<input type="image" src="../../../assets/img/as-logo-150dpi-05.png" class="d-block animate__animated animate__slideInLeft offMenu" id="offMenu">
Next in my TS file in the constructor part I code the jQuery function, I create 3 variables:
The first one is effects this variable saves the second effect that
is animate__bounceOutRight.
The second variable is effectsEnd that saves the different classes
that Animate.css have to detect when the animation ends for the
different browsers.
And the third one is to save the element I want to add or remove
classes, in this case is my input with the class offMenu.
If you want to add one more variable to save the animate class you currently have, you can do it.
Next I select the element I want to add and remove classes and call the event on click once again in the function I select the element and remove the firts animate class 'animate__slideInLeft' as this animation already end theres no need to add the effectsEnd variable, next I add the second animation class that is saved in my variable effects, then with one we indicate this is going to happen one time and check fot the animation to end with the variable effectsEnd once the animation ends, we remove the animation class effects and add the firt animation class.
constructor() {
$(() =>{
var effects = 'animate__bounceOutRight';
var effectsEnd = 'animationend oAnimationEnd mozAnimationEnd webkitAnimationEnd';
var element = $('input.offMenu');
$(element).on("click", () => {
$(element).removeClass('animate__slideInLeft').addClass(effects).one(effectsEnd, () =>{
$(element).removeClass(effects).addClass('animate__slideInLeft')
});
});
})
}
Whit this code you can put one animation to show when the page is load and then add another animation when you click in the element and take back the element once the out animation is done, hope this helps someone else.
Related
I am new to this website and to coding in general. I am having trouble attempting to get an image to shrink back to its "small" size after being enlarged by a single click.
This is my HTML element:
<img src="http://image.com/123.jpg"
id="smart_thumbnail"
class="small"
This id and class cannot be changed, as it is for an assignment. The "small" class automatically turns the image into a thumbnail. It enlarges upon clicking, but I cannot get it to return to its "small" state by clicking it again. It must be done with an if/else statement.
Here is the Javascript template given:
document.addEventListener("DOMContentLoaded", function(event) {
var thumbnailElement = document.getElementById("smart_thumbnail");
thumbnailElement.addEventListener("click", function() {
thumbnailElement.className = "";
});
});
The double quotes is the "enlarge" class.
Thank you, and I apologize if this post does not fit the format required on this site. I also searched everywhere for this solution but could not find it for the life of me.
This can be done using the DOM classList attribute:
thumbnailElement.classList.toggle("small");
This will remove the small class from the element if it is present, otherwise it will add it.
I have following code working so far: JSFIDDLE DEMO
The relevant JS is here:
// Define classes & background element.
var classes = ['bg1','bg2','bg3','bg4'],
$bg = document.getElementById('blah');
// On first run:
$bg.className = sessionStorage.getItem('currentClass') || classes[0];
// On button click:
$('.swapper').mousedown(function () {
// (1) Get current class of background element,
// find its index in "classes" Array.
var currentClassIndex = classes.indexOf($bg.className);
// (2) Get new class from list.
var nextClass = classes[(currentClassIndex + 1)%classes.length];
// (3) Assign new class to background element.
$bg.className = nextClass;
// (4) Save new class in sessionStorage.
sessionStorage.setItem('currentClass', nextClass);
});
For my purposes, this functionally working great -- I can click a single button to continually swap between those four classes while also storing the current class to sessionStorage, so that when I click links on my website, the currentClass is loaded right away. (Note: on my website the setup is the same, but the classes bg1, bg2, bg3, and bg4 contain background images.)
What I'd like it to do:
When swapping from one class to another, I'd like it to do a quick/short cross-fade. Right now it just snaps from one class/background to another.
My thinking was: is there a way I can trigger a CSS class transition or animation that contains the fade, perhaps as a parent class? I know there's a jQuery fade function, but I haven't been able to get it working with my setup so that it triggers on mouseClick.
Here's an updated jsfiddle based on your comment where you said you've sort of having it work.
I've added the timeout functions
setTimeout(function(){$bg.className = nextClass}, 500);
setTimeout(function(){$($bg).fadeIn(500)}, 500)
The first timeout makes it so that the image is swapped right after the first image fades out. The second timeout gives it a bit of time to load in so it's not so jittery.
You can play with the }, 500); number to get it timed just like you want, 500 is half a second, 1000 is a second etc.
I am using this jquery.smoothZoom.min.js to zoom and pan image.I have successfully applied that to my project for single image,now i want to add (<,>.i.e. corousal) ,so that I can use it for multiple images.When I add the corresponding part in my custom.js it does not work properly.
I will attach two screen sorts which will clear the picture
This is the first case
and after clicking the right corousal button
I can see only the background but not the required image . I can not understand what i am missing ,
This the html part i have been using
<div class="image-display" id="displayplan4" style="width:70%;height:120%; left:39%;top:10%;position:absolute;display:none;">
<img src="images/amenities.jpg" style="width:150%;height:130%; left:-60%;top:-20%;position:absolute;overflow:auto; z-index:1;">
<div style="width:150%;height:130%; left:-60%;top:-20%;position:absolute;background:rgba(255,255,255,0.7);z-index:2;">
</div>
<img class="planzoom" src="gallery/Residential/ongoing/Almog/Plan/almog1.jpg" id = "almogplan0" style="width:100%;height:100%; right:3%;top:50%;position:absolute;z-index:3;">
<!--button for forward and backward movement-->
</div>
and
<div id = "almogplandivII">
<img class="planzoom" src="gallery/Residential/ongoing/Almog/Plan/almog2.jpg" id= "almogplan1" style="width:100%;height:100%; right:3%;top:50%;position:absolute;z-index:3;display:none;">
</div>
and the corresponding js part to show and hide image on mouse click upon the image.
var almog_plan_div=0;
//Function for image forward with forward button
$("#almogforward").click(function ()
{
if(almog_plan_div<1)
{
$("#almogplan"+almog_plan_div).hide();
almog_plan_div++;
$("#almogplan"+almog_plan_div).show();
}
else
{
$("#almogplan"+almog_plan_div).hide();
almog_plan_div=0;
$("#almogplan"+almog_plan_div).show();
}
});
//Function for image backward with backward button
$("#almogback").click(function ()
{
if(almog_plan_div>0)
{
$("#almogplan"+almog_plan_div).hide();
almog_plan_div--;
$("#almogplan"+almog_plan_div).show();
}
else
{
$("#almogplan"+almog_plan_div).hide();
almog_plan_div=1;
$("#almogplan"+almog_plan_div).show();
}
});
I have tried like adding display:none style properties but it does not help my cause,
any help on this ?
Remove inline styling display: none from the img tag and then when u initialize your page, then hide that image using hide() function.
Inline-styling might be overriding this
Thanks to both of your answers ,both of u may not be exactly correct but definitely helped me getting me my solution.
The trick i was missing:
I) have used two different divs ,but i have not positioned the second one, (I noticed only that when I tried the whole thing in a new web page with only 2 images in it ,they were not positioned properly )my requirement needs the divs to be hidden ,i had to hide them.
2) The other thing i had to remove was the position:absolute thing from individual image elements.
Once rectified its cool now.
I'm working with the Meteor Wordplay example right now. The project I have going is at https://github.com/ajcrites/meteor-wordplay
One feature that I wanted to add was not showing duplicate words and highlighting the duplicated word in red (animating it). I got this working via
Meteor.call('score_word', word_id, function (error, result) {
if (result !== undefined) {
var bg = $("#word_" + result.id).css('background-color');
$("#word_" + result.id).css('background-color', 'red');
//Otherwise transition takes effect *before* BG color is applied
setTimeout(function () {
$("#word_" + result.id).css('transition', 'all 2s')
.css('background-color', bg);
}, 10);
}
});
The server will send back a duplicated word ID if there is one.
This works fine, but the problem is that any time a word is added it seems like the entire > words template gets redrawn. I thought it was because the HTML was changing because of the animation that's going on, but I also tried doing this using CSS to do the animation instead, and even without duplicating words I can see in the console that the entire template gets redrawn.
I found a question on Meteor earlier that said the answer is to use a Meteor Collection to return from the template instead of some other abstract collection, but as far as I can tell I am:
Template.words.words = function () {
return Words.find({game_id: game() && game()._id,
player_id: this._id});
};
How can I stop the entire > words template from being redrawn each time? Is there a way to only add new words to the template?
Regardless of the answer to #1, is there a way that I can animate the red BG on a duplicated word and have it go through the full animation even if the > words template is updated?
I'll try to answer that hard question, please don't downvote me if I'm mistaken:
I think you can't nowadays. Maybe on the next render system they are building.
Yes, but I think it's not trivial with the current system. I have a game that I need to rotate a card when users choose one. What I've done was duplicating the div. One receives the last card and the other one receives the current card. So with jQuery I .show() or .hide() them and .addClass() that does the animation. In the class I have transitions and other things that rotate the card.
.
{{#with player_next_card}}
<div id="player-next-card" class="inner-card" style="display: none;">
<!--- stuff here --->
</div>
{{/with}}
{{#with player_last_card}}
<div id="player-last-card" class="inner-card">
<!--- same stuff with other info here --->
</div>
{{/with}}
I am setting up a "Billboard" for the home page of a site. The billboard will have an active image displayed and there will be thumbnails of the right that are used to change the image on the billboard.
Something like this:
Currently I swap the images like this:
<div id="_bbImage">
<img src="images/bill1.png" class="bbImage" id= "MainBB"/>
</div><!--_bbImage-->
<div id="_bbTab1" class="inactiveTab">
<a href="images/bill2.png" onclick="swap(this); return false;">
<img src="images/bbtab1.png" class="bbTabImg" id="bbTabImg1" />
</a>
</div><!--bbTab1-->
and the JavaScript function looks like this:
function swap(image){document.getElementById("MainBB").src = image.href;}
But now, I would like to have the thumbnail to have a different class when Its selected or "Active" to achive this effect:
I need to accomplish the class switch to active, but I also need to make sure that the previously selected tab gets set back to the "inactive" class again.
I tried something like this:
function inactiveTab(name){document.getElementById(name).className = "inactiveTab";}
function activeTab(name){document.getElementById(name).className = "activeTab";}
function inactiveTabAll(){
inactiveTab("_bbTab1");
inactiveTab("_bbTab2");
inactiveTab("_bbTab3");
inactiveTab("_bbTab4");
inactiveTab("_bbTab5");
inactiveTab("_bbTab6");
}
with:
<div id="_bbTab1" class="inactiveTab">
<a href="images/bill1.png" onclick="swap(this); inactiveTabAll(); activeTab("_bbTab1"); return false;">
<img src="images/bbtab2.png" class="bbTabImg" id="bbTabImg1" />
</a>
</div><!--bbTab1-->
But this doesn't seem to be working, when I click on the thumbnail I just get linked to a blank page with "image/bill2.png" image displayed.
Does anyone know a good way to accomplish this, or can anyone point me in the right directions.
Thanks in advance,
Rob
In my opinion, you could have a look at the following jquery method:
http://api.jquery.com/hover/
It has callback functions, where you can make your content visible / invisible.
Instead of your "inactivateTab" - function, you could use the "hide"-method:
http://api.jquery.com/hide/
the problem is that you are using an href for the image inside the tag.
an tag is originally a link to a given url
replace
href="xx.png" with
href="javascript:swap(this); inactiveTabAll(); activeTab("_bbTab1");"
I don't understand what's the original role of the href in your code, but you don't seem to be using it anyway
Instead of img elements, use divs and put the image into the background (use the background-image style). This allows you to define which image should be displayed where in pure CSS. You can also swap images by adding/removing classes:
.bbTabImg { background-image: url(images/bbtab1-inactive.png); }
.bbTabImg.active { background-image: url(images/bbtab1.png); }
As for inactive, use this jQuery:
$('.active').removeClass('active');
This finds all elements with the active class and turns it off. Now you can set one of them active again and the CSS above will load the correct image.