How do I add a fade to a change image mouseover event? - javascript

This is my Javascript function so far :
function changeImg (){
document.getElementById('main').style.backgroundImage = "url('./img/map/maphv.png')"
}
function changeBack () {
document.getElementById('main').style.backgroundImage = "url('./img/map/map.png')"
}
This is in the HTML :
<div id="main">
<a data-title="Africa" href="collection/africa.html" onmouseover="mouseoversound.playclip();changeImg()" onmouseout="changeBack()"><img class="africa" src="./img/map/africa.png" height="50"/> </a>
This is the CSS :
#main {
background-image: url(../img/map/map.png);
background-size: 100%;
background-repeat: no-repeat;
width: 100%;
height: 580px;
position: relative;
}
#main img.africa {
top: 244px;
left: 397px;
height: 33.5%;
position: absolute;
width: 18%;
opacity:0;
}
#main img.africa:hover {
top: 244px;
left: 397px;
height: 33.5%;
position: absolute;
width: 18%;
opacity:1;
transition: opacity .5s ease-in-out;
-moz-transition: opacity .5s ease-in-out;
-webkit-transition: opacity .5s ease-in-out;
}
So the CSS is quite irrelevant but I posted it so that you can see how the top hover is fading in and out. I just wanted to add the fade to the onmouseover event to the background map main element.
So really I just need to add the fade in the Javascript function and add that function to the mouseover event handler?
Any ideas as Javascript is not my first language.. ;)

If you can use jquery,then you can do something like
FIDDLE DEMO
$("#main").on("mouseenter", function () {
$(".africa").stop(true, true).fadeOut(); /***fadeIn or fadeOut***/
});

Ditch the Javascript
If i understand your question correctly, you want to fade between images when you hover over an element, right? This can easily be done in pure CSS.
Give the element you want to animate a background image
Add a child element that's the same size as the parent. This can be an <img>, or a span or div with a background image
Set the opacity for the child element to 0, unless someone hovers over the parent element.
HTML
<div class="fading-bg">
<img src="foo/bar.jpg" alt="stuff">
</div>
CSS
.fading-bg{
position:relative;
width: 100px;
height: 100px;
background: no-repeat center;
background-size: cover;
}
.fading-bg img{
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
opacity: 0;
-webkit-transition: opacity 500ms;
transition: opacity 500ms;
}
.fading-bg:hover img{
opacity: 1;
}
Javascript is awesome, but in my personal opinion you should avoid using it for simple animations like this, as CSS is more than capable of doing it on its own.

Related

HTML - Second IMG hover issue

I have 2 semicircles stuck next to each other forming a circle. When I hover on the left semicircle, the right one lowers it's opacity (which is what is supposed to do) but when I hover on the right one, the opacity doesn't change at all.
HTML:
<div id="animation-components">
<img src="leftball.svg" alt="" class="animation-item-01">
<img src="rightball.svg" alt="" class="animation-item-02">
</div>
CSS:
#animation-components {}
.animation-item-01 {
display: inline;
position: relative;
margin-bottom: 240px;
margin-top: 100px;
transform: translate(631px,80px);
height: 320px;
transition: opacity ease 0.5s;
}
.animation-item-02 {
display: inline;
position: relative;
margin-bottom: 240px;
margin-top: 100px;
transform: translate(627px,80px);
height: 320px;
transition: opacity ease 0.5s;
}
.animation-item-01:hover + .animation-item-02{
opacity: 50%;
}
.animation-item-02:hover + .animation-item-01{
opacity: 50%;
}
What can I alter to make this work?
The issue is that you can only select the next sibling with the adjacent sibling selector.
.element-1 + .element-2 /* good */
.element-2 + .element-1 /* not so good */
Since .animation-item-02 comes after .animation-item-01, there is no way to select the previous .animation-item-01 from .animation-item-02
Doing the following will fix the issue:
#animation-components:hover > div {
opacity: 50%;
}
#animation-components > div:hover {
opacity: 100%;
}
CSS Combinators can't be used to apply styles to elements before target element.
The adjacent sibling selector (+) will aply to all adjacent elements, not to it's opposite elements.
CSS It's in the name: Cascading Style Sheets only supports styling in cascading direction, not up.
To achieve the desired, you can do the folowwing:
#animation-components:hover img {
opacity: .5;
}
#animation-components img:hover{
opacity: 1;
}
<div id="animation-components">
<img src="https://via.placeholder.com/150.png/ff0000" alt="" class="animation-item-01">
<img src="https://via.placeholder.com/150.png/ff0000" alt="" class="animation-item-02">
</div>
It might just be me but I find it heaps easier to throw in just a little bit of javascript and avoid messy css combinators. Heres my fix, script goes anywhere in your html file, I put it after the closing body tag.
<script>
function fadeOut(obj) {
document.getElementById(obj).style.animationName = "fadeOut";
}
function fadeIn(obj) {
document.getElementById(obj).style.animationName = "fadeIn";
}
</script>
#item1 {
display: inline;
position: relative;
margin-bottom: 240px;
margin-top: 100px;
transform: translate(631px,80px);
height: 320px;
animation-duration: 0.5s;
animation-fill-mode: forwards;
}
#item2 {
display: inline;
position: relative;
margin-bottom: 240px;
margin-top: 100px;
transform: translate(627px,80px);
height: 320px;
animation-duration: 0.5s;
animation-fill-mode: forwards;
}
#keyframes fadeOut {
0%{opacity: 1;}
100%{opacity: 0.5;}
}
#keyframes fadeIn {
0%{opacity: 0.5;}
100%{opacity: 1;}
}
<div id="animation-components">
<img src="leftball.svg" alt="" id="item1" onmouseover="fadeOut('item1')" onmouseout="fadeIn('item1')">
<img src="rightball.svg" alt="" id="item2" onmouseover="fadeOut('item2')" onmouseout="fadeIn('item2')">
</div>
Also its just a me thing, but you have class attributes where id attributes should be. If your applying seperate styles to two completely seperate elements its a good idea to use id, but if your applying same style to two elements

How to build a CSS animation that "slides in", revealing a text/div after it finishes sliding?

I am trying to mimic the CSS animations from a website here: https://stanographer.com/
I want to copy the way the site:
starts by showing a full screen black div sliding away to the right
"loads" the black background (div tags) behind text (as in "Hi, I'm Stanley Sakai"), expanding left to right and
"loads" the text over the black background div, expanding left to right.
Now you might ask, "Why not just inspect the page, look at the classes on the divs and text, then inspect the CSS sheet in the network tab?" And I've tried that. The CSS looks weird. My friend said it is pre-processed by SASS, whatever that means. Anyway, I cannot decipher the code.
I've been to a few different StackOverflow pages (here's one) & over a dozen different pages on Google. I learned about using keyframes but I haven't figured out how to recreate the effect on Stanographer.com. My friend, who owns the website, also provided this example, but I don't get how to apply it to individual divs. He said something about using the z-index but I just don't see it.
I know that to make the page start with a full black screen & then slide out, I have to trigger a class change using JavaScript. I have:
let blackStuff = document.getElementById("blackness");
window.addEventListener("load", () => {
console.log("loaded");
blackStuff.setAttribute("class", "black-box-out");
},
false
);
.black-box {
position: fixed;
float: left;
top: 0;
width: 100%;
height: 100%;
bottom: 0;
background-color: #000;
z-index: 999999;
-webkit-animation: powerslide 0.5s forwards;
-webkit-animation-delay: 2s;
animation: powerslide 0.5s forwards;
animation-delay: 2s;
}
#-webkit-keyframes powerslide {
100% {
left: 0;
}
}
#keyframes powerslide {
100% {
left: 0;
}
}
.black-box-out {
margin-left: 100%;
animation: slide 0.5s forwards;
-webkit-transition: slide 0.5s forwards;
transition: slide 0.5s forwards;
}
<div id="blackness" class="black-box"></div>
But this just makes the "blackness" div disappear instantly on page load. I want it to slide out. Clearly, I don't get how to use CSS animations.
If you are interested in seeing more of what doesn't work, read on. Otherwise, you can skip this section: it only shows my failed trials.
I've learned how to make a CSS animation expand horizontally from 0:
.wrapper {
position: relative;
overflow: hidden;
width: 500px;
height: 50px;
border: 1px solid black;
}
.slide-custom {
width: 500px;
height: 50px;
background: cyan;
position: relative;
-webkit-animation: slideIn 2s forwards;
animation: slideIn 2s forwards;
}
/* moz and webkit keyframes excluded for space */
#keyframes slideIn {
0% {
transform: scaleX(0);
}
100% {
transform: scaleX(1);
}
}
<div class="wrapper slide-custom">
<h1 class="slide-custom">
<span>MEET ROLY POLY.</span>
<!-- expands horizontally from 0 width to 100% width -->
</h1>
</div>
And I've learned to make text "slide in" from the left, though it starts at 100% width when I want it to start at 0% width:
/* CSS */
.test-slide {
animation-duration: 3s;
animation-name: testSlide;
}
#keyframes testSlide {
from {
margin-left: 0%;
width: 50%;
}
to {
margin-left: 100%;
width: 100%;
}
}
<div class="test-slide">
<h1><span>ABOUT.</span></h1>
<!-- will slide in from the left -->
</div>
There's more -- unfortunately none of it mimics the website I'm trying to copy.
Explanation
There are multiple ways to achieve what you want actually. I did not opt to animate width. The first few frames of the animation will be not as expected.
So instead, we can use clip-path. What clip-path basically does is masking. You can "crop" a div such that only a part of it is visible. We will utilise clip-path and ::before or ::after pseudo-element (either is fine) to create this animation. What we need to do:
Create the pseudo-element and position it such that it covers (is on top) the whole animatable element (position: absolute)
Set the pseudo-element's background to black
Using clip-path, mask the animatable element to display no parts of the element (this will also cause the pseudo-element to not be displayed as it is part of the element). The direction of the clipping is important. The direction here is from the right side to the left side.
Using animation and #keyframes, unmask the previously masked div. This will reveal it slowly from the left side to the right side (because initially, we masked it from the right to left; upon unmasking, the reverse direction happens)
Upon unmasking the element, the pseudo-element will be on top of the text we want to display
After a short while later, mask the pseudo-element (not the whole element) from the right direction to the left direction, again using clip-path so that the text seems revealed slowly
It works! However, I recommend reading about clip-path. Also, one really handy clip-path CSS generator I really like to use is this (if you want to clip from the right to left, you should drag the points from the right to left). I also highly recommend reading about CSS positioning (a staple in good CSS animations). You needn't be using z-index: 9999; you generally want to keep track of the z-index you use.
Solution
Here's a working solution using the described method. Try running it.
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: Helvetica;
}
body,
html {
width: 100%;
height: 100%;
}
#wrapper {
background: #555555;
width: 100%;
height: 100%;
color: white;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
#wrapper * {
margin: 5px;
}
.heading {
font-size: 3em;
padding: 10px 5px;
}
.caption {
font-size: 1em;
padding: 5px;
font-family: Courier;
}
.animatable {
position: relative;
clip-path: polygon(0 0, 0 0, 0 100%, 0% 100%);
animation: .75s cubic-bezier(1,-0.01,.12,.8) 1s 1 reveal forwards;
}
.animatable::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #20262b;
padding: inherit;
animation: .75s cubic-bezier(1,-0.01,.12,.8) 1.75s 1 hideBlack forwards;
}
#keyframes reveal {
from { clip-path: polygon(0 0, 0 0, 0 100%, 0% 100%); }
to { clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%); }
}
#keyframes hideBlack {
from { clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%); }
to { clip-path: polygon(100% 0, 100% 0, 100% 100%, 100% 100%); }
}
<div id="wrapper">
<div class="heading animatable">Hi, I am Richard!</div>
<div class="caption animatable">I am a person.</div>
</div>
Although the simple animation you wanted can be created using merely CSS, I still suggest you read about how to make animations using JavaScript and the various libraries it has in making animations. This is because once there are many animations and transitions going on, it becomes hard to keep track of animations (especially when you want animations to start after another animation ends). A good library is anime.js (do explore more options before settling on one). Furthermore, notice how the animations only appear upon scrolling down in the website you provided? That's doable only with JS (one such method is using IntersectionObserver API provided by most browsers).
Here you have some CSS3 animations, you trigger that animation when the .entrance-animation gets the .active class.
You'll need an observer to watch when the item gets into view and, when the item is visible, you add the .active class to it.
Hope it helps!
setTimeout(() =>
{
let animate = document.querySelectorAll('.entrance-animation');
animate.forEach(item => item.classList.add('active'));
}
,1000);
.entrance-animation
{
position: relative;
color: blueviolet;
white-space: nowrap;
font-size: 24px;
width: 0;
overflow: hidden;
transition: width 0.5s ease;
}
.entrance-animation::before
{
content: '';
position: absolute;
top: 0;
right: 0;
height: 100%;
width: 100%;
background-color: black;
z-index: 10;
transition: width 0.5s ease;
transition-delay: 0.5s;
}
.entrance-animation.active
{
width: 100%;
}
.entrance-animation.active::before
{
width: 0%;
}
<p class="entrance-animation">
Hello
</p>
<p class = "entrance-animation">
Here we are
</p>
You can use CSS3 transitions or maybe CSS3 animations to slide in an element.
For browser support: http://caniuse.com/
I made two quick examples just to show you how I mean.
CSS transition (on hover)
Demo One
Relevant Code
.wrapper:hover #slide {
transition: 1s;
left: 0;
}
In this case, Im just transitioning the position from left: -100px; to 0; with a 1s. duration. It's also possible to move the element using transform: translate();
CSS animation
Demo Two
#slide {
position: absolute;
left: -100px;
width: 100px;
height: 100px;
background: blue;
-webkit-animation: slide 0.5s forwards;
-webkit-animation-delay: 2s;
animation: slide 0.5s forwards;
animation-delay: 2s;
}
#-webkit-keyframes slide {
100% { left: 0; }
}
#keyframes slide {
100% { left: 0; }
}
Same principle as above (Demo One), but the animation starts automatically after 2s, and in this case I've set animation-fill-mode to forwards, which will persist the end state, keeping the div visible when the animation ends.
Like I said, two quick example to show you how it could be done.
EDIT: For details regarding CSS Animations and Transitions see:
Animations
https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_animations
Transitions
https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_transitions
Hope this helped.

Transform $.show() to css

I got this css:
#pop {
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: rgba(0,0,0,0.8);
z-index: 10;
display: none;
}
Until now, in order to show this #pop div I used $("#pop").show(450);
How can I do it more "Cheaply" with css? I'd like to keep the same fade in effect $.show(ms) provides, not just display it.
well you can create animation and switch class on element something like:
$('#pop').addClass('show');
and you would need css something like this:
#pop {
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: rgba(0,0,0,0.8);
z-index: 10;
display: block;
visibility: hidden;
opacity: 0;
}
#pop.show {
visibility: visible;
opacity: 1;
transition: 1.45s all;
}
As far as I know display property doesn't support transitions so you will need to do it with opacity. You could potentially put both classes on same element to simulate feel of element becoming visible on page load.
Here's update with fiddle, you need to use visibility property:
https://fiddle.jshell.net/6jwfz608/
you can use JS to toggle classes using "className" and use transition in the CSS
CSS
.pop_hidden {
transition:all 450ms;
position: absolute;
top: 0;
left: -101vw;
width: 100vw;
height: 100vh;
background-color: rgba(0,0,0,0.8);
z-index: 10;
display: none;
}
.pop_shown {
transition:all 450ms;
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: rgba(0,0,0,0.8);
z-index: 10;
display: none;
}
(css edit) i got rid of display and changed it to moving the div from out of frame going right.
JS
document.getElementById('pop').className = 'pop_hidden';//to load the hidden div you can use id too
setTimeout(() => {
document.getElementById('pop').className = 'pop_shown';
}, 20);///adjustable delay if needed(ex: set to var in game loop)
Edit: my opinion on using CSS transition in combination with setting classNames. It's easy and fun to do. For a fading effect, toggle opacity. for and slide effect, toggle positions, there are tons of creative ways to change your elements. And since the naming of classes is completely arbitrary, you can have multiple classes to switch to. Also, i switched it to class out of habit(SORRY). But it should not matter, you can toggle id's the same way.
Here's an example showing onclick functionality and handled with Vanilla Javascript and no Jquery, since you wanted something less weighty.
document.getElementById('showBill').addEventListener('click', function () {
var bill = document.getElementById('bill');
if (bill.classList.contains('hide')) {
bill.classList.remove('hide');
} else {
bill.classList.add('hide');
}
});
img {
opacity: 1;
transition: opacity 3s ease-in-out;
-moz-transition: opacity 3s ease-in-out;
-webkit-transition: opacity 3s ease-in-out;
}
img.hide {
opacity: 0;
}
<button id='showBill'>Show Bill</button>
<br/>
<img src='http://fillmurray.com/300/300' class='hide' id='bill' />

a tag showing image on hover with transition

I'm trying to display an image on the hover of an a tag which I have got complete and fully working, now I'm facing a problem...
I want the image to 'fade' in and out of the page when it is hovered rather than just appearing in order to give it a more satisfying finish.
My code at the minute is...
a.top-row:hover:after {
transition: .5s;
-webkit-transition: .5s;
-moz-transition: .5s;
display: block;
position: absolute;
z-index: 10;
top: -295px;
left: -30px; }
and to display the image I have seperate id's for each of the a tags so it's done like this..
a#a1:hover:after {
content: url(../images/cars/audi/a1.png); }
HTML -
<a class="top-row" id="a1">A1</a>
Like this? (background fixed, animating opacity)
a.top-row {
position: relative;
}
a.top-row:after {
transition: .5s;
-webkit-transition: .5s;
-moz-transition: .5s;
display: block;
position: absolute;
top: 100%;
left: 100%;
z-index: 10;
width: 70px;
height: 50px;
opacity: 0;
content: ' ';
pointer-events: none;
}
#a1:after {
background: url(https://placehold.it/70x50);
}
#r8:after {
background: url(https://placehold.it/70x50/ff00ff);
}
a.top-row:hover:after {
opacity: 1;
}
<a class="top-row" id="a1">A1</a><br/>
<a class="top-row" id="r8">R8</a>
Having images fade-in using only CSS would only make it complicated. Instead you can use the jQuery fadeIn() and fadeOut() method to achieve the same.
HTML
<div>
<a link="" id="showme">abcd</a>
<img src="image.jpg" height="200" width="300" alt="button" id="btn">
</div>
jQuery
$('#showme').hover(
function() {
$('#btn').fadeIn('slow');
},function() {
$('#btn').fadeOut('slow');
});
CSS
div {
width:305px;
height:229px;
}
#btn {
display:none;
}

CSS - On hover moving image littlebit left, if not hovered then back to original position

I've been trying doing it, but it doesn't work. It should move that image left 10px, but it doesn't. That div has left css inside it, I think it's because of that. I tried !important, but it didn't work.
Here's JSFiddle: https://jsfiddle.net/jwbvxhv0/1/
$(".seen").bind("webkitAnimationEnd mozAnimationEnd animationEnd", function(){
$(this).removeClass("animated")
})
$(".seen").hover(function(){
$(this).addClass("animated");
})
#-webkit-keyframes example {
0% {
left: 0px;
}
25% {
left: 10px ! important;
}
100% {
left: 0px;
}
}
.seen.animated {
position: relative;
-webkit-animation-name: example;
-webkit-animation-duration: 2s;
}
You can use translate transform for left/right movement as it does not affect any neighbour elements' position. To make the transition smooth, you need to add transition on transform property for your image.
Update:
If you have a button next to the img, which has higher z-index as you mentioned. You need to apply the same effect to a parent element that contains both - that image and that button.
.moving-left
{
height: 100px;
position: relative;
transition: transform 0.3s ease;
transform: translateX(0px);
width: 100px;
}
.moving-left:hover
{
transform: translateX(10px);
}
.moving-left button
{
left: 8px;
position: absolute;
top: 30px;
z-index: 99;
}
<div class="moving-left">
<img src="http://placehold.it/100X100" alt="" />
<button>Button here</button>
</div><!--.moving-left-->

Categories