AnimeJs implementation with react doesn't work - css

I've implemented a simple Anime Js text animation into my react app; I have other other Anime Js projects which perform perfectly but I just don't see the issue with this one, and why it doesn't work.
TextColourChangeLoader.js
import React from 'react';
import './styles/TextColourChangeLoader.css';
import anime from 'animejs';
export default class TextColourChangeLoader extends React.Component {
constructor(props) {
super(props);
this.state = {
text: "",
play: false
}
}
componentDidMount() {
this.setState({
text: this.props.textToRender,
play: true
})
}
componentWillUnmount() {
this.setState({
text: '',
play: false
})
}
playAnimeColourChange = () => {
if(this.state.play) {
anime({
targets: '.loader-letter',
delay: anime.stagger(100),
duration: 1000,
scale: anime.stagger(2, {easing: "easeInElastic"}),
color: '#7DE2FC',
direction: 'alternate',
easing: 'easeInOutElastic(1,.8)',
loop: true,
loopComplete: function() {
console.log('done')
}
});
}
}
render() {
this.playAnimeColourChange();
return (
<div id="loader-text-holder">
{this.state.text.split('').map((letter, i) => {
return <span id={letter === " " ? "loader-letter-space" : "loader-letter"+i} key={i} className="loader-letter text">{letter}</span>
})}
{this.playAnimeColourChange()}
</div>
)
}
}
Example.js
import React from 'react';
import './styles/ViewLoaderWithText.css';
import anime from 'animejs';
import TextColourChangeLoader from './TextColourChangeLoader';
export default class ViewLoaderWithText extends React.Component {
constructor(props) {
super(props);
this.state = {
play: false
}
}
componentDidMount() {
this.setState({
play: true
})
}
playAnime = () => {
if(this.state.play) {
let loaderAnime = anime({
targets: '.view-loader-shape',
delay: anime.stagger(100, {start: -100}),
translateY: [{value: -25, easing: 'easeInCubic'}, {value: 0, easing: 'easeOutCirc'}],
background: '#7DE2FC',
direction: 'alternate',
easing: 'easeInOutElastic(1,.8)',
duration: 1000,
loop: true,
autoplay: true
});
}
}
render() {
return (
<div id="view-loader-wrapper">
<div id="loader-shape-holder">
<span className="view-loader-shape" id="view-loader-shape1"></span>
<span className="view-loader-shape" id="view-loader-shape2"></span>
<span className="view-loader-shape" id="view-loader-shape3"></span>
<span className="view-loader-shape" id="view-loader-shape4"></span>
<span className="view-loader-shape" id="view-loader-shape5"></span>
</div>
<TextColourChangeLoader textToRender="Verifying email"/>
{this.playAnime()}
</div>
)
}
}
The anime js instance in the Example.js file works as it should; however the TextColourChangeLoader.js animation doesn't run. I've tried logging to the console each time a loop completes with the loopComplete callback option, and it shows that the loop is running however, the animation doesn't. I've also tried only running the TextColourChangeLoader.js animation, but that still doesn't work. What could be a possible explanation for this? Anything helps.

I think that doesn't work because you are trying to animate a component that had not loaded first. Remember the lifecycle flow in React, I prefer use React Hooks to solve the problem and this is the way: with the useEffect hook you pass in the animate function, in order to first render the component and then execute the function, not in the reverse order. I guess that the equivalent in class components is componentDidMount() so try to refactorize your code in order to connect the anime() with the componentDidMount. Conclusion, the main concept is first render the component and then execute the anime(). Sorry for my english level.

Related

How to apply user defined style(CSS) to React-Treebeard?

I'm working with treebeard in my react project.
when I try to add a user-defined style it's not getting applied to the container.
I have tried different methods to achieve this.
I tried to define the style from tag, tried to define style.css in a different file, import it and assign it to style in Treedeard tag.
the main goal is to change the background color and the position.
Here is my code:
workspace.jsx
import React from "react";
import {Treebeard} from 'react-treebeard';
import data from "./data";
export class WorkSpace extends React. Component {
constructor(props){
super(props);
this.state = {
data: {data}
};
this.onToggle = this.onToggle.bind(this);
const decorators = {
Container: (props) => {
return (
<div style={props.backgroundColor="yellow"}>
</div>
);
}
};
}
onToggle(node, toggled){
const {cursor, data} = this.state.data;
if (cursor) {
this.setState(() => ({cursor, active: false}));
}
node.active = true;
if (node.children) {
node.toggled = toggled;
}
this.setState(() => ({cursor: node, data: Object.assign({}, data)}));
}
render() {
return (
<div className="base_container">
<h3>Select Component</h3>
<div className="components">
<Treebeard
data={data}
onToggle={this.onToggle}
style = {style_components}
decorators={this.decorators}
/>
</div>
</div>
);
}
}

How to modify the css for reactjs-dropdown-component?

Goal
I need to modify the CSS for the reactjs-dropdown-component.
Background/Overview
I've downloaded the dropdown, imported it, and have it fully operational in react. However, I'm fairly new to coding and haven't yet been in a situation where I need to do significant styling to a downloaded component. Do I just recreate the stylesheet for it and import it?
The css for this component is in this Github repo: https://github.com/dbilgili/Custom-ReactJS-Dropdown-Components/blob/master/src/styles/stylus/dropdown.styl
The instructions I followed for downloading/using this dropdown are here: https://github.com/dbilgili/Custom-ReactJS-Dropdown-Components
I'm not sure that it's necessary but here is code where I'm using the dropdown
import React from 'react';
import './EventContainer.css';
import { Dropdown } from 'reactjs-dropdown-component';
import { dining } from './EventContainerIcons.js';
class EventContainer extends React.Component {
constructor(props){
super(props);
this.state = {
...props.event,
activityIcon: [
{
id: 0,
title: <img src={dining} width="64" height="64" alt="dining icon" />,
selected: false,
key: 'activityIcon'
},
{
id: 1,
title: 'Orange',
selected: false,
key: 'activityIcon'
},
{
id: 2,
title: 'Strawberry',
selected: false,
key: 'activityIcon'
}
],
};
}
handleTypeChange = (e) => {
this.setState({
type: e.target.value
})
}
handleTimeChange = (e) => {
this.setState({
time: e.target.value
})
}
handleSummaryChange = (e) => {
this.setState({
summary: e.target.value
})
}
handleNotesChange = (e) => {
this.setState({
notes: e.target.value
})
}
resetThenSet = (id, key) => {
let temp = this.state[key];
temp.forEach(item => (item.selected = false));
temp[id].selected = true;
this.setState({
[key]: temp
});
};
render(){
return (
<div className="eventContainer-flex">
<Dropdown
title="Event Type"
list={this.state.activityIcon}
resetThenSet={this.resetThenSet}
/>
<div>
<input
className="time-input-styling"
type="time"
value={this.state.time}
onChange={this.handleTimeChange}/>
</div>
<div>
<textarea
className="textarea-styling"
/*placeholder="Write summary here"*/
value={this.state.summary}
onChange={this.handleSummaryChange}
cols={60}
rows={3} />
</div>
<div>
<textarea
className="textarea-styling"
/*placeholder="Write notes here"*/
value={this.state.notes}
onChange={this.handleNotesChange}
cols={30}
rows={3} />
</div>
</div>
)
}
}
export default EventContainer;
In the documentation, they alreayd said it:
Refer to the following styling file for overriding the default styles.
You can create your own styling file with the same class names in
order to do your custom styling.
So, you have to create your css file, with the classes and override the classes you want.

trying to create the toggled menu bar with react.js but the code is not working?

the problem is that I wanted a toggle menu and I created a hamburger apply css on it and set up the methods but its not working, there is no errors given
import React, { Component } from 'react'
import './toggle.css';
export default class toggle extends Component {
constructor(props){`enter code here`
super(props);
this.state={
switch:false
}
}
handleSwitch=()=>{
this.setState={
switch:!this.state.switch
}
}
render() {
let className='toggle-switch';
if(this.state.switch){
className='toggle-switch changes';
}
return (
<div className={className} onClick={this.handleSwitch}>
<span className="bars1"></span>
<span className="bars2"></span>
<span className="bars3"></span>
</div>
)
}
}
setState is a function. Your handler should be
handleSwitch = () => this.setState({
switch: !this.state.switch
})
Or better yet, when referencing the past state value its best to use a function
handleSwitch = () => this.setState( prevState => ({
switch: !prevState.switch
}))
You need to use setState as function and I recommend to practice binding handleSwitch in constructor to access states for clearly understanding how it works:
constructor(props){
super(props);
this.state={
switch: false
}
this.handleSwitch = this.handeSwitch.bind(this);
}
handleSwitch() {
this.setState({
switch: !this.state.switch
});
}

Access Event Of Component That Is Passed As Prop

I pass a React Component as a Prop to a child.
That component has an event.
In child component, I want to get access to that event and bind it to a method inside child. How can I do that ?
I often use Semantic-UI React Modal as following:
class Example extends Component {
constructor(props) {
super(props);
this.state = {
modalOpen: false
}
}
handleOpen = () => this.setState({ modalOpen: true })
handleClose = () => this.setState({ modalOpen: false })
render(){
return(
<Modal
onClose={this.handleClose}
open={this.state.modalOpen}
trigger={<Button onClick={this.handleOpen}>Gandalf</Button>}>
<Modal.Header>Balrog</Modal.Header>
<Modal.Content>
<h1>You shall not pass!</h1>
{/*
Some form that closes Modal on success
onSuccess : this.handleClose
*/}
<Button onClick={this.handleClose}>Grrrrr</Button>
</Modal.Content>
</Modal>
)
}
}
export default Example
Now I want to make it reusable
import React, { Component } from 'react'
import { Modal } from 'semantic-ui-react'
class ReusableModal extends Component {
constructor(props) {
super(props);
this.state = {
modalOpen: false
}
}
handleOpen = () => this.setState({ modalOpen: true })
handleClose = () => this.setState({ modalOpen: false })
render(){
return(
<Modal
onClose={() => this.handleClose}
open={this.state.modalOpen}
{/*
How to access onClick event on trigger prop content ?
this.prop.trigger can be a Button or a Menu.Item
*/}
{...this.props}>
{this.props.children}
</Modal>
)
}
}
How can I have access to the trigger prop Component and bind its onClick event to handleOpen method ?
Edit :
to be more precise here is what I'm looking for
<ChildComponent trigger={<Button>This button should fire a function defined in child component</Button>} />
ChildComponent extends Component {
functionToCall = () => { console.log('hello') }
// I would like to :
// let myButton = this.props.trigger
// myButton.onClick = functionToCall
}
In React, data flows from parent to child. If there are multiple child components that have events that need to trigger changes in parent component you must fire callback function in child component.
Parent component:
handleOpen = () => { // do something }
(...)
<childComponent onClickCallback={this.handleOpen}
And in child component:
<button onClick={this.props.onClickCallback}> Click to close</button>
Pass this.handleOpen as a prop and call it as a prop in child component, and it will trigger function in the parent component, where you can handle data however you want.
Is this what you asked for?
The key here is to clone element
ChildComponent extends Component {
functionToCall = () => { console.log('hello') }
this.Trigger = React.cloneElement(
this.props.trigger,
{ onClick: this.functionToCall }
)
}

MDL - ripple effect changes margin on some elements

I'm using react with mdl and I want to create a menu with a drawer, and I'm pretty happy with the result, except one thing, when there is a scroller on the menu and I click on a menu item there is a ripple effect that sometimes makes the other menu items move a bit:
I don't know what is going on, here is my menu item component:
import React from 'react'
export default class MenuItem extends React.Component {
constructor(props) {
super(props);
this.onClick = this.onClick.bind(this);
}
onClick() {
this.props.onClick(this.props.id);
}
render () {
let liClassNames = this.props.isSelected ? 'menuItemSelected' : 'menuItemNotSelected';
return (
<div className={'mdl-list__item mdl-button mdl-js-button mdl-js-ripple-effect menuItem ' + liClassNames} onClick={this.onClick}>
<span className='mdl-list__item-primary-content'>
<i className={'material-icons menuItemIcon md-28'}>{this.props.icon}</i>
<span>{this.props.screenName}</span>
</span>
</div>
)
}
}
React.propTypes = {
id: React.PropTypes.number.isRequired,
screenName: React.PropTypes.string.isRequired,
icon: React.PropTypes.string.isRequired,
isSelected: React.PropTypes.bool.isRequired,
onClick: React.PropTypes.func.isRequired
};
Menu:
import React from 'react';
import MenuItem from './MenuItem';
export default class Menu extends React.Component {
constructor(props) {
super(props);
this.state = {
isMaximized: true,
selectedMenuItem: this.props.modules[0].screens[0].id
};
this.handleMenuToggle = this.handleMenuToggle.bind(this);
this.onMenuItemClick = this.onMenuItemClick.bind(this);
}
handleMenuToggle() {
this.setState({ isMaximized: !this.state.isMaximized });
}
onMenuItemClick(screenId) {
this.setState({ selectedMenuItem: screenId });
}
render () {
let drawerClassNames = this.state.isMaximized ? 'drawerMaximized' : 'drawerMinimized';
return (
<div className='mdl-js-layout mdl-layout--fixed-drawer'>
<div className={'mdl-layout__drawer drawer scrollbar ' + drawerClassNames }>
<ul className='demo-list-item mdl-list content'>
{this.props.modules.map((module, index) =>
<li key={index}>
<span className="mdl-layout-title menuHeader">{module.moduleName}</span>
{module.screens.map((screen) =>
<MenuItem key={screen.id}
id={screen.id}
screenName={screen.screenName}
icon={screen.icon}
isSelected={ screen.id === this.state.selectedMenuItem ? true : false }
onClick={this.onMenuItemClick}/>
)}
</li>)}
</ul>
</div>
</div>
);
}
}
Menu.propTypes = {
modules: React.PropTypes.arrayOf(
React.PropTypes.shape({
moduleName: React.PropTypes.string.isRequired,
id: React.PropTypes.number.isRequired,
screens: React.PropTypes.arrayOf(
React.PropTypes.shape({
id: React.PropTypes.number.isRequired,
screenName: React.PropTypes.string.isRequired,
icon: React.PropTypes.string.isRequired
})
).isRequired
}
)
).isRequired
}
When I remove the ripple effect from the li tag, (mdl-js-ripple-effect class) it works fine.
What is the problem here?

Resources