Slide long image horizontally (full screen) - html

Could do with some help.
I need to slide a long image horizontally once and then back... I've followed a tutorial here https://css-tricks.com/creating-a-css-sliding-background-effect/ and its all working. My problem is I want the sliding image to be fullscreen (the image height needs to fit the browser viewpoint). Current image is 7676 x 3939. background-size: cover was an option but image is too large so it doesn't fit height-wise. So I'd like half the image (3838px - fullscreen) to show initially then slide to the other half and then back.
Would appreciate some assistance. Below is my code. Thanks.
.wrapper {
overflow: hidden;
}
.sliding-background {
background: url("long-image.jpg") center;
height: 100vh;
width: 7676px;
animation: slide 3s linear 1;
}
#keyframes slide {
0%{
transform: translate3d(0, 0, 0);
}
50%{
transform: translate3d(-3838px, 0, 0);
}
100%{
transform: translate3d(0, 0, 0);
}
}

Try add position relative or absolute to .sliding-background

You could also try animating the background position instead of the element itself. Then you should make your container full screen, like this:
body,
html {
margin: 0;
padding: 0;
}
#wrapper {
overflow: hidden;
}
.sliding-background {
background-image: url("https://upload.wikimedia.org/wikipedia/commons/9/93/Denali_National_Park_Polychrome_Mountains_Wide_17350px.jpg");
background-repeat: repeat-x;
background-size: cover;
height: 100vh;
width: 100vw;
animation: slide 45s linear infinite;
}
#keyframes slide {
0% {
background-position: 0 0;
}
50% {
background-position: 100% 0;
}
100% {
background-position: 0 0;
}
}
See: https://jsfiddle.net/9mLhdy4c/

Related

How to set transition for 2 backgrounds in an element?

in this code:
#p1 {
background-image: url(backimgs/first/1.jpg), url(backimgs/first/2.jpg);
background-color: #05080d;
background-position: left top, left bottom;
background-size: 100% 35%, 100% 65%;
}
I want when the page shows up, first show backimgs/first/1.jpg then after 1 sec show backimgs/first/2.jpg. how can I do it?
You can't animate background-images. You can change it, but there won't be any smooth transition:
#p1 {
background-image: url(backimgs/first/1.jpg), url(backimgs/first/2.jpg);
background-color: #05080d;
background-position: left top, left bottom;
background-size: 100% 35%, 100% 65%;
animation: change-bg;
animation-duration: 1s;
}
#keyframes change-bg {
0% {
background-image: url(backimgs/first/1.jpg), url(backimgs/first/2.jpg);
background-size: 100% 35%, 100% 65%;
}
100% {
background-image: url(backimgs/first/2.jpg), url(backimgs/first/1.jpg);
background-size: 100% 65%, 100% 35%;
}
}
If you want a smooth transition - you can use ::before and ::after with a background and animate the opacity of them. Let me know with a comment if you need more info on this aproach, I'll edit the post and show, how it's done.
You mention 'transition' in the title so you will need to control the two parts of the background separately.
To enable this, this snippet removes the backgrounds from the element itself, instead putting them onto two pseudo elements. The before pseudo element having the first image as background and the after pseudo element having the second one.
Separating the components in this way means we can animate the opacities, the first pseudo element going from opacity 0 to opacity 1 in the first second.
Note however that a little hack has been added to ths snippet. As the animation on the before pseudo element is to happen on load then there needs to be some method of waiting for the background image to load before the animation starts else there is a danger it will be part way through, or even finished, before the image is actually available.
I do not know the wider context of how you are testing for load being complete so have just put a delay in here for demo purposes. You'll need to decide what to do to avoid this inital load situation.
* {
margin: 0;
padding: 0;
}
#p1 {
/* added for this demo */
display: inline-block;
width: 100vw;
height: 100vh;
position: relative;
}
#p1::before,
#p1::after {
content: '';
position: absolute;
z-index: -1;
width: 100%;
left: 0;
display: inline-block;
background-color: #05080d;
background-size: cover;
background-repeat: no-repeat no-repeat;
background-position: center center;
animation: fadein 1s linear;
animation-fill-mode: forwards;
opacity: 0;
}
#p1::before {
top: 0;
height: 35%;
background-image: url(https://picsum.photos/id/1018/1024/768);
animation-delay: 1s;
/* a hack to ensure it is loaded before start the animation */
}
#p1::after {
bottom: 0;
height: 65%;
background-image: url(https://picsum.photos/id/1015/1024/768);
animation-delay: 2s;
}
#keyframes fadein {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
<div id="p1"></div>

Apply different animations to multiple backgrounds images in a single class

I have a single class named slider .I need to have different types of animation for different images.Please help me to implement that .Now all my images are having same mode of animation.I just want to keep a single class slider.
Here is my code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
body{
margin:0p;
padding:0p;
background: green;
perspective: 800px;
height: 100vh;
width: 100wh;
}
.slider{
/* background-image: url(https://www.mozilla.org/media/img/logos/firefox/logo-quantum.9c5e96634f92.png);
background-size: 800px 800px;
width: 800px;
height: 800px;
border: 2px solid;
color: pink;
*/
width:100vw;
height:100vh;
background: url(b1.jpg);
background-size: 100wh 100vh;
/* animation: slide 2s infinite;*/
animation: slide
2s infinite;
margin: 100px auto;
}
#keyframes slide{
from{
/* transform:rotateY(0deg);*/
/* transform: rotate3d(1, 1, 1, 0deg);*/
transform: rotate3d(0, 1, 0, 0deg);
background-color: pink;
}
to{
/* transform:rotateY(180deg);
transform: rotate3d(1, 1, 1, 360deg);*/
transform: rotate3d(0, 1, 0, 360deg);
background-color: pink;
}
25%{
background-image: url(b2.jpg);
background-size: 100wh 100vh;
}
50%{
background-image: url(b3.jpg);
background-size: 100wh 100vh;
}
75%{
background-image: url(b4.jpg);
background-size: 100wh 100vh;
}
100%{
background-image: url(b5.jpg);
background-size: 100wh 100vh;
}
}
</style>
</head>
<body>
<div class="slider"></div>
</body>
</html>
Here is the fiddle
My fiddle
Also one more doubt in each image there seems to be a repetition of image as if the same image gets reduced and a part of the image is getting added there .I just want to have a single image with 100% view not repetition.
Any help would be highly appreciated
This is called a slider and looking at the keyframes definition it seems as though you want to rotate a set of images in order using one animation, not different animations for each image. Tfhis is doable as long as you don't want totally different animations for each 'slide'.
A couple of points:
Your 'doubt' is justified. The image is being repeated as that is the default for background in CSS, set it to 'no-repeat' so you don't get the little extra bits.
The images may (or may not, depends on your use case, but in general) have differing aspect ratios and they may be different or not from the aspect ratio of the viewport (which the containing element uses to set its dimensions). Use either background-size: contain to ensure you see the whole image for every one, or cover if you want to have the entire viewport covered, though in that case either the top and bottom or the side may get cropped to fit
You probably want the background-position to be centered both horizontally and vertically rather than left and top which would be the default in this case.
Here's an altered snippet. Note that the sizes transform over a short time which you may or may not want. You can alter the keyframes to stop that (let me know if you need help with that). Also the very last image has no time to show itself so you probably want to look at the % settings to make sure it gets a look in.
body {
margin: 0p;
padding: 0p;
background: green;
perspective: 800px;
height: 100vh;
width: 100wh;
}
.slider {
/* background-image: url(https://www.mozilla.org/media/img/logos/firefox/logo-quantum.9c5e96634f92.png);
background-size: 800px 800px;
width: 800px;
height: 800px;
border: 2px solid;
color: pink;
*/
width: 100vw;
height: 100vh;
background: url(https://picsum.photos/id/1023/300/300);
background-repeat: no-repeat no-repeat;
/* ADDED */
background-position: center center;
/* ADDED */
background-size: cover;
/* ADDED - TRY BOTH TO DECIDE WHICH YOU WANT IF YOU HAVE IMAGES OF DIFFERENT ASPECT RATIOS */
background-size: contain;
/* ADDED */
background-size: 100wh 100vh;
/* animation: slide 2s infinite;*/
animation: slide 2s infinite;
margin: 100px auto;
}
#keyframes slide {
from {
/* transform:rotateY(0deg);*/
/* transform: rotate3d(1, 1, 1, 0deg);*/
transform: rotate3d(0, 1, 0, 0deg);
background-color: pink;
}
to {
/* transform:rotateY(180deg);
transform: rotate3d(1, 1, 1, 360deg);*/
transform: rotate3d(0, 1, 0, 360deg);
background-color: pink;
}
25% {
background-image: url(https://picsum.photos/id/1015/1024/768);
background-size: 100wh 100vh;
}
50% {
background-image: url(https://picsum.photos/id/1016/768/1024);
background-size: 100wh 100vh;
}
75% {
background-image: url(https://picsum.photos/id/1018/200/300);
background-size: 100wh 100vh;
}
100% {
background-image: url(https://picsum.photos/id/1020/300/300);
background-size: 100wh 100vh;
}
}
<div class="slider"></div>
UPDATE
In the above snippet each image gets the same animation. The requirement is for each to have its own (rotation, zoom et al). This can be achieved while still maintaining the single slider class requirement by having each part of the keyframes define the animation for that particular slide.
In this snippet there are 4 slides, each takes one quarter of the overall alloted time for one iteration of the animation. In each part the particular animation required is defined. This snippet assumes that you want to do the animation bit for half the time an image has the show it without moving for the remaining half. These timings can be altered by altering the %s in the keyframes.
The first image rotates, the second image zooms, the third image comes in from 0 opacity and the fourth image just shows without moving.
Obviously more images can be added and different types of movement, scaling, opacity defined by altering %s and inserting more background images.
Note: opacity will refer to the whole element, so the backgroud pink color also faded which looked odd so I removed it. If it is important to have a background you will have to think about an extra element and animating that, or decide not to use opacity as one of the things that change, or have green to pink change anyway.
body {
margin: 0p;
padding: 0p;
background: green;
perspective: 800px;
height: 100vh;
width: 100wh;
}
.slider {
width: 100vw;
height: 100vh;
background-repeat: no-repeat no-repeat;
/* ADDED */
background-position: center center;
/* ADDED */
background-size: cover;
/* ADDED - TRY BOTH TO DECIDE WHICH YOU WANT IF YOU HAVE IMAGES OF DIFFERENT ASPECT RATIOS */
background-size: contain;
/* ADDED */
animation: slide 16s infinite;
margin: 100px auto;
}
#keyframes slide {
0% {
transform: rotate3d(0, 1, 0, 0deg);
opacity: 1;
background-image: url(https://picsum.photos/id/1023/300/300);
}
12.5%,
24.99% {
/* to make the slide not move between those times */
transform: rotate3d(0, 1, 0, 360deg);
opacity: 1;
background-image: url(https://picsum.photos/id/1023/300/300);
}
25% {
transform: rotate3d(0, 0, 0, 0deg) scale(1);
opacity: 1;
background-image: url(https://picsum.photos/id/1015/1024/768);
}
37.5%,
49.99% {
/* so it scales up for the first half of its time, then stays there showing */
transform: rotate3d(0, 0, 0, 0deg) scale(1.5);
opacity: 1;
background-image: url(https://picsum.photos/id/1015/1024/768);
}
50% {
transform: rotate3d(0, 0, 0, 0deg) scale(1);
opacity: 0;
background-image: url(https://picsum.photos/id/1016/768/1024);
}
74.99% {
transform: rotate3d(0, 0, 0, 0deg) scale(1);
opacity: 1;
background-image: url(https://picsum.photos/id/1016/768/1024);
}
75% {
transform: rotate3d(0, 0, 0, 0deg) scale(1);
opacity: 1;
background-image: url(https://picsum.photos/id/1018/200/300);
}
100% {
transform: rotate3d(0, 0, 0, 0deg) scale(1);
opacity: 1;
background-image: url(https://picsum.photos/id/1018/200/300);
}
}
<div class="slider"></div>
The overall aimation has time of 16s to give each image 2 seconds to move and 2 seconds staying still.
You will find that you need to play around with opacity to stop very sudden changes if this is a problem.
The snippet repeats both the transform and the opacity setting each time which is not always necessary, but I find it serves as a reminder that transform needs all the settings in it, it's not 'cumulative'.

Problem: Getting a seamless marquee effect with an img to work, but it restarts visibly

I've been trying to get a marquee effect with a fog image to work for several days now. I tried several tutorials (videos and written ones), but the effect keeps visibly skipping/restarting and the effect is not seamless. The image itself is 1000px wide and is loopable. The two fog images are different and move at a different speed to have a better effect.
I did manage to get it to work with text, with the help of another tutorial, but the img version still poses problems. To clarify: The images are displayed, they move properly, but at some point the animation restarts/skips/jumps instead of seamlessly repeating the images.
My current version looks like the following (its a vue project):
.fog-container {
top: 0;
height: 100%;
overflow: hidden;
position: absolute;
width: 100%;
z-index: 0;
}
.fog-img {
height: 100%;
position: absolute;
width: 300vw;
}
.fog-img-first {
animation: marquee 120s linear infinite;
background-position: center;
background-repeat: repeat;
background-size: contain;
}
.fog-img-second {
animation: marquee 60s linear infinite;
background-position: center;
background-size: contain;
background-repeat: repeat;
}
#keyframes marquee {
0% {
transform: translate3d(0, 0, 0);
}
100% {
transform: translate3d(-200vw, 0, 0);
}
}
<v-main>
<div class="fog-container">
<div
:style="{'background-image':
`url(${require('./assets/pictures/background/fog_1.png')})`}"
class="fog-img fog-img-first"
/>
<div
:style="{'background-image':
`url(${require('./assets/pictures/background/fog_2.png')})`}"
class="fog-img fog-img-second"
/>
</div>
</v-main>

CSS animation not smooth enough

The animation is moving linearly from left to right but starts abruptly once the animation time is over. Tried with reducing to 1s and increasing the time to 15s. And even increased the keyframes but still doesn't work. Please help:
.grid-item-2 {
grid-column: 1 / span 2;
grid-row: 1;
background-image: url(Building_1.png);
margin-left: 100px;
margin-top: 53px;
width: 90%;
background-repeat: repeat-x;
animation: Buildings 2s linear infinite;
}
#keyframes Buildings {
0% { background-position: 0% 100%; }
25% { background-position: 25% 75%; }
50% { background-position: 50% 50%; }
75% { background-position: 75% 25%; }
100% { background-position: 100% 0; }
}
<div class="grid-item grid-item-2"></div>
The problem with the jumping is that you need to adapt the background image to the size of the div element, which can be hard if you want to have a responsive site. The code below is the best I can come up with, where I loop between -100% and 200%, making the image start outside the element and then end outside the other side of the element, creating the illusion that it continues. I would honestly replace repeat-x with just repeat.
I added a background color just to make the element more visible.
.grid-item-2 {
grid-column: 1 / span 2;
grid-row: 1;
background-image: url("https://picsum.photos/id/737/300/200.jpg");
/* margin-left: 100px;
margin-top: 53px; */
width: 90%;
background-repeat: repeat-x;
background-size: 50% 50%;
animation: Buildings 3s linear infinite;
background-color: #000; /* just to show case the element better */
height: 90vh;
}
#keyframes Buildings {
0% { background-position: -100% 200%; }
100% { background-position: 200% -100%; }
}
<div class="grid-item-2">
</div>
Getting rid of the intermediary keyframes would make it smoother. You only need the frames at 0% and 100%. When you set the animation timing function to linear, it will automatically make sure that all the keyframes that you defined are met. The animation should look something like this...
#keyframes Buildings {
0% {
background-position: 0% 100%;
}
100% {
background-position: 100% 0;
}
}

Css animations - animation is slow and jiggles

I wanted to ask, what is wrong with this CSS code? It is used to animate background image - zoom effect.
#media (min-width: 1000px) {
.anim-on {
background-size: 110% 110%;
background-position: center center;
animation: shrink 12s infinite alternate;
}
.anim-out {
background-size: 120% 120%;
background-position: center center;
animation: small 6s infinite alternate;
}
#keyframes shrink {
0% {
background-size: 110% 110%;
}
100% {
background-size: 100% 100%;
}
}
#keyframes small {
0% {
background-size: 100% 100%;
}
100% {
background-size: 110% 110%;
}
}
}
This code generates nice effect, but i saw, that on slower machines, affect is bad.
What is wrong? Or maybe someone has better idea, how create this effect, in better technique?
Background size is a visual property and so any change to its value would cause repainting to occur. Painting is a very expensive operation and is bound to have an impact on the performance in low end machines. One way to overcome this would be to use CSS transform (scale to be precise) instead of background-size change to produce the animation.
Snippet which will cause performance impact:
The below snippet uses the same animation as in the question. When you run this snippet and inspect it using Chrome Dev tools (by enabling "Show Paint Rects" option), you'd see that both images have a paint rect associated with them (green or red colored box) and that as the animation is happening the box keeps blinking (or stays as-is). This indicates that a repaint is happening often and thus it impacts performance.
.anim-on,
.anim-out {
height: 200px;
width: 200px;
background: url(http://lorempixel.com/200/200/nature/1);
}
.anim-on {
background-size: 110% 110%;
background-position: center center;
animation: shrink 12s infinite alternate;
}
.anim-out {
background-size: 120% 120%;
background-position: center center;
animation: small 6s infinite alternate;
}
#keyframes shrink {
0% {
background-size: 110% 110%;
}
100% {
background-size: 100% 100%;
}
}
#keyframes small {
0% {
background-size: 100% 100%;
}
100% {
background-size: 110% 110%;
}
}
/* Just for demo */
div {
float: left;
margin-right: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='anim-on'></div>
<div class='anim-out'></div>
Snippet which will cause lesser performance impact:
In the below snippet, I have added the background-image to a pseudo-element and then used scale transform on it to produce the zoom-in/out effect. The parent's overflow: hidden setting prevents the animation from affecting its size. If you inspect this with Chrome Dev tools you'd see that the green or red colored box appears only once when the page is loaded and goes away. This indicates that there is no further repaint is happening during the animation itself and hence it is better from a performance point of view. You'd also notice that this animation is more smoother than the earlier one.
.anim-on,
.anim-out {
position: relative;
height: 200px;
width: 200px;
overflow: hidden;
}
.anim-on:after,
.anim-out:after {
position: absolute;
content: '';
height: 100%;
width: 100%;
top: 0px;
left: 0px;
background: url(http://lorempixel.com/200/200/nature/1);
}
.anim-on:after {
animation: shrink 12s infinite alternate;
}
.anim-out:after {
animation: small 6s infinite alternate;
}
#keyframes shrink {
0% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}
#keyframes small {
0% {
transform: scale(1);
}
100% {
transform: scale(1.1);
}
}
/* Just for demo */
div {
float: left;
margin-right: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='anim-on'></div>
<div class='anim-out'></div>
You can find more information about the various CSS properties and how a change to their value will impact the rendering process in the CSS Triggers website.
You can find more information about the rendering process and how using transform (as opposed to few other properties) results in a performance improvement in the below articles/sites:
HTML5 Rocks - Accelerated Rendering in Chrome
GPU Accelerated Compositing in Chrome.
Google Developers - Rendering Performance.
I edited Henry code, now css is reusable, so user can add background image to element via CMS, and css code will do the rest:
.anim {
position: relative;
height: 100vh;
width: 100%;
overflow: hidden;
**background-size: 0px!important;**
}
.anim:after {
position: absolute;
content: '';
height: 100%;
width: 100%;
top: 0px;
left: 0px;
background-size: cover !important;
**background: inherit;**
z-index: -1;
}
.anim:after {
animation: shrink 12s infinite alternate;
}
#keyframes shrink {
0% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}
#keyframes small {
0% {
transform: scale(1);
}
100% {
transform: scale(1.1);
}
}
<section class="anim" style="background: url('images/1.png');"></section>
Thanks * :)