I want to create a component called CarouselItem which is functioning as an object within a carousel display, I want these items to have different opacities depending on how close to the middle of the carousel they are and fade to fully opaque when hovered over, to do this i need the CSS to be able to access a variable of the component state to see how opaque they should be before they are hovered. I read this other post on stackoverflow which talks about using an arrow function to create a style and use that in the react style but because i want to include keyframes I'm not sure how i would implement this. Any ideas on how to implment or other solutions that may work?
CSS used in fade in animation
.fade {
animation: fade-in-keyframes 2s;
}
#keyframes fade-in-keyframes {
from {opacity: 0}
to {opacity: 1}
}
(the from portion of the fade in keyframes section should use the variable from the react component instead of 0)
you can easily use styled-components. You can pass your component state as a prop to your CSS. it's very easy to use and I actually have code that I think could help you a lot
I will share the link with you
CodeSandBox
if you go to my styled.js file you will see my code
You can write a function that will generate keyframes based on your props. I think it will help a lot on this matter
const WaterDrop = styled.div`
animation-duration: 0.3s;
animation-fill-mode: forwards;
animation-timing-function: linear;
// this is the part that you you send the data as props to use it on your css
animation-name: ${({ keyFrameStep }) => goDownKeyFrame(keyFrameStep.start,
keyFrameStep.end)};
`;
this is how you pass you data
<WaterDrop keyFrameStep={keyFrameStep} />
and this the function I used to generate different keyframes based on my needs
const goDownKeyFrame = (start, end) => {
if (start > end) {
return keyframes`
0% {
top: ${
circleHeightWidth *
(totalAmountOfCircle % 2 === 0 && totalAmountOfCircle === start
? start - 1
: start) +
circleVerticalMargin * (2 * start - 1)
}px;
background-color: white;
border-radius: ${borderRadius}px;
}
50%{
background-color: white;
}
100% {
top: ${
circleHeightWidth * end + circleVerticalMargin * (2 * end + 1)
}px;
border-radius: ${borderRadius}px;
background-color: rgb(255,116,0);
}
`
} else if (start < end) {
return keyframes`
0% {
top: ${
circleHeightWidth * (start + 1) +
circleVerticalMargin * (2 * start + 1)
}px;
border-radius: ${borderRadius}px;
}
50%{
border-radius: 0px ${borderRadius}px ${borderRadius}px;
}
100% {
top: ${
circleHeightWidth * end + circleVerticalMargin * (2 * end + 1)
}px;
border-radius: ${borderRadius}px;
}
`
}
}
the js file won't work if you want see how it is work I strongly suggest to check out my codesandbox link
if you use Replit or StackBlitz
Replit
Stack Blitz
Related
I was trying to make a 100% pure css animation, fadein and fadeout when i click on hamburguer menu to reveal the sidebar, (the backdrop should showing opacity like 500 miliseconds) (like jquery fadein) and when i click inside the sidebar to close the menu (the backdrop should hidde the opacity in 2 seconds) (like jquery fadeout)
You can see the version of jquery code here: https://cdpn.io/gilperon/fullpage/ZErBzvY
This is a very simple code, to open menu i put the event on hamburguer icon onclick=' $('#menu-backdrop').fadeIn(500);' and close to close, i put onclick=' $('#menu-backdrop').fadeout(2000);'
If it is not possible to make 100% css pure the animation, since it should be activated by onclick, maybe use just the javascript pure to onclick to add class, and the animation by done via css
I have a lot of ways using height:0 and key frames, but it was not possible to make the animation fadeout, fadein it works.
I make a code that workds to fadein, but to fadeout not working:
Another options are welcome, maybe using visibility, or other ways to show and hidden the animation, display:none usually not works with css animation
#menu-backdrop {
display: none;
animation:fadeOut 5s linear;
}
#menu-backdrop.exibir {
display: block;
animation:fadeIn 0.5s linear;
}
#keyframes fadeIn {
0% {
opacity:0
}
100% {
opacity:1;
}
}
#keyframes fadeOut {
0% {
opacity:1
}
100% {
opacity:0;
}
}
If anyone can post a work solution should be great, thank you very much guys.
Okay what you need is a transition, and you need to move away from your display property as it will break your animations and transitions since you cannot animate or transition that property in CSS.
A quick example:
const button = document.querySelector( 'button' );
const nav = document.querySelector( 'nav' );
button.addEventListener( 'click', event => {
event.preventDefault();
nav.classList.toggle( 'active' );
});
nav {
position: fixed;
right: 0;
top: 0;
width: 50%;
height: 100%;
background: red;
transition: opacity .4s;
/* This should be set to 0, but to make the point
* of pointer-events clear, I will set it to slightly
* higher so you can see there's no interaction
* with the nav. */
opacity: .1;
pointer-events: none;
}
nav:hover {
/* If you can interact with the navigation,
* you will see it change color. */
background: blue;
}
nav.active {
opacity: 1;
pointer-events: all;
}
nav + button:before {
content: 'Open ';
}
nav.active + button:before {
content: 'Close ';
}
<nav></nav>
<button>Nav</button>
The above shows you that by combining pointer-events: none with opacity you can effectively hide your menu. I added the :hover state for the <nav> to show that you cannot click the <nav> when it is open, and you should therefor consider this element invisible to the user.
I am attempting to style a component with transform: translateX(...); css property. However, the existing component already uses transform: translate();, so my style is simply overwriting the existing transform property. What I would like to do is read the existing translate data on the element so I can simply add my translate amount to what is already there. My ideal solution would look something like this:
const Element = ...
const StyledElement = styled(Element)`
transform: translateX(${currentTranslate.x - 5});
`
The question is, How can I read the existing style from the underlying component?
My Specific Use Case
(for those interested)
The element I'm styling is a Tooltip from reactstrap, which is positioned using transform: translate(...position of target);. I'm trying to make the tooltip bounce a little to give it some life, so I'm using:
This code to add animation
const horizontalDoubleBounce = keyframes`
0% {
left: 0;
}
20% {
left: -5px;
}
40% {
left: 0;
}
60% {
left: -5px;
}
80% {
left: 0;
}
100% {
left: 0;
}
`
const SpotlightTooltip = styled(Tooltip)`
animation: ${horizontalDoubleBounce} 1000ms ease-in infinite;
`
I resorted to using the left property which is working because it doesn't override anything, but I would rather use transform: translate() for a smoother animation.
You have to read currentTranslate outside of component and pass it's value as a prop to your styled component.
const Element = (props) => {
const currentTranslate = window.scrollY // for example
// ...
return <StyledElement currentTranslate={currentTranslate}>
}
Styled component will be look:
const StyledElement = styled(Element)`
transform: ${({currentTranslate}) => `translateX(${currentTranslate - 5})`};
`
Could seem a duplicate of this question, but actually I am trying to affect the animation-delay property, not the animation timing itself.
I have an Angular template that creates list items by looping through them:
<div class="list-item" *ngFor="let item of items; let i = index" [attr.data-index]="i" style="animation-delay: {{ (i) + 's' }}"></div>
As you can see I already have the index and was hoping to use that to increment the animation delay on each element. But when I test in chrome, the style property isn't even computed, even though the index attribute is applied correctly. The animation, which I have specified in CSS, works fine, but the delay isn't applied:
.list-item {
animation: appear 0.3s ease-out forwards;
}
#keyframes appear
{
0%
{
top: 550px;
opacity: 0;
}
10%
{
opacity: 1;
}
100%
{
top: 30px;
opacity: 1;
}
}
Try Using ngStyle Directive:
[ngStyle]="{'animation-delay': i + 's'}"
Hope that works well, If not , please share a working example on stackblitz
I'd like to know if it's possible to start a non-looping GIF from the beginning with CSS animation? For my example I have two GIFs. The first counts 1,2,3 each second - the second GIF counts 4,5,6 each second.
My goal is to show the first GIF until it counts to 3, then switch to the second GIF until it counts to 6, where it stops. My issue is that the second GIF will always be on 6 if I get it to show, at all.
My setup is as follows:
<div id="gif-two" class="gif"></div>
<div id="gif-one" class="gif"></div>
CSS
.gif {
width: 300px;
height: 300px;
position: absolute;
top: 0;
left: 50%;
margin-left: -150px;
}
#gif-one {
background: url("http://i.imgur.com/jLTVHdY.gif");
}
#gif-two {
background: url("http://i.imgur.com/O61k5Nf.gif");
}
I'm at a loss on how to handle this at the moment. I've tried toggling visibility - but have no idea how to make this work in just CSS.
Note: It is possible to achieve what you want by using CSS animations (as you will see from this answer) but I'd recommend you to combine them into the same GIF and use it that way because the approach used in this answer is too complex (so much so that I may struggle to explain it).
When the GIF is added as abackground-image, both images are loaded at pretty much same time by the browser and the GIF animation starts executing immediately. This means that change from 4-5 on the second GIF is happening at almost the same time as 1-2 on the first GIF. So, when the first GIF's loop ends, the second GIF's loop would also have ended and this is why you'd always see only 6.
The only way to avoid that from happening is to make the browser load the image after the first loop is completed. Below snippet achieves just this in a very complicated manner. The below is how:
Initially the background image is added only to the first div (because it needs to start its own loop immediately).
An animation with duration of 3s is set to the first div. This animation will hide the first div (and its background image) after around 3s, which is, the time take for its loop to complete. The opacity change from 1 to 0 starts at 95% itself to create a fade-out effect. Otherwise, at the end of loop it looks as though it blinks off and the second GIF blinks on (which doesn't look pleasing).
The second div doesn't have any background image added to it at the start because if it is added then it will load immediately and start its loop. An animation with 3s duration is added to this also.
The animation on the second div is such that it gets the background image added to it only at the end of the animation (100%). This means that the second image is loaded only after 3s (duration) and it starts its loop only from that time (by which, the loop of the first is already completed).
.gif {
width: 300px;
height: 300px;
position: absolute;
top: 0;
left: 50%;
margin-left: -150px;
}
#gif-one {
animation: img 3s linear forwards;
background: url(http://i.imgur.com/jLTVHdY.gif?3);
}
#gif-two {
animation: img2 3s linear forwards;
z-index: -1;
}
#keyframes img {
0%, 95% {
opacity: 1;
}
100% {
opacity: 0;
}
}
#keyframes img2 {
0%, 99% {
background-image: none;
}
100%{
background: url(http://i.imgur.com/O61k5Nf.gif?3);
}
}
<div id="gif-one" class="gif"></div>
<div id="gif-two" class="gif"></div>
Note: As I was writing this answer, I realized that setting the background-image within #keyframes rules does not work in IE and Firefox. Hence, the above solution is WebKit only. Also, as far as I am aware there is no other pure CSS solution possible. You would have to use JavaScript and that would help in the cache busting that CBroe is referring to also. Below is a sample demo using JS.
Using single element + JS:
window.onload = function() {
var el = document.querySelector('.gif');
el.style.backgroundImage = 'url(http://i.imgur.com/jLTVHdY.gif' + Math.random() + ')';
setTimeout(function() {
el.style.backgroundImage = 'url(http://i.imgur.com/O61k5Nf.gif' + Math.random() + ')';
}, 3250);
}
.gif {
width: 300px;
height: 300px;
position: absolute;
top: 0;
left: 50%;
margin-left: -150px;
}
<div class="gif"></div>
Using two elements + JS:
window.onload = function() {
var el1 = document.querySelector('#gif-one'),
el2 = document.querySelector('#gif-two');
el1.style.backgroundImage = 'url(http://i.imgur.com/jLTVHdY.gif' + Math.random() + ')';
setTimeout(function() {
el1.style.opacity = '0';
el2.style.backgroundImage = 'url(http://i.imgur.com/O61k5Nf.gif' + Math.random() + ')';
}, 3250);
}
.gif {
width: 300px;
height: 300px;
position: absolute;
top: 0;
left: 50%;
margin-left: -150px;
transition: opacity .05s .5s;
}
<div id="gif-one" class="gif"></div>
<div id="gif-two" class="gif"></div>
I'm using Vaadin Tepi Filter Tree table to display trade portfolio record and want to blink the background of specified cell when data changed.
I can update the User Interface by using PUSH method in vaadin, but don't know how to blink the background color, please help.
You can basically achieve this by using CSS animations and the Vaadin addStyleName() function. When you want to blink your data, just add some style to the element that should blink. See the sample below on how to implement a background change with CSS animations.
.blink {
animation: blink 1s steps(5, start) 3;
-webkit-animation: blink 1s steps(5, start) 3;
width: 100px;
height: 100px;
}
#keyframes blink {
to {
background-color: green;
}
}
#-webkit-keyframes blink {
to {
background-color: blue;
}
}
<div class="blink"> </div>