How to render a random trajectory animation infinitely, on some interval? - reactjs

What I would like is to create a code that 'shoots' out some image from the center of the screen to some random trajectory.
Here is the descriptional code I would like to achieve:
class Name extends React.Component{
render(){
return (
<img animation moving from centre to some random trajectory>
after few seconds...
<another img animation (the same one) moving from centre to some other random trajectory>
<do it many more times, until event occurs that will stop it>
);
}
}
I have made components that create interface, and that render an image animation of movement from centre to some random trajectory, but only once. I don't know how to make it repeatedly.
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import "./bootstrap/css/bootstrap.css";
import {CreateEnvironment} from './components/createEnvironment';
import {SheepsStart} from './components/sheepsStart';
class MainComponent extends React.Component {
render(){
return (
<React.Fragment>
<CreateEnvironment />
<SheepsStart />
</React.Fragment>
);
}
}
ReactDOM.render(<MainComponent/>, document.getElementById('root'));
Component CreateEnvironment is irrelevant, it creates 3 drawing divs.
Component SheepsStart:
import React from 'react';
import {CreateSheeps} from './createSheeps';
import sheep from '../images/sheep.png';
export class SheepsStart extends React.Component {
render(){
return (
<React.Fragment>
<CreateSheeps src = {sheep} alt = "Sheep"/>
</React.Fragment>
);
}
}
Styled component, which I needed so I could insert random #keyframes:
import styled from 'styled-components';
import { sheepWantsToEscape } from './KeyFrames';
export const CreateSheeps = styled.img`
width:2.5%;
z-index: 1;
position:absolute;
left:48.75%;
bottom:48.75%;
animation: ${sheepWantsToEscape} 4s;
animation-iteration-count:1;
animation-timing-function:linear;
`
export default CreateSheeps;
Component with #keyframes with random trajectory coordinates.Function createTrajectory calculates coordinates, and returns an array of two.
import styled, { keyframes } from 'styled-components';
import {createTrajectory} from './helperFunction';
let coordinates = createTrajectory();
export const sheepWantsToEscape = keyframes`
0% {
left:48.75%;
bottom:48.75%;
}
100% {
left:${coordinates[0]}%;
bottom:${coordinates[1]}%;
}

This is only an example, if you point out what you've tried out I'll can be more specific:
const base = 100;
class Hello extends React.Component {
state = {
myStyle : {
marginTop: base,
marginLeft: -base,
}
}
plusMinus = () => Math.random() < 0.5 ? -1 : 1;
randomize = () => {
this.setState({
myStyle: {
marginTop: Math.random()*base*this.plusMinus(),
marginBottom: Math.random()*base*this.plusMinus(),
},
});
}
render() {
return <div><img
style={{...this.state.myStyle}} src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a7/React-icon.svg/200px-React-icon.svg.png" />
<button onClick={this.randomize}>move</button>
</div>;
}
}
ReactDOM.render(
<Hello name="World" />,
document.getElementById('container')
);
https://jsfiddle.net/vya19fz2/

Related

React Progressbar not Visible?

I have created a React progress bar with the help of third part library
import React from "react";
import { css } from "#emotion/core";
import ClipLoader from "react-spinners/ClipLoader";
// Can be a string as well. Need to ensure each key-value pair ends with ;
const override = css`
display: block;
margin: 0 auto;
border-color: red;
`;
class AwesomeComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: true
};
}
render() {
return (
<div className="sweet-loading">
<ClipLoader
css={override}
size={150}
color={"#123abc"}
loading={this.state.loading}
/>
</div>
);
}
}
export default AwesomeComponent;
and then import in index.js file
import AwesomeComponent from './awesomeComponent.js';
ReactDOM.render(
<Provider store={store}>
<BrowserRouter>
<App />
<AwesomeComponent />
</BrowserRouter>
</Provider>,
document.getElementById("root")
);
In my application i want to show this progresbar when data loading from nodejs api or any button clicked ..But nothing visible in GUI related to progressbar.
If you are using class based component for react-promise-tracker then you need to use HOC promiseTrackerHoc :
import React from "react";
import { css } from "#emotion/core";
import ClipLoader from "react-spinners/ClipLoader";
import { promiseTrackerHoc } from "react-promise-tracker"; // <--------- HERE
// Can be a string as well. Need to ensure each key-value pair ends with ;
const override = css`
display: block;
margin: 0 auto;
border-color: red;
`;
class AwesomeComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: true
};
}
render() {
return (
this.props.promiseInProgress && // <--------- HERE
<div className="sweet-loading">
<ClipLoader
css={override}
size={150}
color={"#123abc"}
loading={this.state.loading}
/>
</div>
);
}
}
export default promiseTrackerHoc(AwesomeComponent); // <--------- HERE
WORKING DEMO :
Note :
You can checkout DOC, as they have explained everything, I
think you can help you to find out whatever the scenario you want to
implement
In this example, you can see how you can change the visibility of your spinner just changed the local state by clicking on button
https://codesandbox.io/s/modern-monad-4tipc?file=/src/AwesomeComponent.js

state value (on Test2.js) not changing in react-native for the given below code

First thing is that in Test1.js when i uses Test2.js two time.In the first one I passes the data="First" and in second one I passes data="Second". But when the screen render and when I press the Button First It show "First" on the screen but when I press button second,it do'nt render "Second" on screen.
As I found that the value of state in the Test2.js is not changing.
Can You explain me why the value of state is not changing in the Test2.js
And can anyone tell how to fix this.And more thing if I uses component instead of this.A() and this.B() it works fine but as below method not works.
Here is the code..
Test1.js
import React, { Component } from 'react'
import { Text, StyleSheet, View } from 'react-native'
import {Button} from 'react-native-elements'
import Test2 from './Test2';
var a = "First"
var b = "second"
export default class Test1 extends Component {
state={
activeA:true,
activeB:false
}
A = ()=>{
return( <Test2 data={a}/>)
}
B = () =>{
return(<Test2 data={b}/>)
}
render() {
return (
<View style={{ flex:1,justifyContent:'center',padding:20}}>
<Button buttonStyle={{ marginBottom: 10}} title="First" onPress={()=>{this.setState({activeA:true,activeB:false})}}/>
<Button buttonStyle={{ marginBottom: 10}} title="Second" onPress={()=>{this.setState({activeA:false,activeB:true,})}}/>
{this.state.activeA?this.A():this.B()}
</View>
)
}
}
Test2.js
import React, { Component } from 'react'
import { Text, View } from 'react-native'
export default class Test2 extends Component {
state={
data:this.props.data
}
render() {
return (
<View>
<Text syle = {{fontSize:20,}}> {this.state.data} </Text>
</View>
)
}
}
Do not transfer to the status value, but render directly.
Test2.js
import React, { Component } from 'react'
import { Text, View } from 'react-native'
export default class Test2 extends Component {
constructor(props) {
super(props);
const { data } = props
}
render() {
return (
<View>
<Text syle = {{fontSize:20,}}> {this.props.data} </Text>
</View>
)
}
}
Test2.propTypes = {
data: PropTypes.string
}

react-custom-scrollbars jumps to top on any action

I am using react-custom-scrollbars in a react web app because I need to have two independant scroll bars, one for the main panel and one for the drawer panel. My issue is that the content in the main panel is dynamic and whenever I take some action in the main panel that changes state the scroll bar jumps to the top of the panel again.
UPDATE:
I believe I need to list for onUpdate and handle the scroll position there. If it has changed then update if not do not move the position?
In code, I have a HOC call withScrollbar as follows:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import AutoSizer from 'react-virtualized-auto-sizer';
import { Scrollbars } from 'react-custom-scrollbars';
import { colors } from '../../theme/vars';
import { themes } from '../../types';
// This is a Higher Order Component (HOC) used to
// provide a scroll bar to other components
export default (ChildComponent, styling) => {
class ComposedComponent extends Component {
state = {
// position: ??
};
handleUpdate = () => {
//update position
//this.scrollbar.scrollToBottom();
};
render() {
return (
<AutoSizer>
{
({ width, height }) => (
<Scrollbars
style={{ width, height, backgroundColor: colors.WHITE, overflow: 'hidden', ...styling }}
onUpdate={() => this.handleUpdate()}
renderThumbVertical={props => <Thumb {...props} />}
autoHide
autoHideTimeout={1000}
autoHideDuration={200}
>
<ChildComponent {...this.props} />
</Scrollbars>
)
}
</AutoSizer>
);
}
}
return ComposedComponent;
};
const Thumb = styled.div`
background-color: ${props =>
props.theme.theme === themes.LIGHT ? colors.BLACK : colors.WHITE};
border-radius: 4px;
`;
in my MainView component I just wrap the export like this:
export default withScrollbar(LanguageProvider(connect(mapStateToProps, null)(MainView)));
I have read a few similar issues on this like this one: How to set initial scrollTop value to and this one scrollTo event but I cannot figure out how to implement in my case. Any tips or suggestions are greatly appreciated.
So I found a way to get this to work and it feels like a complete hack but I'm posting in hopes it might help someone else.
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import AutoSizer from 'react-virtualized-auto-sizer';
import { Scrollbars } from 'react-custom-scrollbars';
import { colors } from '../../theme/vars';
import { themes } from '../../types';
// This is a Higher Order Component (HOC) used to
// provide a scroll bar to other components
export default (ChildComponent, styling) => {
class ComposedComponent extends Component {
state = {
stateScrollTop: 0,
};
onScrollStart = () => {
if (this.props.childRef) { // need to pass in a ref from the child component
const { scrollTop } = this.props.childRef.current.getValues();
const deltaY = Math.abs(scrollTop - this.state.stateScrollTop);
if (deltaY > 100) { // 100 is arbitrary. It should not be a high value...
this.props.childRef.current.scrollTop(this.state.stateScrollTop);
}
}
};
handleUpdate = () => {
if (this.props.childRef) {
const { scrollTop } = this.props.childRef.current.getValues();
this.setState({ stateScrollTop: scrollTop });
}
};
render() {
return (
<AutoSizer>
{
({ width, height }) => (
<Scrollbars
ref={this.props.childRef}
style={{ width, height, backgroundColor: colors.WHITE, overflow: 'hidden', ...styling }}
onScrollStart={e => this.onScrollStart(e)}
onUpdate={e => this.handleUpdate(e)}
renderThumbVertical={props => <Thumb {...props} />}
autoHide
autoHideTimeout={1000}
autoHideDuration={200}
>
<ChildComponent {...this.props} />
</Scrollbars>
)
}
</AutoSizer>
);
}
}
return ComposedComponent;
};
const Thumb = styled.div`
background-color: ${props =>
props.theme.theme === themes.LIGHT ? colors.BLACK : colors.WHITE};
border-radius: 4px;
`;
I use this HOC like this:
create a ref for the component you want to use it with
pass the ref to the component that will use the HOC:
class SomeChildComponent extends Component {
...
viewRef = React.createRef();
...
render() {
return ( <MainView childRef={this.viewRef} />)
}
import and wrap the component
import withScrollbar from '../../hoc/withScrollbar';
...
export default withScrollbar(MainView);
I tried the above solution and it didn't seem to work for me.
However what did work was making sure that my child components inside Scrollbars were wrapped in a div with a height of 100%:
<Scrollbars>
<div style={{ height: '100%' }}>
<ChildComponent />
<ChildComponent />
</div>
</Scrollbars>

Managing state when changing backgroundImage

In state I'm setting background image with a photo and I wanted to do 2 buttons, one is changing background image to another photo and another is setting background image back to the first photo.
Here is piece of my code:
\\index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import "semantic-ui/dist/semantic.min.css";
import logo1 from "./modules/images/one.jpg";
ReactDOM.render(
<App bgImage={`url(${logo1})`} />,
document.getElementById("root")
);
\\App.js
import React, { Component } from "react";
import "./App.css";
import NavBar from "./modules/NavBar";
import logo1 from "./modules/images/one.jpg";
import logo2 from "./modules/images/night.jpg";
class App extends Component {
constructor(props) {
super(props);
this.state = {
bgImage: props.bgImage //so here I set the backroundImage with logo1, because I want to logo1 to be on the start of application, but when I change to logo2 I want to have that logo2 even when I refresh page ( but when I do it, constructor of App is setting it to the logo1. So maybe, can I save that logo even when the App is reloading to get the latest logo ?
};
}
ChangeToLightMode = e => {
this.setState({
bgImage: `url(${logo1})`
});
};
ChangeToDarkMode = e => {
this.setState({
bgImage: `url(${logo2})`
});
};
render() {
return (
<div
style={{
display: "flex",
minHeight: "100vh",
flexDirection: "column",
backgroundImage: this.state.bgImage,
height: "100%",
width: "100%"
}}
>
<NavBar
ChangeToDarkMode={this.ChangeToDarkMode}
ChangeToLightMode={this.ChangeToLightMode}
/>
);
}
}
export default App;
\\NavBar.js
import React, { Component } from "react";
class NavBar extends Component {
render() {
return (
<div>
<Menu fixed="top" inverted>
<Menu.Menu position="right">
<Menu.Item onClick={this.props.ChangeToDarkMode}>
DarkMode
</Menu.Item>
<Menu.Item onClick={this.props.ChangeToLightMode}>
LightMode
</Menu.Item>
</Menu.Menu>
</Menu>
</div>
);
}
}
So I implemented a way that I can change background photo but when I click for example logo in my application and the constructor of App is called it is setting my bgImage to the first photo even when I had second photo and I know it. But I want only the first photo to be set in constructor in the start of the application, after it I want to have the photo according to which method I use. So should I store somewhere the bgImage state and do something with it in App constructor ?
If the default value for bgImage needs to be determined before App is rendered, then usually you would do this by passing a prop into the component e.g.
<App bgImage={`url(${logo1})`} />
Then in the constructor, you can set this as the default state
class App extends Component {
constructor(props) {
super(props);
this.state = {
bgImage: props.bgImage
};
}
}

Composition of react-emotion and external css (eg. bootstrap) classes

Is there a way to add external (eg. bootstrap) classes along with react-emotion styling?
import React, { Component } from 'react';
import { css } from 'react-emotion';
const MyStyle = css`
STYLE
`
export default class MyComponent extends Component {
render() {
return (<button className={css`${MyStyle}` /* add in some way `btn btn-default` */ }>Text</button>);
}
}
Thanks!
Yes you can. Below is the link where i had made a small example, the font colour is coming from react-emotion and background colour is coming from bootstrap.
import React, { Component } from 'react';
import { render } from 'react-dom';
import 'bootstrap/dist/css/bootstrap.min.css';
import styled, { css } from 'react-emotion'
const myStyle = css`
color: rebeccapurple;
`;
class App extends Component {
constructor() {
super();
this.state = {
name: 'React'
};
}
render() {
return (
<div className={myStyle + ' bg-primary'}>Hello World</div>
);
}
}
render(<App />, document.getElementById('root'));

Resources