I have an element which should render when the page is loaded:
{this.state.pageLoaded && <MyComponent className={classes.container} /> }
When this component is rendered I would like for it to fade in. So I am trying to apply some jss, but can't get it quite work.
This is my JSS:
const styles = theme => ({
'#keyframes fadein': {
from: { opacity: 0 },
to : { opacity: 1 }
},
/* Firefox < 16 */
'#-moz-keyframes fadein': {
from: { opacity: 0 },
to : { opacity: 1 }
},
/* Safari, Chrome and Opera > 12.1 */
'#-webkit-keyframes fadein': {
from: { opacity: 0 },
to : { opacity: 1 }
},
/* Internet Explorer */
'#-ms-keyframes fadein': {
from: { opacity: 0 },
to : { opacity: 1 }
},
/* Opera < 12.1 */
'#-o-keyframes fadein': {
from: { opacity: 0 },
to : { opacity: 1 }
},
container: {
//How do I insert like -webkit-animation in here????
animation: '$fadein',
},
});
I do not know if my syntax is correct as I am confused with how to apply things with special character like #keyframes, --webkit-animation, etc... so that different browsers will work.
When I run the page no animations happen and I get the following warninings in my console:
Warning: [JSS] Unknown rule #-moz-keyframes fadein
Warning: [JSS] Unknown rule #-webkit-keyframes fadein
Warning: [JSS] Unknown rule #-ms-keyframes fadein
Warning: [JSS] Unknown rule #-o-keyframes fadein
To achieve this in JSS, you need to declare a key-frames property to your styles object like so;
export default ({
'#keyframes ring': {
from: {
transform: 'rotate(0deg)',
},
to: {
transform: 'rotate(360deg)',
},
},
someClassName: {
animationDelay: '-0.2s',
animationDuration: '1s',
animationIterationCount: 'infinite',
animationName: '$ring', <-- HERE IS HOW YOU REFERENCE TO IT
animationTimingFunction: 'cubic-bezier(0.5, 0, 0.5, 1)',
},
});
You can apply this effect with some css.
.fade-in {
animation: fade-in 2s;
}
#keyframes fade-in {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
Just add fade-in className to your component and add this code to your css file.
Since you do not want to use css. You may save some time by adding something like http://react-animations.herokuapp.com/ or https://digital-flowers.github.io/react-animated-css.html to your app.
By following the documentation you can add animations to your react project.
I would go this route if you are unwilling to add css or sass to the project.
Related
Is it possible to pass a value from html to the tailwind.config.js file?
I essentially want to do something similar to how we can pass a value from HTML to CSS using use custom properties. But instead passing it to the tailwind.config.js file.
For example, with HTML and CSS you can do:
.fill-color {
color: var(--color);
}
<div class="fill-color" style="--color: blue;">Test</div>
but in my project I need to pass in a variable like: 20 from the index.html file:
<div class="scroll" style="--variable-number: 20">Test</div>
So I can use it to set the keyframes percentage correctly: Tailwind.config.js file below
module.exports = {
extend: {
animation: {
scroll: 'scroll 25s linear infinite'
}
},
keyframes: {
scroll: {
'0%': {transform: 'translateX(0%)'},
'100%': {transform: 'translateX(NEED 20 VALUE HERE%)' },
}
},
}
Yes, you can do what you want to achieve, see this playground for a working example. Just add var(--percentage) to the translateX.
HTML:
<div class="animate-text-scroll" style="--percentage: 20%">Test</div>
Tailwind config:
module.exports = {
theme: {
extend: {
keyframes: {
'scroll': {
'0%': { transform: 'translateX(0)' },
'100%': { transform: 'translateX(var(--percentage))' },
},
},
animation: {
'text-scroll': 'scroll 2s linear infinite',
},
},
},
plugins: [],
}
Hope this helps.
You can achieve this using custom css variable and arbitrary values.
Heres a demo: https://play.tailwindcss.com/qEqKUVP8IQ
Whats happening:
First we define our custom keyframes and animation in the config. allowing it to read a css var like so:
extend: {
keyframes: {
scroll: {
'0%': {transform: 'translateX(0)'},
'100%': {transform: 'translateX(var(--scroll-distance))' },
}
},
animation: {
scroll: 'scroll 1s linear infinite'
},
},
then we can use arbitrary values in our class naming like so:
<div class="animate-scroll [--scroll-distance:20px]">Test</div>
<div class="animate-scroll [--scroll-distance:50px]">Test</div>
So same animation, but a custom distance on multiple elements.
The other option is to define a default value in the css file like so:
:root {--new-variable: red;}
and use it on an element
<div class="bg-[color:var(--new-variable)]">Test</div>
Hope that helps.
I'm using the library https://github.com/hypeserver/react-date-range , react 17.0.2 and next 12.0.0
I would like that when I change from one month to another, instead of making a sudden change, to be able to configure a Fade-In, or a Slide, just as it happens in the AirBnb calendar.
Does anyone know how I can do this? Thank you very much and sorry for the inconvenience.
This is my actual behavior
This is something like what I want, but it could also be a fade in or something similar.
Exactly like Airbnb i believe its not possible because the react-date-range works a little different from what airbnb does.
But you can get similar behavior using SwitchTransition and CSSTransition from react-transition-group library. You can check their docs here.
First, here's the code sample with DateRangerPicker using CSSTransition between months.
And below the same code, with comments on what its doing:
CSS file:
/*
Overflow the Calendar container
.rdrDateRangeWrapper is a class that react-date-range creates internally
*/
.rdrDateRangeWrapper {
overflow-x: hidden;
}
/*
.rdrMonths is the class that react-date-range creates internally for the month container calendar
.fadeRightToLeft classes is related to react-transition-group
Created for transition from right to left
*/
.fadeRightToLeft-enter .rdrMonths {
opacity: 0;
transform: translateX(100%);
}
.fadeRightToLeft-enter-active .rdrMonths {
opacity: 1;
transform: translateX(0%);
}
.fadeRightToLeft-exit .rdrMonths {
opacity: 1;
transform: translateX(0%);
}
.fadeRightToLeft-exit-active .rdrMonths {
opacity: 0;
transform: translateX(-100%);
}
.fadeRightToLeft-enter-active .rdrMonths,
.fadeRightToLeft-exit-active .rdrMonths {
transition: opacity 100ms, transform 100ms;
}
/*
Same as fadeRightToLeft:
.fadeLeftToRight classes is related to react-transition-group
Created for transition from left to right
*/
.fadeLeftToRight-enter .rdrMonths {
opacity: 0;
transform: translateX(-100%);
}
.fadeLeftToRight-enter-active .rdrMonths {
opacity: 1;
transform: translateX(0%);
}
.fadeLeftToRight-exit .rdrMonths {
opacity: 1;
transform: translateX(0%);
}
.fadeLeftToRight-exit-active .rdrMonths {
opacity: 0;
transform: translateX(100%);
}
.fadeLeftToRight-enter-active .rdrMonths,
.fadeLeftToRight-exit-active .rdrMonths {
transition: opacity 100ms, transform 100ms;
}
Component file:
import { useState } from "react";
import { addDays, isAfter } from "date-fns";
import { DateRangePicker } from "react-date-range";
import { SwitchTransition, CSSTransition } from "react-transition-group";
import "react-date-range/dist/styles.css";
import "react-date-range/dist/theme/default.css";
import "./styles.css";
export default function App() {
const [state, setState] = useState([
{
startDate: new Date(),
endDate: addDays(new Date(), 7),
key: "selection"
}
]);
// state created to hold the first month that calendar is showing
const [shownDateChangeValue, setShownDateChangeValue] = useState(new Date());
// state created to check if use created next Month ou previous month
const [isNextMonth, setIsNextMonth] = useState(true);
return (
<SwitchTransition mode="out-in">
<CSSTransition
/*** call the transition when month changes ***/
key={shownDateChangeValue}
/*** code related to SwitchTransition ***/
addEndListener={(node, done) =>
node.addEventListener("transitionend", done, false)
}
/*** Set the transition class related to the user action ***/
classNames={isNextMonth ? "fadeRightToLeft" : "fadeLeftToRight"}
>
<DateRangePicker
onChange={(item) => {
setState([item.selection]);
}}
showSelectionPreview={true}
moveRangeOnFirstSelection={false}
months={2}
ranges={state}
direction="horizontal"
/*** set the current month ***/
shownDate={shownDateChangeValue}
/*** Change shownDateChangeValue and isNextMonth states, dispatching the transition ***/
onShownDateChange={(month) => {
/* check if user click next or previous month */
const isNext = isAfter(month, shownDateChangeValue);
setIsNextMonth(isNext ? true : false);
setShownDateChangeValue(month);
}}
/>
</CSSTransition>
</SwitchTransition>
);
}
I am trying to create a bunch of animations that should be calculated.
I am omitting the actual calculation of those animations here as they are not relevant.
The problem I am having is in producing the correct #keyframes constructs.
here is my stripped back less:
.Entry(#animCount, #frameResolution)
{
.CreateAnim(#animNum) when (#animNum =< #animCount)
{
#keyframesname: ~'MyAnimation-#{animNum}';
.frame(#frame) when (#frame =< 100%)
{
#{frame}
{
hello1: #frame;
hello2: #animNum;
}
// .frame( ((#frame + #frameResolution)) );
}
#keyframes #keyframesname {
.frame(0%);
}
.CreateAnim(((#animNum + 1 )));
}
.CreateAnim(1);
}
and this is how it might be called:
.Entry(3, 50%);
I'm compiling it like so:
lessc -m=strict-legacy bug.less bug.css
I expected output such as this:
#keyframes MyAnimation-1 {
0% {
hello1: 0%;
hello2: 1;
}
}
#keyframes MyAnimation-2 {
0% {
hello1: 0%;
hello2: 2;
}
}
#keyframes MyAnimation-3 {
0% {
hello1: 0%;
hello2: 3;
}
}
But in fact MyAnimation-1 also contains all the keyframes from MyAnimation-2 and MyAnimation-3, while MyAnimation-2 contains also contains all the keyframes from MyAnimation-3
Is this a bug in less, or have I done something wrong?
$lessc --version
lessc 3.9.0 (Less Compiler) [JavaScript]
I use this inline transform to iterate dynamically over slides
<div className="slides" style={{transform: `translate(${currentPosition}%, 0px)`, left: 0}}> {slider} </div>
</div>
which is working fine. However I would like to add some fadein to this element on position changing and the following css does not working
on element slides via css
opacity: 0;
animation: fadein 2s ease-in 1 forwards;
here is my fadein animation
#keyframes fadein {
from {
opacity:0;
}
to {
opacity:1;
}
}
What I'm missing in this case?
You can try something like this. That will give you idea how can you apply animations.
class Test extends React.Component {
constructor(props) {
super(props);
this.state = {
currentPosition: 0,
opacity: 0
}
}
componentDidMount() {
setTimeout(() => this.setState({
opacity: 1
}), 500);
}
handleClick() {
let self = this;
this.setState({
opacity: 0
}, () => setTimeout(() => self.setState({
opacity: 1
}), 2000))
}
render() {
return ( <
div >
<
div className = "slides"
style = {
{
transform: `translate(${this.state.currentPosition}%, 0px)`,
left: 0,
opacity: this.state.opacity
}
} > Some title to test animation < /div> <
button onClick = {
this.handleClick.bind(this)
} > Click < /button> <
/div>
)
}
}
React.render( < Test / > , document.getElementById('container'));
.slides {
transition: all 2s ease-in;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.min.js"></script>
<div id="container"></div>
Here is the fiddle.
Hope it helps.
I have a component that gets unmounted after ten seconds, and I just can't seem to get the leave-animations working with React CSSTransitionGroup. The appear classes gets added when the component mounts and those animations work well. However, the leave classes never gets added to the component on unmount. I've found several working jsfiddle examples, but the code doesn't work for me. I'm new to React so I'm hoping that someone can point me in the right direction. I've set the timeouts to be able to see if the classes gets added.
Main component:
this.state = {
renderBlankSlate: true,
//the rest of the initial state..
}
// This unmounts the component
componentDidMount() {
this.interval = setTimeout(() => this.setState({renderBlankSlate: false}), 10000);
}
{ this.state.renderBlankSlate ?
<ReactCSSTransisionGroup
component="div"
transitionName="slide"
transitionEnterTimeout={ 500 }
transitionAppear={ true }
transitionAppearTimeout={ 2000 }
transitionLeaveTimeout={ 5000 }
>
<BlankSlate />
</ReactCSSTransisionGroup>
: null }
CSS:
.slide-appear {
transform: translateX(110%);
height: 0;
opacity: 0;
}
.slide-appear.slide-appear-active {
transform: translateX(0);
height: 100%;
opacity: 1;
transition: all 2s ease-in;
}
.slide-leave {
transform: translateX(0);
}
.slide-leave.slide-leave-active {
transform: translateX(110%);
transition: 5s ease-in;
}
You probably want to add that ternary within the transition group.
<ReactCSSTransitionGroup
component="div"
transitionName="slide"
transitionEnterTimeout={ 500 }
transitionAppear={ true }
transitionAppearTimeout={ 2000 }
transitionLeaveTimeout={ 5000 }
>
{this.state.renderBlankSlate ? <BlankSlate /> : null}
</ReactCSSTransitionGroup>
The reason your leave animation isn't firing is because the Transition group is leaving as well