CSS Keyframe animation on an image in React - javascript

I' trying to implement this straight-forward keyframe animation. But nothing moves.
The Waves component is in its own file, and the component is called from of a Grid component. Could this cause the trouble?
-src/App.js <-- Grid.js called here
-src/animations/Waves.js
-src/components/Grid.js <-- Waves.js called here
-public/index.css
React component looks like this:
const Waves = () => {
return (
<section>
<div className='singleWave waveAnimation'>
<Image src={wave}></Image>
</div>
</section>
)
}
css-file here:
.singleWave {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 100px;
background: url("../src/pics/wave.png");
background-size: "1000px, 100px";
top: 0.7vh;
opacity: 0.7;
}
.waveAnimation {
animation: "animate 30s linear infinite";
z-index: 1000;
opacity: 0.8;
animation-delay: 0s;
bottom: 0;
}
#keyframes animate {
0% {
background-position-x: 0;
}
100% {
background-position-x: 1000px;
}
}
#keyframes animate2
{
0% {
background-position-x: 0;
}
100% {
background-position-x: -1000px;
}
}
Sure, its unnecessary to declare the image twice (imported in the component and in the css-file). But the animation seems to work with neither of the two.

Related

Text Animation Flickering Problem in CSS and React

I managed to achieve this animation through CSS animations and React. but go stuck in flickering problem. I don't know why this is happening maybe 'cause I used setInterval or there is some problem with my css animations keyframes. help me to solve this problem. the flicker only occurs after some time. and after refreshing the page the animation works perfectly fine without flicker problem.
this is how the animation looks after refreshing the page and this is what I want too. (ignore the screen recorder watermark).
animation I want
but after sometime the animation starts flickering like this.
Flickering problem
here are the code snippets I wrote
jsx snippet
<div className="relative w-[280px] md:w-[350px] lg:w-[500px]">
<span>{"[ "}</span>
<p className="text_animate ml-2">
{dev ? "for" : "by"} Developers
</p>
<span className="absolute right-0 ">{" ]"}</span>
</div>
css snippet
.text_animate {
color: orange;
margin: 0 auto;
display: inline-block;
position: relative;
letter-spacing: .15em;
text-align: start;
animation: text-up 6s linear infinite;
cursor: none;
}
#keyframes text-up {
0% {
top:45px;
opacity: 0;
}
20% {
top:0;
opacity: 1;
}
35% {
top: 0;
opacity: 1;
}
50% {
top: -45px;
opacity: 0;
}
52% {
top: 45px;
opacity: 0;
}
70% {
top: 0;
opacity: 1;
}
85% {
top: 0;
opacity: 1;
}
100% {
top: -45px;
opacity: 0;
}
}
useState changing text
const [dev, setDev] = useState(true);
setInterval(() => {
setDev(!dev);
}, 3000);
If there is any better way to achieve this I would really love to learn so let me know that too.
Maybe you should put setInterval to useEffect, and remember to clear timer. Like this:
useEffect(() => {
const timer = setInterval(() => {
setDev(!dev);
}, 3000);
return () => {
clearInterval(timer);
}
}, []);
And there is a solution only using css to implement this, I will write a demo later.
EDIT:
Explain the above code:
useEffect with [] as second param will make sure run setInterval once when mount the component.
The clearInterval in return function will make sure engine GC the variables in setInterval callback functions when unmount the component, or the setInterval will still work even though you needn't it.
CSS only solution:
ul {
margin: 0;
padding: 0;
list-style-type: none;
}
li {
margin: 0;
padding: 0;
}
.scroll-container {
overflow: hidden;
height: calc(var(--line-h) * 1px);
line-height: calc(var(--line-h) * 1px);
font-size: 18px;
}
.scroll-container ul {
animation-name: move;
animation-duration: calc(var(--speed) * var(--lines));
animation-timing-function: steps(var(--lines));
animation-iteration-count: infinite;
}
.scroll-container ul li {
animation-name: li-move;
animation-duration: var(--speed);
animation-iteration-count: infinite;
}
#keyframes move {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(0, calc(var(--lines) * var(--line-h) * -1px));
}
}
#keyframes li-move {
0% {
transform: translate(0, 0);
}
50%,
100% {
transform: translate(0, calc(var(--line-h) * -1px));
}
}
<div
class="scroll-container"
style="--lines: 2; --line-h: 26; --speed: 3s"
>
<ul>
<li>For Developers</li>
<li>By Developers</li>
<!-- repeat first in tail for infinity -->
<li>For Developers</li>
</ul>
</div>
I leaned this from Chokcoco on CodePen but forget which post.

Increasing animation speed (CSS) of transform animation

I'm trying to find a way to speed up the transform (flip about the y axis) in 0.05 seconds. Basically, the image flips in 0.05 seconds. The flip animation however does not change despite what I did in CSS. Please help
CSS
<style>
.a {
width: 50px;
height: 50px;
position: relative;
animation-name: box;
animation-duration: 10s;
transition: transform 0.05s;
animation-iteration-count: infinite;
animation-direction: alternate;
}
#keyframes box {
0% { left: var(--rando0); top: var(--rando1); transform: rotateY(180deg);}
25% { transform: rotateY(180deg) left: var(--rando2); top: var(--rando3);}
50% { left: var(--rando4); top: var(--rando5); transform: rotateY(180deg);}
75% { transform: rotateY(180deg) left: var(--rando6); top: var(--rando7);}
100% { left: var(--rando8); top: var(--rando9); transform: rotateY(180deg);}
}
HTML
<img src="image.gif" alt="prgm" class='a left' class='character'>
JS
<script>
const root = document.querySelector(":root"); // we first get the root element
for(let i = 0; i < 10; i++) {
root.style.setProperty(`--rando${i}`, `${Math.floor(Math.random() * 200) + 1}px`);
}
</script>
Thanks
You can have two animations running at the same time. This snippet keeps the left/top animation at 10s and introduces a rotate animation at 0.5s. (At 0.05s the rotation gives very flashing result which didn't seem to be likely what you wanted).
const root = document.querySelector(":root"); // we first get the root element
for (let i = 0; i < 10; i++) {
root.style.setProperty(`--rando${i}`, `${Math.floor(Math.random() * 200) + 1}px`);
}
.a {
width: 50px;
height: 50px;
position: relative;
animation-name: box, rotate;
animation-duration: 10s, 0.5s;
animation-iteration-count: infinite;
animation-direction: alternate;
}
#keyframes rotate {
0%,
49.99%,
100% {
transform: rotateY(0);
}
50%,
99.99% {
transform: rotateY(180deg);
}
}
#keyframes box {
0% {
left: var(--rando0);
top: var(--rando1);
}
25% {
left: var(--rando2);
top: var(--rando3);
}
50% {
left: var(--rando4);
top: var(--rando5);
}
75% {
left: var(--rando6);
top: var(--rando7);
}
100% {
left: var(--rando8);
top: var(--rando9);
}
}
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRzhbV48pXypX9otxEVYrZ1etEOZqym7693twATGzSGqg&s" alt="prgm" class='a left' class='character'>
UPDATE: the requirement was clarified - the image is to flip instantaneously but every half second goes back to its initial orientation.
The keyframes named rotate have been changed so that it stays at 0degrees rotation for half the animation time, flips 180degrees and stays at that for the second half.

Vue: CSS animations on class change

I am creating a hamburger menu component in Vue but for some reason the animations do not work. It gets to what should be the end result of the animation, but there is no animation.
I trigger the animation through a class change.
I've read up some on Vue transitions but to me it seems like those are mostly used when actually removing or adding elements, which I am not doing, just changing styling in an element.
I include the whole component below, if it is of any help.
<template>
<div id="hamburgerWrapper" #click="changeClass()">
<div id="hamburger1" :class="classObject"></div>
<div id="hamburger2"></div>
<div id="hamburger3" :class="classObject"></div>
</div>
</template>
<script>
export default {
name: "hamburger",
data() {
return {
active: false
};
},
computed: {
classObject: function(){
return {
in: this.active,
out: !this.active
}
}
},
methods: {
changeClass(){
this.active = !this.active
}
}
};
</script>
<style lang="scss">
$height: 300px;
$width: $height;
#hamburgerWrapper{
margin-top: 30px;
margin-left: 30px;
width: $width;
height: $height;
background-color: rgb(192, 192, 192);
position: relative;
cursor: pointer;
#hamburger1,#hamburger2,#hamburger3{
position: absolute;
height: $height * 0.2;
width: $width;
background-color: blue;
border-radius: $height * 0.1;
}
#hamburger1{
top: 0;
//transform: translateY(($height/2)-($height * 0.1));
&.in{
animation: topIn 1s ease forwards;
}
&.out{
animation: topIn 1s ease reverse forwards;
}
}
#hamburger2{
top: 50%;
transform: translateY(-50%);
}
#hamburger3{
bottom: 0;
&.in{
animation: botIn 1s ease forwards;
}
&.out{
animation: botIn 1s ease reverse forwards;
}
}
}
#keyframes topIn {
0% {transform: translateY(0) rotate(0deg)}
50% {transform: translateY(($height/2)-($height * 0.1)) rotate(0deg)}
100% {transform: translateY(($height/2)-($height * 0.1)) rotate(45deg)}
}
#keyframes botIn {
0% {transform: translateY(0) rotate(0deg)}
50% {transform: translateY(-(($height/2)-($height * 0.1))) rotate(0deg)}
100% {transform: translateY(-(($height/2)-($height * 0.1))) rotate(-45deg)}
}
</style>
I changed the "out"-animation to not do the reversed "in"-animation, but instead just an own animation. That somehow worked.

How to make image move in a frame infinitely?

okay so I have this right here:
html:
<div class="object">
<img src="https://www.direktorenhaus.com/wp-content/uploads/2018/03/Kabali-After-Puja-6-1-800x533.jpg" alt="pic">
</div>
css:
.object {
animation: MoveLeftRight 10s linear infinite;
position: absolute;
top: 0;
right: 0;
}
#keyframes MoveLeftRight {
0%, 100% {
right: 0;
}
50% {
right: 300px;
}
}
demo: https://jsfiddle.net/kte1ar3p/
but instead of it moving left and right, right to left all the time, i want to to like go through... i.e when it goes from e.g right to left, it will come out again from right to left. i dont know if this makes sense as I am explaining...
like moving a big picture into a small frame.
EDIT:
I got this so far, which should do with a little bit of playing around. thank you. https://jsfiddle.net/rgsnwb79/
Change CSS
.object{
position: relative;
width: 300px;
height: 280px;
overflow: hidden;
}
.object img {
animation: MoveLeftRight 10s linear infinite;
position: absolute;
top: 0;
right: 0;
}
#keyframes MoveLeftRight {
0%, 100% {
right: 0;
}
50% {
right: -50%;
}
}
https://jsfiddle.net/kte1ar3p/2/
Considering you want to repeat the display of the image and its movement... What if you animated it like sliding the image off of itself (like a deck of cards)?
HTML
<div class="object">
<img class="slide" src="https://images.freecreatives.com/wp-content/uploads/2016/04/Abstract-Patterns-For-Free.jpg" alt="pic">
</div>
CSS
body {
margin: 0;
}
.object {
background-image: url("https://images.freecreatives.com/wp-content/uploads/2016/04/Abstract-Patterns-For-Free.jpg");
width: 100vw;
height: 100vh;
}
.slide {
animation: MoveLeftRight 3s linear infinite;
position: absolute;
top: 0;
left: 0;
}
#keyframes MoveLeftRight {
0% { left: 0; }
50% { left: 50%; }
100% { left: 100%; }
}
https://jsfiddle.net/mittenmoon72/kte1ar3p/27/
If you're wanting a carousel, I'd just use one of the many JavaScript carousel libraries out there.

How to make a permanent change background-position in js?

I know how to run the animation from point A to point B, so to speak, but do not know how to run continuously in a circle. Below is a small code prepared:
.bg {
display: block;
position: absolute;
width: 100%;
height: 100%;
background: url(http://www.dejurka.ru/wp-content/uploads/2015/06/watercolor-patterns4.jpg) top left/30%;
animation: bg 2s cubic-bezier(0, -0.02, 1, 0.99);
}
#keyframes bg {
0% {
background-position: left -100px;
}
100% {
background-position: left 0px;
}
}
<div class="bg"></div>
help with script
If by:
run continuously in a circle
You mean run animation in a loop, then you can add the infinite animation-iteration-count property. In the shortcode you can just add infinite to your animation property. See demo:
.bg {
display: block;
position: absolute;
width: 100%;
height: 100%;
background: url(http://www.dejurka.ru/wp-content/uploads/2015/06/watercolor-patterns4.jpg) top left/30%;
animation: bg 2s cubic-bezier(0, -0.02, 1, 0.99) infinite;
}
#keyframes bg {
0% {
background-position: left -100px;
}
100% {
background-position: left 0px;
}
}
<div class="bg"></div>
Edit: jQuery Solution
With jQuery you can use the animate() function to achieve the same effect.
// bg animation function
function bgAnimate(speed) {
// define bg div
var el = $('.bg');
// get current background y-axis position and convert to integer (strips `px`)
var posY = parseInt(el.css("background-position-y"));
// animate element
el.animate({
'background-position-y': posY + 100 // add 100px
},{
duration: speed,
easing: 'linear',
complete: function() {
bgAnimate(speed); // repeat aniamtion (loop)
}
});
}
bgAnimate(1000); // call function
html, body {padding: 0;margin: 0;}
.bg {
display: block;
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
background-image: url(http://www.dejurka.ru/wp-content/uploads/2015/06/watercolor-patterns4.jpg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="bg"></div>

Categories

Resources