my scenario: I have basic image 100x50px. I have one hover jpeg image 300x150 px and it has 9 areas (3x3, each area is 100x50 px and has another image inside). Until there is no on hover event, just another image is shown. Now I am trying to do that on hover these 9 areas changes one by one after 0.3second in cyclic way. Once mouse is not on hover, first image appears back.
<div class="thumb">
<a href="click.php"><img src="image.jpg">
<img class="hovered" src="hover.jpg" style="margin-top: 0%; margin-left: 0%; display: none;">
</a>
</div>
<div class="thumb">
<a href="click.php"><img src="another.jpg">
<img class="hovered" src="hovX.jpg" style="margin-top: 0%; margin-left: 0%; display: none;">
</a>
</div>
how could I do this please?
(I think I should somehow call javascipt function to display hovered class and start changing position of image each 0.3s. But no idea how..)
MY IMAGES:
first image without hover:
3x3 hover source image:
on hover images cycle like this:
then after 0.3s
then after another 0.3s
etc
(numbers are just for reference)
final effect should look like when mouse on hover:
when mouse is not on hover then this image is shown
You could achieve this using css.
First, put the images into a container element.
<div id="img-container">
<div class="hover-img"/>
<div class="hover-img"/>
<div class="hover-img"/>
<div class="hover-img"/>
<div class="hover-img"/>
<div class="hover-img"/>
<div class="hover-img"/>
<div class="hover-img"/>
<div class="hover-img"/>
</div>
Now you can set the size and background image of each element in css:
#img-container {
width: 300px;
height: 150px;
}
.hover-img {
width: 100px;
height: 50px;
display: inline-block;
background-image: url('image.jpg');
background-size: cover;
transition: background-image 0.3s;
}
I added a transition of 0.3 seconds to the background image so the image will change gradually when we hover over the container. To apply the change on mouse hover, we can set a different image for the hover state of the container. This means that every image will transition to the new image when the container div is hovered over.
#img-container:hover>.hover-img {
background-image: url('hover.jpg');
}
Now you want each image to change one-by-one. To do this, you can add a transition delay. You can use css nth-child to target each image directly, though this is a bit long winded and might be better done programmatically with javascript.
.hover-img:nth-child(2) {
transition-delay: 0.3s;
}
.hover-img:nth-child(3) {
transition-delay: 0.6s;
}
.hover-img:nth-child(4) {
transition-delay: 0.9s;
}
.hover-img:nth-child(5) {
transition-delay: 1.2s;
}
.hover-img:nth-child(6) {
transition-delay: 1.5s;
}
.hover-img:nth-child(7) {
transition-delay: 1.8s;
}
.hover-img:nth-child(8) {
transition-delay: 2.1s;
}
.hover-img:nth-child(9) {
transition-delay: 2.4s;
}
I'm not sure if this exactly what you want but I hope it gives some idea of how you could achieve what you want using pure css.
Is this what you meant (but with images)? You can use onmousover and onmouseout attributes to trigger your animation.
const container = document.getElementById("container");
//instead of colors you'd use source urls
const colors = ["blue","red","green","orange","pink","gold","purple","brown","yellow"];
for (let i = 0; i < 9; i++) {
const div = document.createElement("div");
//instead of color you'd add src attribute
div.style.backgroundColor = colors.shift();
div.classList.add("square");
if(i === 0) div.classList.add("active");
container.append(div);
}
let interval;
function animation() {
let i = 2;
container.children[0].classList.toggle("active")
container.children[1].classList.toggle("active");
interval = setInterval(()=>{
if(container.children[i]) {
container.children[i - 1].classList.toggle("active")
container.children[i].classList.toggle("active");
i++
} else {
container.children[0].classList.toggle("active")
container.children[i - 1].classList.toggle("active")
i = 1;
}
},300)
}
function reset() {
clearInterval(interval);
for(let i = 0; i < container.children.length; i ++){
const child = container.children[i];
if(child.classList.contains("active")) child.classList.toggle("active");
if(i === 0)child.classList.toggle("active");
}
}
#container {
width: 300px;
height: 150px;
display: flex;
flex-wrap: wrap;
cursor: pointer;
}
.square {
width: 100px;
height: 50px;
opacity: 0;
pointer-events: none;
}
.active {
opacity: 1;
}
<div id="container" onmouseover="animation()" onmouseout="reset(this)"></div>
Related
I made a simple slide show with divs stacked one on top of the other.
I switch the div on display with display:none or display:block.
But when I add animations, I encounter a problem. The fade in works, but I have no idea how to fade out a vanishing slide. The slide just disappears and I can't get any fade out method that I have found to work. Where is the error please?
let pages = document.getElementsByClassName("page");
let buttons = document.getElementsByClassName("page-button");
let currentPage = 0;
pages[currentPage].style.display = "block";
for (let i = 0; i < buttons.length; i++) {
buttons[i].addEventListener("click", () => changePage(i));
}
function changePage(k) {
pages[currentPage].style.display = "none";
pages[k].style.display = "block";
currentPage = k;
}
.content-container {
display: flex;
height: 90vh;
}
.page {
position: absolute;
display: none;
width: 100%;
height: 100%;
animation: fadeIn 3s;
}
#keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#slideshow {
flex-grow: 1;
position: relative;
}
<div class="content-container">
<div id="slideshow">
<div class="page" style="background-color: red;"></div>
<div class="page" style="background-color: green;"></div>
<div class="page" style="background-color: blue;"></div>
</div>
<button class="page-button">1</button>
<button class="page-button">2</button>
<button class="page-button">3</button>
</div>
For animation I use the library called Animate.css. Take a look at the following link:
https://animate.style/
You can install this library with NPM:
npm install animate.css --save
Then you can use this library like this:
<div class="page animate__fadeOutLeft" style="background-color: green;">
The issue is that you are using a display none, which will instantly remove the coloured block and fade in from white.
On click set the background colour of the 'content-container' to the item's colour to be removed, giving the impression of fading in from that colour.
var contentContainer = document.getElementsByClassName("content-container");
var replaceColour = pages[k].styles.getPropertyValue("background-color")
contentContainer.style.backgroundColor = replaceColour;
Example
i need to make divs appear like this, or any other fancy way. Can someone provide source or something that can help?
We can add the class name of a CSS attribute with a transition, and animate property to switch it from an opacity: 0 element to an opacity: 1 element, and assign it an animation attribute that slides it in using the CSS transform property.
We can use getBoundingClientRect and scrollTop to check when the element is in view, and add the class when it is.
This gives us something close to the desired effect.
document.addEventListener("scroll", (event) => {
const elementsToAnimate = Array.from(document.querySelectorAll(".stationary"));
for (element of elementsToAnimate) {
const {
scrollTop
} = document.querySelector("html");
const {
top
} = element.getBoundingClientRect();
const containsAnimateClass = element.classList.contains("from-left");
if (top < scrollTop / 2 && !containsAnimateClass)
element.classList.add("from-left");
}
});
body {
display: flex;
flex-direction: column;
gap: 1rem;
}
.stationary {
opacity: 0;
width: 100px;
height: 100px;
background: red;
}
.from-left {
transition: 1s ease;
opacity: 1;
animate: 1s ease slide-in-from-left;
}
#keyframes slide-in-from-left {
from {
transform: translateX(-50%);
}
to {
transform: translateX(0);
}
}
<body>
<div>Scroll!</div>
<div class="stationary"></div>
<div class="stationary"></div>
<div class="stationary"></div>
<div class="stationary"></div>
<div class="stationary"></div>
<div class="stationary"></div>
<div class="stationary"></div>
<div class="stationary"></div>
<div class="stationary"></div>
<div class="stationary"></div>
</body>
You can use simple libraries already implemented these animations:
https://github.com/matthieua/WOW
https://scrollrevealjs.org/
https://scrollmagic.io/examples/basic/reveal_on_scroll.html
https://michalsnik.github.io/aos/
(I personally love this, its easy to use)
Or in other hand make your own animation.
add event listener for scroll and create a keyframe animation. Then assign the class to the element when scroll reached to your desire number.
I am developing a chrome extension which on any hover over an image it should popout a box over the image and the image should be zoomed to 1.5 times the original image.
So I started working on examples and found a similar example like this.
.zoomin img {
height: 200px;
width: 200px;
-webkit-transition: all 2s ease;
-moz-transition: all 2s ease;
-ms-transition: all 2s ease;
transition: all 2s ease;
}
.zoomin img:hover {
width: 300px;
height: 300px;
}
<div class="zoomin">
<img src="http://www.corelangs.com/css/box/img/zimage.png" title="All you need to know about CSS Transitions " />
</div>
But instead i need to create a box without zooming the image on hover. So in my exercise using this Using only CSS, show div on hover over <a> i have developed this.
main.js
div {
display: none;
}
img:hover + div {
display: block;
height : 200px;
width : 300px;
}
But the problem is that the size of the image should be dynamically adjusted based on the image we are hovering.
Is there a way to make this work when we hover over an image it should automatically make a div which should hold 1.5 times the dimensions of the image.Any suggestions.?Please help
I have included the screenshot below for reference.
img:hover div {
display: block;
var img = document.getElementById('imageid');
// get the image dimensions using this id
var width1 = img.clientWidth;
var height1 = img.clientHeight;
height : width * 1.5;
width : height * 1.5;
}
You need to just remove
+
because it selects immediate next div element to img.
I guess you should try:
img:hover ~ div
{
//your height and width goes here
}
I think this is the sort of thing you wanted.
I don't think you can do this with CSS only (though would love to be wrong)
I've done a for loop to add an event listener on for when you mouse over and off an image in .zoomin. Then it sets the image source accordingly.
var zoominSel = document.querySelectorAll(".zoomin img");
var zoomContSel = document.querySelector(".zoomcont img")
for (let i = 0; i < zoominSel.length; i++) {
zoominSel[i].addEventListener("mouseover", function(event) {
zoomContSel.setAttribute('src', event.target.getAttribute('src'));
zoomContSel.style.width = event.target.offsetWidth + "px";
zoomContSel.style.height = event.target.offsetHeight + "px";
zoomContSel.parentElement.style.top = event.target.offsetTop + "px";
zoomContSel.parentElement.style.left = (event.target.offsetLeft + event.target.offsetWidth + 2) + "px";
});
zoominSel[i].addEventListener("mouseout", function(event) {
zoomContSel.setAttribute('src', '');
});
}
body {
margin: 0;
}
.zoomin img {
max-width: 200px;
}
.zoomcont img[src=""] {
display: none;
}
.zoomcont {
z-index: 1000;
position: absolute;
transform: scale(1.5);
transform-origin: 0 0;
}
<div class="zoomin">
<img src="http://www.corelangs.com/css/box/img/zimage.png" />
</div>
<div class="zoomin">
<img src="http://usabilitygeek.com/wp-content/uploads/2013/07/free-fonts-for-commercial-personal-use.jpg" />
</div>
<div class="zoomcont">
<img src="" />
</div>
Hope you find this helpful.
I'm trying to create a slider of images (previous/next) so the images slide to the left when I click "previous" and to the right when I click "next" with 0.5s of slowness, so it takes some animation. And when I reach the last image and click "next", I want images to "run backwards" to the first one, the same when I'm in the first one and click "previous", so it "run forward" until the last one.
I want the same behaviour this JSFiddle shows. (but I don't need the timer to move images automatically and don't need the "triggers" buttons, just "previous" and "next").
The problem here is that my images don't have fixed size. I define a width in percentage and can't define a height because I have responsive design, the image resizes as I resize the browser window.
The jQuery to previous/next actions is pretty easy, but I just can't find a way to add this animation when I remove/add the "active" class to my images (so they become visible or not).
I have already tried putting all images side by side and showing only the first one (setting container width equals to image width), so when I click "next" I just "move" the container to the left so it begins to display the next image, but it doesn't work because once I can't define the height of the images, they will appear underneath each other, not side by side.
JSFiddle
HTML
<div class="images">
<img class="active" src="1.jpg">
<img src="2.jpg">
<img src="3.jpg">
</div>
<div class="previous">previous</div>
<div class="next">next</div>
CSS
img {
width: 100px;
display: none;
float: left;
}
img.active {
display: block;
}
jQuery
$('.next').on('click', function() {
var active = $('img.active');
var next = active.next('img');
if (next.length) {
active.removeClass('active');
next.addClass('active');
} else {
active.removeClass('active');
$('.images img:first').addClass('active');
}
});
Well the problem is the height for sliding.
First you need to have an element which is the "picture frame" which hold all the other images. That's important.
For better imagination a picture:
Now you have several technics to show and hide images. One could be to set the opacity. When using transition: opacity .15s ease-in-out; The one Picture is fading out and the next on is fading in.
For the slideshow effect is given to the position of the visible image to its width to the left and the image previously purely new to his wide to the right and then to 0. Thus, moves the current picture on the left the frame out and the new comes out right in.
And here is the difficulty if the height is not the same. If the current image 300px high and the new 400px, so the image frame here would adjust his height immediately once the new image start to be visible.
The content below would start to jump with each slide.
Is that so desired???
If yes, I can make you an example how it works.
You can actually do this in Pure CSS!
You use an ID and a label (with a for attribute=for the targeted id)
That's basically it. All you have left is to style it! (Forked from Joshua Hibbert's Pen)
body {
background: #f7f4e2;
}
/* Slides */
.slider input {
display: none;
}
/* Buttons */
.slider label {
display: none;
cursor: pointer;
position: absolute;
top: 6em;
left: 50%;
transform: translateX(-50%);
color: #fff;
background: #000;
padding: 1.36em .5em;
opacity: .6;
font-size: 19px;
font-family: fantasy;
font-weight: bold;
transition: .25s;
}
.slider label:hover {
opacity: 1;
}
.previous {
margin-left: -188px;
}
.next {
margin-left: 188px;
}
#slide1:checked ~ .buttons .slide1 {
display: block;
}
#slide2:checked ~ .buttons .slide2 {
display: block;
}
#slide3:checked ~ .buttons .slide3 {
display: block;
}
#slide4:checked ~ .buttons .slide4 {
display: block;
}
/* Images */
.slider {
position: absolute;
top: 50%;
left: 50%;
width: 400px;
height: 300px;
margin-top: -150px;
margin-left: -200px;
white-space: nowrap;
padding: 0;
float: left;
transition: .25s;
overflow: hidden;
box-shadow: 0 0 0 3.12px #e8e8e8,
0 0 0 12.64px #eaebe4,
0 0 0 27.12px #000,
0 24px 3.824em 5.12px #000;
}
.slide {
width: 500em;
transition: .25s;
}
.slider img {
float: left;
width: 400px;
height: 300px;
}
#slide1:checked ~ .slide {
margin: 0;
}
#slide2:checked ~ .slide {
margin: 0 0 0 -400px;
}
#slide3:checked ~ .slide {
margin: 0 0 0 -800px;
}
#slide4:checked ~ .slide {
margin: 0 0 0 -1200px;
}
<div class="slider">
<input type="radio" name="slide" id="slide1" checked="true" />
<input type="radio" name="slide" id="slide2" />
<input type="radio" name="slide" id="slide3" />
<input type="radio" name="slide" id="slide4" />
<div class="buttons">
<!-- Slide 1 -->
<label for="slide4" class="slide1 previous"><</label>
<label for="slide2" class="slide1 next">></label>
<!-- Slide 2 -->
<label for="slide1" class="slide2 previous"><</label>
<label for="slide3" class="slide2 next">></label>
<!-- Slide 3 -->
<label for="slide2" class="slide3 previous"><</label>
<label for="slide4" class="slide3 next">></label>
<!-- Slide 4 -->
<label for="slide3" class="slide4 previous"><</label>
<label for="slide1" class="slide4 next">></label>
</div>
<div class="slide">
<img src="http://dribbble.s3.amazonaws.com/users/322/screenshots/872485/coldchase.jpg">
<img src="http://dribbble.s3.amazonaws.com/users/322/screenshots/980517/icehut_sm.jpg">
<img src="http://dribbble.s3.amazonaws.com/users/322/screenshots/943660/hq_sm.jpg">
<img src="http://dribbble.s3.amazonaws.com/users/322/screenshots/599584/home.jpg">
</div>
</div>
Although this method is the most compatible (except for old versions of IE) and depending on how you animate it this method can be more time consuming than a JS method, but can also be faster, it just depends on how you want the animations to go, or you could use a css library that does this for you.
Here are some css image sliders I recommend.
10 Amazing Pure CSS3 Image Sliders
http://bashooka.com/coding/pure-css3-image-sliders/
Pure CSS Image Slider Without Javascript #Codeconvey is a good solution for what you're looking for, but lots of CSS
http://codeconvey.com/pure-css-image-slider/
The downside to these along with what you're working on is that you can't touch to slide on a phone or tablet which is more common now a days with photo galleries.
I recommend checking out Fotorama it's amazing! :)
Perhaps not the ideal situation but at least it will give you an idea. you can use the animation function of jQuery and I also changed your code a bit. See demo here
Within your HTML I would say this:
<div id="images">
<div class="images-wrapper">
<img src="http://www.cutestpaw.com/wp-content/uploads/2016/02/In-the-spotlight.jpg">
<img src="http://www.cutestpaw.com/wp-content/uploads/2016/02/Bath-time-with-ducky.jpg">
<img src="http://www.cutestpaw.com/wp-content/uploads/2016/03/FB_IMG_1452981788903.jpg">
<img src="http://www.pictures-of-cats.org/images/Pixiebob-cat-list-of-cat-breeds-pictures-of-cats.jpg" />
</div>
</div>
<div class="previous">
previous
</div>
<div class="next">
next
</div>
and within your jQuery code you can animate the width:
$('.images-wrapper img:gt(0)').hide();
$('.next').click(function() {
$('.images-wrapper img:first-child').animate({width:'toggle'},350).next().fadeIn().end().appendTo('.images-wrapper');
});
$('.previous').click(function() {
$('.images-wrapper img:first-child').animate({width:'toggle'},350);
$('.images-wrapper img:last-child').prependTo('.images-wrapper').fadeOut();
$('.images-wrapper img:first-child').fadeIn();
});
With this implementation the whole process of changing and adding the active class to the image is removed and replaced by animation functions
Simplest solution (I think) is to force the items to be of the same size, by placing them in a div. You can even have the div show the image without the use of an img tag, by using the background-image CSS feature (see http://www.w3schools.com/css/css3_backgrounds.asp for more details).
The item CSS could look like:
.item {
background-size: contain;
background-position: center;
}
and in each item in the HTML:
<div class='item' style='background-image: url(img1.jpg)' />
<div class='item' style='background-image: url(img2.jpg)' />
<div class='item' style='background-image: url(img3.jpg)' />
I finally got there.
HERE is the fiddle with the solution I developed.
The main problem in the implementation of this image slider was that images, althought were all the same size, have dynamic width (defined in % on CSS) and dynamic height (not defined on CSS).
The solution was basically put an "fake" image (with opacity: 0) inside my container so the container get the actual size of images I will use in the slider; put a div to "hold" the real images with position: absolute and give it a width calculted by number of images * 100%; and for last, give each image in my slider a width of x%, based on number of images.
In the jQuery, I "move" the "images holder div" always by %, never by static values, once the width of everything can change if I resize the window.
If you start to slide the images to the left and right and then resize the window, you will see that it continues to work perfectly.
I have implemented using css3 animations. However this will require manipulating animation values in css every time a slide gets added or removed.
#keyframes slideAnim {
0% {
transform: translateX(0)
}
12.5% {
transform: translateX(0%);
}
25% {
transform: translateX(-25%);
}
37.5% {
transform: translateX(-25%)
}
50% {
transform: translateX(-50%)
}
62.5% {
transform: translateX(-50%)
}
75% {
transform: translateX(00%);
}
89.5% {
transform: translateX(00%)
}
100% {
transform: translateX(00%)
}
}
Here the animation values are set such that there is a pause between slide transitions. I have added a parent frame to show only one slide at a time.
Please refer this fiddle.
I am trying to have text appear over each image as the user hovers over that specific image. I don't want all of the text for every image to appear when a user hovers over one image. I have it where only the one photo becomes opaque but right now the text shows up for every image when hovering over any image.
HTML:
<div class="image">
<img class="projectImage" src="images/peralta.png" alt="">
<h3 class="hiddenH3">This is a test!</h3>
</div>
SCSS:
.image {
position: relative;
width: 100%;
.projectImage {
width: 100%;
transition: all 0.5s ease-in;
}
.hiddenH3 {
display: none;
position: absolute;
top: 45%;
width: 100%;
}
}
JS:
$('.projectImage').on("mouseover", function() {
$(this).closest('.projectImage').addClass("coolEffect");
$('.hiddenH3').fadeIn(1000);
});
$('.projectImage').on("mouseout", function() {
$(this).closest('.projectImage').removeClass("coolEffect");
$('.hiddenH3').fadeOut(1000);
});
Use .next along with this
$('.projectImage').on("mouseover", function() {
$(this).addClass("coolEffect");
$(this).next(".hiddenH3").fadeIn(1000);
});
$('.projectImage').on("mouseout", function() {
$(this).removeClass("coolEffect");
$(this).next(".hiddenH3").fadeOut(1000);
});
You can also remove .closest(".projectImage") as this refers to that image.
Why don't you do this with CSS? Since the selectors needed are very old and entrenched, you can do something like this:
.projectImage + h3 {
transition: opacity 1000ms;
opacity: 0;
}
.projectImage:hover + h3 {
opacity: 1;
}
This will fade in your h3 when you hover over the project image, as long as you structure it in that way (i.e., ing, then h3). You can also remove the classes cooLEffect and hiddenh3 as we have defined that by only targeting the h3 that comes after a project image.
The fancy transition effect will only work on modern browser, but older browsers gracefully degrade.
Edit: SASS / LESS
.image {
.projectImage {
& + h3 {
transition: opacity 1000ms;
opacity: 0;
}
&:hover + h3 {
opacity: 1;
}
}
}