Created
January 20, 2019 11:19
-
-
Save MilanRgm/47c68ad9c2a5a295f32ffaab21f2bb26 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from "react"; | |
import { connect } from 'react-redux'; | |
import { fabric } from "fabric"; | |
import imagesReducer from "reducers/images"; | |
import Filter from "components/Home/Filter"; | |
import { Wrapper, CanvasWrapper, Row, Column } from "./styled"; | |
// Below there is functional component approach | |
// This class based and index.js of images should use connect to make image selection work but not below commented code and | |
// images/index.js commented work. | |
class ImageBoard extends React.Component { | |
constructor() { | |
super(); | |
this.state = { | |
canvas: undefined, | |
selected: undefined | |
}; | |
} | |
handleDeleteKey(event) { | |
if (event.keyCode === 46 || event.keyCode === 8) { | |
event.preventDefault(); | |
if (this.state.selected !== undefined) { | |
this.state.canvas.remove(this.state.selected); | |
this.setState({ selected: undefined }); | |
} | |
} | |
} | |
componentDidMount() { | |
const canvas = new fabric.Canvas("canvas"); | |
document.addEventListener( | |
"keydown", | |
this.handleDeleteKey.bind(this), | |
false | |
); | |
canvas.on("object:selected", e => this.setState({ selected: e.target })); | |
canvas.on("selection:cleared", e => this.setState({ selected: undefined })); | |
this.setState({ canvas: canvas }); | |
this.setCanvasBackground(this.props.images, canvas); | |
} | |
componentDidUpdate(prevProps) { | |
if ( | |
prevProps.images !== | |
this.props.images | |
) { | |
this.setCanvasBackground( | |
this.props.images, | |
this.state.canvas | |
); | |
} | |
// this.setCanvasBackground( | |
// this.props.images, | |
// this.state.canvas | |
// ); | |
} | |
setCanvasBackground(image, canvas) { | |
canvas.setBackgroundImage(image, e => { | |
let iw = canvas.backgroundImage.width, | |
ih = canvas.backgroundImage.height, | |
cw = canvas.getWidth(), | |
ch = canvas.getHeight(); | |
let iar = iw / ih, | |
car = cw / ch; | |
let nw = cw, | |
nh = ch; | |
if (iar > car) { | |
nh = ch; | |
nw = nh * iar; | |
} else if (iar < car) { | |
nw = cw; | |
nh = cw / iar; | |
} | |
canvas.backgroundImage.width = nw; | |
canvas.backgroundImage.height = nh; | |
canvas.renderAll(); | |
}); | |
} | |
addText(val) { | |
if (val || val.checked) { | |
console.log("val", val); | |
let text = new fabric.IText("Double click me to change the text!", { | |
fontSize: 28, | |
fontWeight: 600, | |
left: 100, | |
top: 100, | |
fill: "black", | |
width: 20, | |
height: 20 | |
}); | |
this.state.canvas.add(text); | |
} else { | |
console.log('active object', this.state.selected) | |
this.state.canvas.on("text:editing:entered", () => console.log('hello')); | |
} | |
} | |
addSubtitle(val) { | |
if (val || val.checked) { | |
const text = new fabric.IText("subtitle", { | |
fontSize: 24, | |
fontWeight: 400, | |
left: 100, | |
top: 200, | |
fill: "white", | |
width: 20, | |
height: 20 | |
}); | |
this.state.canvas.add(text); | |
} | |
} | |
opacityChange(val) { | |
this.state.canvas.backgroundImage.setOpacity(val / 100); | |
this.state.canvas.renderAll(); | |
} | |
render() { | |
return ( | |
<Wrapper> | |
<Row> | |
<Column width={10}> | |
<CanvasWrapper> | |
<canvas | |
id="canvas" | |
ref={el => (this.canvasEl = el)} | |
width={500} | |
height={400} | |
className="z-depth-1" | |
/> | |
</CanvasWrapper> | |
</Column> | |
<Column width={6}> | |
<Filter | |
addText={this.addText.bind(this)} | |
addSubtitle={this.addSubtitle.bind(this)} | |
opacityChange={this.opacityChange.bind(this)} | |
applyTextFilter={this.applyTextFilter.bind(this)} | |
applyColor={this.applyColor.bind(this)} | |
applyBlur={this.applyBlur.bind(this)} | |
/> | |
</Column> | |
</Row> | |
</Wrapper> | |
); | |
} | |
} | |
const mapStateToProps = state => { | |
console.log('state changed', state) | |
return { | |
images: state.images.selectedImage | |
}; | |
}; | |
export default connect(mapStateToProps)(ImageBoard); | |
// const ImageBoard = (props) => { | |
// let canvasEl = React.useRef(null); | |
// const [selected, setSelected] = React.useState(null) | |
// const [canvasState, setCanvas] = React.useState(null) | |
// const [state, _] = React.useReducer(imagesReducer, {selectedImage: require('assets/images/image1.jpg')}) | |
// const setCanvasBackground = (image, canvas) => { | |
// if (image) { | |
// canvas.setBackgroundImage(image, e => { | |
// let iw = canvas.backgroundImage.width, | |
// ih = canvas.backgroundImage.height, | |
// cw = canvas.getWidth(), | |
// ch = canvas.getHeight(); | |
// let iar = iw / ih, | |
// car = cw / ch; | |
// let nw = cw, | |
// nh = ch; | |
// if (iar > car) { | |
// nh = ch; | |
// nw = nh * iar; | |
// } else if (iar < car) { | |
// nw = cw; | |
// nh = cw / iar; | |
// } | |
// canvas.backgroundImage.width = nw; | |
// canvas.backgroundImage.height = nh; | |
// canvas.renderAll(); | |
// }); | |
// } | |
// } | |
// const handleDeleteKey = event => { | |
// if (event.keyCode === 46 || event.keyCode === 8) { | |
// event.preventDefault(); | |
// console.log('canvasState', canvasState); // null i get | |
// if (selected !== undefined) { | |
// canvasState.remove(selected); | |
// setSelected(undefined); | |
// } | |
// } | |
// } | |
// React.useEffect(() => { | |
// // runs once on mount | |
// const canvasRef = new fabric.Canvas("canvas"); | |
// document.addEventListener( | |
// "keydown", | |
// handleDeleteKey, | |
// false | |
// ); | |
// canvasRef.on("object:selected", e => setSelected(e.target)); | |
// canvasRef.on("selection:cleared", e => setSelected(undefined)); | |
// setCanvas(canvasRef); | |
// setCanvasBackground(state.selectedImage, canvasRef); | |
// return () => { | |
// document.removeEventListener("keydown", handleDeleteKey, false); | |
// } | |
// }, []) | |
// React.useEffect(() => { | |
// // runs every time new getSelectedImage is received, including initial render | |
// setCanvasBackground(props.getSelectedImage, canvasState); | |
// }, [props.getSelectedImage]) | |
// const addText = val => { | |
// if (val || val.checked) { | |
// let text = new fabric.IText("Double click me to change the text!", { | |
// fontSize: 28, | |
// fontWeight: 600, | |
// left: 100, | |
// top: 100, | |
// fill: "black", | |
// width: 20, | |
// height: 20 | |
// }); | |
// canvasState.add(text); | |
// } | |
// } | |
// const opacityChange =val => { | |
// canvasState.backgroundImage.setOpacity(val / 100); | |
// canvasState.renderAll(); | |
// } | |
// const applyColor = e => { | |
// selected.setColor(e.hex); | |
// // canvasState is here null | |
// canvasState.renderAll(); | |
// } | |
// console.log('props', props) | |
// return ( | |
// <Wrapper> | |
// <Row> | |
// <Column width={80}> | |
// <CanvasWrapper> | |
// <canvas | |
// id="canvas" | |
// ref={canvasEl} | |
// width={500} | |
// height={400} | |
// className="z-depth-1" | |
// /> | |
// </CanvasWrapper> | |
// </Column> | |
// <Column width={20}> | |
// <Filter | |
// addText={addText} | |
// addSubtitle={addSubtitle} | |
// opacityChange={opacityChange} | |
// applyTextFilter={applyTextFilter} | |
// applyColor={applyColor} | |
// applyBlur={applyBlur} | |
// /> | |
// </Column> | |
// </Row> | |
// </Wrapper> | |
// ); | |
// } | |
// export default ImageBoard; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const initialState = { | |
selectedImage: require('assets/images/image1.jpg') | |
}; | |
export default function getSelectedImage(state = initialState, action) { | |
switch (action.type) { | |
case SELECT_IMAGE: | |
return { ...state, selectedImage: action.payload.image}; | |
default: | |
return state; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// images/index.js | |
import React from "react"; | |
import { connect } from 'react-redux'; | |
import styled from "styled-components"; | |
import { SELECT_IMAGE } from "actions/types"; | |
import { selectImage } from "actions"; | |
import imagesReducer from "reducers/images"; | |
import images from "./list"; | |
const Wrapper = styled.div` | |
flex: 1; | |
`; | |
const Image = styled.img` | |
display: flex; | |
flex: 1; | |
width: 150px; | |
max-width: 100%; | |
margin: 20px 0; | |
cursor: pointer; | |
`; | |
// This does not works. | |
// const Images = props => { | |
// const [_, dispatch] = React.useReducer(imagesReducer, []); | |
// return ( | |
// <React.Fragment> | |
// <Wrapper> | |
// {images.map(image => ( | |
// <Image | |
// key={image.id} | |
// src={image.image} | |
// alt={image.category} | |
// onClick={() => dispatch({ type: SELECT_IMAGE, payload: image })} | |
// /> | |
// ))} | |
// </Wrapper> | |
// </React.Fragment> | |
// ); | |
// }; | |
// export default Images; | |
const Images = props => { | |
// const [_, dispatch] = React.useReducer(imagesReducer, []); | |
return ( | |
<React.Fragment> | |
<Wrapper> | |
{images.map(image => ( | |
<Image | |
key={image.id} | |
src={image.image} | |
alt={image.category} | |
onClick={() => selectImage(image)} | |
/> | |
))} | |
</Wrapper> | |
</React.Fragment> | |
); | |
}; | |
export default connect(null, dispatch => ({ selectImage: image => dispatch(selectImage(image))}))(Images); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment