Related
I've got a bunch of images flashing on a preloader screen of a Next.js application with GSAP like a collage and I'm using a ${Math.floor((Math.random() - 0.5)* 500)}px to randomly splatter them on the screen. The issue I'm have is that although it works very well, 'random' doesn't mean it covers the entire screen and it often leave gaps in the view. Is there a way of still assigning random positioning but also covering the entire the viewport?
import { useEffect, useRef, useState, useContext } from 'react'
import { gsap, Linear } from 'gsap'
import imagesLoaded from 'imagesloaded'
import styles from '../../styles/Preloader.module.scss'
import ScrollContext from "../Context"
const images = [
{
src: "/preloader/img.png",
landscape: true,
alt: "Code",
styles: {
position: "relative",
top: `${Math.floor((Math.random() - 0.5)* 500)}px`,
left: `${Math.floor((Math.random() - 0.6)* 900)}px`
}
},
{
src: "/preloader/img.png",
landscape: true,
alt: "Styleguide",
styles: {
position: "relative",
top: `${Math.floor((Math.random() - 0.5)* 500)}px`,
left: `${Math.floor((Math.random() - 0.6)* 900)}px`
}
},
{
src: "/preloader/img.png",
landscape: true,
alt: "Office",
styles: {
position: "relative",
top: `${Math.floor((Math.random() - 0.5)* 500)}px`,
left: `${Math.floor((Math.random() - 0.6)* 900)}px`
}
},
{
src: "/preloader/img.png",
landscape: true,
alt: "Device screens",
styles: {
position: "relative",
top: `${Math.floor((Math.random() - 0.5)* 500)}px`,
left: `${Math.floor((Math.random() - 0.6)* 900)}px`
}
},
{
src: "/preloader/img.png",
landscape: true,
alt: "Zoom meetings",
styles: {
position: "relative",
top: `${Math.floor((Math.random() - 0.5)* 500)}px`,
left: `${Math.floor((Math.random() - 0.6)* 900)}px`
}
},
]
const Preloader = () => {
let [progress, setProgress] = useState(0);
const scrollingStatus = useContext(ScrollContext);
const {scrolable, setScrollable} = scrollingStatus;
const indicatorRef = useRef(null);
const welcomeRef = useRef(null);
const imgRef = useRef(null);
const TLImages = gsap.timeline({ paused: true });
const [rendered, setRendered] = useState(false);
useEffect(() => {
setRendered(true)
}, [])
useEffect(() => {
if (typeof document !== "undefined") {
document.body.style.overflowY = scrolable ? "auto" : "hidden";
}
console.log(scrolable)
}, [scrolable]);
useEffect(() => {
if (welcomeRef.current) {
gsap.fromTo(welcomeRef.current, { alpha: 0, duration: 40 }, { alpha: 1 });
setScrollable(false);
}
TLImages.to(".imagesWrapper", { alpha: 1, ease: Linear.easeNone });
TLImages.add(
gsap.fromTo(
".images",
{ visibility: "hidden", stagger: 0.5 },
{ visibility: "visible", stagger: 0.5 }
)
);
TLImages.add(
gsap.to(".preloader", {
alpha: 0,
onComplete: function () {
setScrollable(true); //scroll for the rest of the home page
},
})
);
}, []);
useEffect(() => {
setTimeout(() => {
let loadedCount = 0;
let loadingProgress = 0;
var imgLoad = imagesLoaded("#__next");
if (imgLoad.images.length === 0) {
loadingProgress = 100;
doneLoading();
}
imgLoad.on("progress", function (instance) {
var imagesToLoad = instance.images.length;
loadProgress(imagesToLoad);
});
function loadProgress(imagesToLoad) {
loadedCount++;
loadingProgress = (loadedCount / imagesToLoad) * 100;
setProgress(loadingProgress);
if (loadingProgress === 100) {
doneLoading();
}
}
function doneLoading() {
gsap.to(indicatorRef.current, {
width: "100%",
onComplete: function () {
gsap.to(welcomeRef.current, {
alpha: 0,
duration: 0.4,
onComplete: function () {
TLImages.play();
},
});
},
});
}
}, 1000);
}, []);
return (
<div className={`${styles.preloader_container} preloader`} style={scrolable ? { zIndex: "-1" } : {zIndex: "99999"}}>
<div className={styles.preloader_wrapper}>
<div className={styles.preloader_inner_wrapper}>
<div className={styles.future} ref={welcomeRef}>
<p className={styles.mid_uppercase}>Do you want to see what the future of digital services looks like?</p>
<div className={styles.progress_bar}>
<div className={styles.progress} ref={indicatorRef}></div>
</div>
</div>
<div className={`${styles.images} imagesWrapper`}>
<div className={styles.imagesInner}>
{images.map((item, idx) => (
<figure
ref={imgRef}
className={`${styles.figure} ${item.landscape ? styles.landscape : styles.portrait} images`}
key={`img-${idx}`}
>
<img src={item.src} alt={item.alt} style={rendered ? item.styles : {}} className={styles.image} />
</figure>
))}
</div>
</div>
</div>
</div>
</div>
);
};
export default Preloader
Goal: create an OptionFan button that when pressed, rotates on its Z axis, and FanItems release from behind the main button and travel along their own respective vectors.
OptionFan.js:
import React, { useState, useEffect } from 'react';
import { Image, View, Animated, StyleSheet, TouchableOpacity, Dimensions } from 'react-native';
import EStyleSheet from 'react-native-extended-stylesheet';
import FanItem from './FanItem';
const { height, width } = Dimensions.get('window');
export default class OptionFan extends React.Component {
constructor (props) {
super(props);
this.state = {
animatedRotate: new Animated.Value(0),
expanded: false
};
}
handlePress = () => {
if (this.state.expanded) {
// button is opened
Animated.spring(this.state.animatedRotate, {
toValue: 0
}).start();
this.refs.option.collapse();
this.setState({ expanded: !this.state.expanded });
} else {
// button is collapsed
Animated.spring(this.state.animatedRotate, {
toValue: 1
}).start();
this.refs.option.expand();
this.setState({ expanded: !this.state.expanded });
}
};
render () {
const animatedRotation = this.state.animatedRotate.interpolate({
inputRange: [ 0, 0.5, 1 ],
outputRange: [ '0deg', '90deg', '180deg' ]
});
return (
<View>
<View style={{ position: 'absolute', left: 2, top: 2 }}>
{this.props.options.map((item, index) => (
<FanItem ref={'option'} icon={item.icon} onPress={item.onPress} index={index} />
))}
</View>
<TouchableOpacity style={styles.container} onPress={() => this.handlePress()}>
<Animated.Image
resizeMode={'contain'}
source={require('./src/assets/img/arrow-up.png')}
style={{ transform: [ { rotateZ: animatedRotation } ], ...styles.icon }}
/>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
justifyContent: 'center',
alignItems: 'center',
borderRadius: 30,
backgroundColor: '#E06363',
elevation: 15,
shadowOffset: {
height: 3,
width: 3
},
shadowColor: '#333',
shadowOpacity: 0.5,
shadowRadius: 5,
height: width * 0.155,
width: width * 0.155
},
icon: {
height: width * 0.06,
width: width * 0.06
},
optContainer: {
justifyContent: 'center',
alignItems: 'center',
borderRadius: 30,
backgroundColor: '#219F75',
elevation: 5,
shadowOffset: {
height: 3,
width: 3
},
shadowColor: '#333',
shadowOpacity: 0.5,
shadowRadius: 5,
height: width * 0.13,
width: width * 0.13,
position: 'absolute'
}
});
FanItem.js:
import React, { useState } from 'react';
import { Image, Animated, StyleSheet, TouchableOpacity, Dimensions } from 'react-native';
import EStyleSheet from 'react-native-extended-stylesheet';
const { width } = Dimensions.get('window');
export default class FanItem extends React.Component {
constructor (props) {
super(props);
this.state = {
animatedOffset: new Animated.ValueXY(0),
animatedOpacity: new Animated.Value(0)
};
}
expand () {
let offset = { x: 0, y: 0 };
switch (this.props.index) {
case 0:
offset = { x: -50, y: 20 };
break;
case 1:
offset = { x: -20, y: 50 };
break;
case 2:
offset = { x: 20, y: 50 };
break;
case 3:
offset = { x: 75, y: -20 };
break;
}
Animated.parallel([
Animated.spring(this.state.animatedOffset, { toValue: offset }),
Animated.timing(this.state.animatedOpacity, { toValue: 1, duration: 600 })
]).start();
}
collapse () {
Animated.parallel([
Animated.spring(this.state.animatedOffset, { toValue: 0 }),
Animated.timing(this.state.animatedOpacity, { toValue: 0, duration: 600 })
]).start();
}
render () {
return (
<Animated.View
style={
(this.props.style,
{
left: this.state.animatedOffset.x,
top: this.state.animatedOffset.y,
opacity: this.state.animatedOpacity
})
}
>
<TouchableOpacity style={styles.container} onPress={this.props.onPress}>
<Image resizeMode={'contain'} source={this.props.icon} style={styles.icon} />
</TouchableOpacity>
</Animated.View>
);
}
}
const styles = StyleSheet.create({
container: {
justifyContent: 'center',
alignItems: 'center',
borderRadius: 30,
backgroundColor: '#219F75',
elevation: 5,
shadowOffset: {
height: 3,
width: 3
},
shadowColor: '#333',
shadowOpacity: 0.5,
shadowRadius: 5,
height: width * 0.13,
width: width * 0.13,
position: 'absolute'
},
icon: {
height: width * 0.08,
width: width * 0.08
}
});
Implementation:
import React from 'react';
import { StyleSheet, View, Dimensions } from 'react-native';
import Component from './Component';
const { height, width } = Dimensions.get('window');
const testArr = [
{
icon: require('./src/assets/img/chat.png'),
onPress: () => alert('start chat')
},
{
icon: require('./src/assets/img/white_video.png'),
onPress: () => alert('video chat')
},
{
icon: require('./src/assets/img/white_voice.png'),
onPress: () => alert('voice chat')
},
{
icon: require('./src/assets/img/camera.png'),
onPress: () => alert('request selfie')
}
];
const App = () => {
return (
<View style={styles.screen}>
<Component options={testArr} />
</View>
);
};
const styles = StyleSheet.create({
screen: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#E6E6E6'
}
});
export default App;
Problem: The issue is, only the last FanItem item runs its animation. (opacity, and vector translation). before implementing the opacity animation I could tell the first three FanItems did in fact render behind the main button, because I could see them when pressing the main button, as the opacity temporarily changes for the duration of the button click.
My question is 1) why are the first three mapped items not animating? and 2) how to resolve this?
You are storing ref of FanItem in option. but, ref gets overridden in each iteration of map. so, at the end it only stores ref of last FanItem in option. So, first declare one array in constructor to store ref of each FanItem:
constructor(props) {
super(props);
// your other code
this.refOptions = [];
}
Store ref of each FanItem separately like this:
{this.props.options.map((item, index) => (
<FanItem ref={(ref) => this.refOptions[index] = ref} icon={item.icon} onPress={item.onPress} index={index} />
))}
and then to animate each FanItem:
for(var i = 0; i < this.refOptions.length; i++){
this.refOptions[i].expand(); //call 'expand' or 'collapse' as required
}
This is expo snack link for your reference:
https://snack.expo.io/BygobuL3JL
I'm working on separating code from index.tsx into two different files viz: firstTab.tsx and secondTab.tsx. I haven't started working on secondTab.tsx yet.
I separated first tab related code into firstTab.tsx as shown in the following code editor: The full functional code with both tabs working are in index.tsx is pasted below:
import React, { Component } from "react";
import { render } from "react-dom";
import "jqwidgets-scripts/jqwidgets/styles/jqx.base.css";
import JqxButton from "jqwidgets-scripts/jqwidgets-react-tsx/jqxbuttons";
import * as ReactDOM from "react-dom";
import JqxWindow from "jqwidgets-scripts/jqwidgets-react-tsx/jqxwindow";
import JqxInput from "jqwidgets-scripts/jqwidgets-react-tsx/jqxinput";
import JqxChart, {
IChartProps
} from "jqwidgets-scripts/jqwidgets-react-tsx/jqxchart";
import JqxGrid, {
IGridProps,
jqx
} from "jqwidgets-scripts/jqwidgets-react-tsx/jqxgrid";
import JqxTabs from "jqwidgets-scripts/jqwidgets-react-tsx/jqxtabs";
import JqxDropDownList, {
IDropDownListProps
} from "jqwidgets-scripts/jqwidgets-react-tsx/jqxdropdownlist";
import firstTab from './firstTab';
interface AppProps {}
interface AppState {
name: string;
}
interface IProps extends IGridProps {
dropdownlistSource: IDropDownListProps["source"];
}
class App extends Component<{}, IProps> {
private myTabs = React.createRef<JqxTabs>();
private gridElement = React.createRef<HTMLDivElement>();
private myGrid = React.createRef<JqxGrid>();
private gridElementTwo = React.createRef<HTMLDivElement>();
private myGrid2 = React.createRef<JqxGrid>();
constructor(props: {}) {
super(props);
this.state = {
dropdownlistSource: [
{ value: 0, label: "Affogato" },
{ value: 1, label: "Americano" },
{ value: 2, label: "Bicerin" },
{ value: 3, label: "Breve" }
]
};
}
public render() {
return (
<JqxTabs
ref={this.myTabs}
// #ts-ignore
width={400}
height={560}
initTabContent={this.initWidgets}
>
<ul>
<li style={{ marginLeft: 30 }}>
<div style={{ height: 20, marginTop: 5 }}>
<div
style={{
marginLeft: 4,
verticalAlign: "middle",
textAlign: "center",
float: "left"
}}
>
US Indexes
</div>
</div>
</li>
<li>
<div style={{ height: 20, marginTop: 5 }}>
<div
style={{
marginLeft: 4,
verticalAlign: "middle",
textAlign: "center",
float: "left"
}}
>
NASDAQ compared to S&P 500
</div>
</div>
</li>
</ul>
<div style={{ overflow: "hidden" }}>
<div id="jqxGrid" ref={this.gridElement} />
<div style={{ marginTop: 10, height: "15%" }} />
</div>
<div style={{ overflow: "hidden" }}>
<div id="jqxGrid2" ref={this.gridElementTwo} />
<div style={{ marginTop: 10, height: "15%" }} />
</div>
</JqxTabs>
);
}
private initGrid = () => {
const source = {
datafields: [{ name: "Date" }, { name: "S&P 500" }, { name: "NASDAQ" }],
datatype: "csv",
localdata: `1/2/2014,1831.98,4143.07
1/3/2014,1831.37,4131.91
1/6/2014,1826.77,4113.68
1/7/2014,1837.88,4153.18
1/8/2014,1837.49,4165.61
1/9/2014,1838.13,4156.19
2/6/2014,1773.43,4057.12
2/7/2014,1797.02,4125.86`
};
const dataAdapter = new jqx.dataAdapter(source, {
async: false,
loadError: (xhr: any, status: any, error: any) => {
console.log(xhr, status, error);
}
});
const columns: IGridProps["columns"] = [
{ cellsformat: "d", datafield: "Date", text: "Date", width: 250 },
{ datafield: "S&P 500", text: "S&P 500", width: 150 },
{ datafield: "NASDAQ", text: "NASDAQ" }
];
const grid = (
<JqxGrid
ref={this.myGrid}
width={"100%"}
height={400}
source={dataAdapter}
columns={columns}
/>
);
render(grid, this.gridElement.current!);
};
private initGrid2 = () => {
const source = {
datafields: [{ name: "Date" }, { name: "S&P 500" }, { name: "NASDAQ" }],
datatype: "csv",
localdata: `1/2/2014,1831.98,4143.07
1/3/2014,1831.37,4131.91
1/6/2014,1826.77,4113.68
1/7/2014,1837.88,4153.18
1/8/2014,1837.49,4165.61
1/9/2014,1838.13,4156.19
1/10/2014,1842.37,4174.67
2/7/2014,1797.02,4125.86`
};
const dataAdapter = new jqx.dataAdapter(source, {
async: false,
loadError: (xhr: any, status: any, error: any) => {
console.log(xhr, status, error);
}
});
const columns: IGridProps["columns"] = [
{ cellsformat: "d", datafield: "Date", text: "Date", width: 250 },
{ datafield: "S&P 500", text: "S&P 500", width: 150 },
{ datafield: "NASDAQ", text: "NASDAQ" }
];
const grid = (
<JqxGrid
ref={this.myGrid2}
width={"100%"}
height={400}
source={dataAdapter}
columns={columns}
/>
);
render(grid, this.gridElementTwo.current!);
};
private initWidgets = (tab: any) => {
switch (tab) {
case 0:
this.initGrid();
break;
case 1:
this.initGrid2();
break;
}
};
}
render(<App />, document.getElementById("root"));
Question:
Since I've already moved private initGrid = () => { inside a separate file firstTab.tsx, in index.tsx where should I put {firstTab.tsx} to make sure both tabs in index.tsx works fine? I mean, even if I comment out private initGrid = () => { function from index.tsx both tabs should work fine.
Thanks
If I would refactor this I would consider the next approach:
Create Parent component Table (probably some more appropriate name)
Create a component for US Indexes
Create a component for NASDAQ compared to S&P 500
Based on the active tab render the proper component.
You could also create a separate file that contains only exports with your data.
If you then import that into your files with the functions you can use that there, keeps it cleaner.
And if you pass that data as a prop / param to your initGrid() functions, you don't have to repeat that code, can reuse it.
I'm trying to navigate to another screen (Artist) by clicking on an element in a FlatList. This FlatList contains Artist instances, as set in the _renderListItem method. So far I've tried three different approaches (two of them commented out at the moment), but none of them seem to work:
Method 1: NavigationActions
Method 2: this.props.navigation.navigate
Method 3: Navigator.push
I managed to pass the params to the other screen, but unfortunately the navigation itself doesn't seem to work; I'm getting the expected values in my logs, but nothing happens and the app stays at LinksScreen (doesn't change screens).
LinksScreen.js
import React, { Component } from 'react';
import { PropTypes } from 'prop-types';
import Artist from './Artist';
import { createStackNavigator, withNavigation, NavigationActions } from 'react-navigation';
import {
ScrollView,
StyleSheet,
View,
Text,
Image,
FlatList,
ActivityIndicator,
TouchableOpacity,
TouchableHighlight,
} from 'react-native';
export default class LinksScreen extends React.Component {
constructor(props) {
super(props);
this._onAlertTypePressed = this._onAlertTypePressed.bind(this);
}
_onAlertTypePressed(typeId: string, typeName: string, imageUrl: string) {
console.log(typeId)
console.log(typeName)
console.log(imageUrl)
// NavigationActions
// NavigationActions.navigate({
// routeName: 'Artist',
// params: { itemId: typeId, itemName: typeName, itemImageUrl: imageUrl,},
// });
// NAVIGATE
this.props.navigation.navigate('HomeStack',{},
{
type: "Navigate",
routeName: "Artist",
params: {
itemId: typeId,
itemName: typeName,
itemImageUrl: imageUrl}
}
);
// PUSH
// this.props.navigator.push({
// screen: 'Artist',
// title: 'Artist',
// passProps: {
// itemId: typeId,
// itemName: typeName,
// itemImageUrl: imageUrl,
// },
// });
}
_renderListItem = ({item}) => (
<Artist
itemId={item.id}
itemName={item.title.rendered}
itemImageUrl={
item.better_featured_image
? item.better_featured_image.source_url
: 'http://54.168.73.151/wp-content/uploads/2018/04/brand-logo.jpg'
}
onPressItem={this._onAlertTypePressed}
/>
);
static navigationOptions = {
title: 'Links',
};
state = {
data: [],
isLoading: true,
isError: false,
};
// static propTypes = {
// navigation: PropTypes.shape({
// navigate: PropTypes.func.isRequired,
// }).isRequired,
// };
componentWillMount() {
fetch('http://54.168.73.151/wp-json/wp/v2/pages?parent=38&per_page=100')
.then(response => response.json())
.then(responseJson => {
responseJson.sort(
(a, b) => (a.title.rendered < b.title.rendered ? -1 : 1)
);
this.setState({
data: responseJson,
isLoading: false,
isError: false,
});
})
.catch(error => {
this.setState({
isLoading: false,
isError: true,
});
console.error(error);
});
}
// Not used anymore.
renderRow = item => (
<View style={styles.grid}>
<Image
style={styles.thumb}
source={{
uri: item.better_featured_image
? item.better_featured_image.source_url
: 'http://54.168.73.151/wp-content/uploads/2018/04/brand-logo.jpg',
}}
/>
<Text style={styles.title}>{item.title.rendered}</Text>
</View>
);
getKey = item => String(item.id);
renderComponent() {
if (this.state.isLoading) {
return <ActivityIndicator />;
} else if (this.state.isError) {
return <Text>Error loading data</Text>;
} else {
return (
<FlatList
numColumns={3}
contentContainerStyle={styles.elementsContainer}
data={this.state.data}
renderItem={this._renderListItem}
keyExtractor={this.getKey}
/>
);
}
}
render() {
return (
<View style={styles.container}>
<Text
style={{
fontSize: 20,
color: '#FFFFFF',
marginLeft: 4,
marginTop: 10,
}}>
RESIDENTS
</Text>
{this.renderComponent()}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#000000',
},
elementsContainer: {
backgroundColor: '#000000',
},
grid: {
marginTop: 15,
marginBottom: 15,
marginLeft: 5,
height: 125,
width: 115,
borderBottomWidth: 1,
borderBottomColor: '#191970',
},
title: {
color: '#FFFFFF',
textAlign: 'left',
fontSize: 12,
},
thumb: {
height: 110,
width: 110,
resizeMode: 'cover',
},
});
Artist.js
The console.log in the beginning of the _onPress() method seem to be working (the expected params have the correct values here), but I'm unable to navigate to this screen.
import React, { Component } from 'react';
import { createStackNavigator } from 'react-navigation';
import {
ScrollView,
StyleSheet,
View,
Text,
TouchableOpacity,
Image,
} from 'react-native';
class Artist extends React.PureComponent {
_onPress = () => {
// console.log(this.props)
const itemId = this.props.itemId
const itemName = this.props.itemName
const itemImageUrl = this.props.itemImageUrl
console.log(itemId)
console.log(itemName)
console.log(itemImageUrl)
// FOR PUSH
// this.props.onPressItem(
// this.props.itemid,
// this.props.itemName,
// this.props.itemImageUrl,
// );
// };
}
static navigationOptions = {
title: 'Artist',
};
render() {
return (
<TouchableOpacity
{...this.props}
style={styles.grid}
onPress={this._onPress}>
<Image
style={styles.image}
source={{uri: this.props.itemImageUrl}}
/>
<Text style={styles.title}>{this.props.itemName}</Text>
</TouchableOpacity>
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor: '#000000',
},
grid: {
marginTop: 15,
marginBottom: 15,
marginLeft: 5,
height: 125,
width: 115,
borderBottomWidth: 1,
borderBottomColor: '#191970',
},
title: {
color: '#FFFFFF',
textAlign: 'left',
fontSize: 12,
},
image: {
height: 110,
width: 110,
resizeMode: 'cover',
},
});
export default Artist;
MainTabNavigator.js
Perhaps there is something wrong regarding the routing, so here is how it's done in my case.
import React from 'react';
import { Platform, AppRegistry } from 'react-native';
import { createStackNavigator, createBottomTabNavigator } from 'react-navigation';
import TabBarIcon from '../components/TabBarIcon';
import HomeScreen from '../screens/HomeScreen';
import LinksScreen from '../screens/LinksScreen';
import SettingsScreen from '../screens/SettingsScreen';
import Artist from '../screens/Artist';
const HomeStack = createStackNavigator({
Home: {
screen: HomeScreen,
},
Links: {
screen: LinksScreen,
},
Artist: {
screen: Artist,
},
});
AppRegistry.registerComponent('ParamsRepo', () => HomeStack);
export default HomeStack;
Try simplyfying your code like this:
this.props.navigation.navigate('Artist',
{
itemId: typeId,
itemName: typeName,
itemImageUrl: imageUrl
}
});
I have been playing around with react-photo-gallery.
Have installed it together with lightbox and it works just fine when I am displaying online photos.
When I try to display imported ones it's not displaying photo but just frame of it.
import React from 'react';
import Gallery from 'react-photo-gallery';
import Lightbox from 'react-images';
import thumbsup from "../../assets/images/thumbsup.png";
const photos = [
{ src: {thumbsup}, width: 4, height: 3 },
{ src: 'https://source.unsplash.com/Dm-qxdynoEc/800x799', width: 1, height: 1 },
{ src: 'https://source.unsplash.com/qDkso9nvCg0/600x799', width: 3, height: 4 }
];
export default class Sample extends React.Component {
constructor() {
super();
this.state = { currentImage: 0 };
this.closeLightbox = this.closeLightbox.bind(this);
this.openLightbox = this.openLightbox.bind(this);
this.gotoNext = this.gotoNext.bind(this);
this.gotoPrevious = this.gotoPrevious.bind(this);
}
openLightbox(event, obj) {
this.setState({
currentImage: obj.index,
lightboxIsOpen: true,
});
}
closeLightbox() {
this.setState({
currentImage: 0,
lightboxIsOpen: false,
});
}
gotoPrevious() {
this.setState({
currentImage: this.state.currentImage - 1,
});
}
gotoNext() {
this.setState({
currentImage: this.state.currentImage + 1,
});
}
render() {
return (
<div>
<Gallery photos={photos} onClick={this.openLightbox} />
<Lightbox images={photos}
onClose={this.closeLightbox}
onClickPrev={this.gotoPrevious}
onClickNext={this.gotoNext}
currentImage={this.state.currentImage}
isOpen={this.state.lightboxIsOpen}
/>
</div>
)
}
}
I am trying to display it like I did in rest of my components.
import thumbsup from "../../assets/images/thumbsup.png";
{ src: {thumbsup}, width: 4, height: 3 }
Removing the curly braces around {thumbsub} should fix your problem.
const photos = [
{ src: thumbsup, width: 4, height: 3 },
{ src: 'https://source.unsplash.com/Dm-qxdynoEc/800x799', width: 1, height: 1 },
{ src: 'https://source.unsplash.com/qDkso9nvCg0/600x799', width: 3, height: 4 }
];
Like you have it now, the photo object would look like this:
{
src: {
thumbsup: "/..../....png"
},
width: 4,
height: 3
}