Skip to content

Instantly share code, notes, and snippets.

@MilanRgm
Created January 20, 2019 11:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MilanRgm/47c68ad9c2a5a295f32ffaab21f2bb26 to your computer and use it in GitHub Desktop.
Save MilanRgm/47c68ad9c2a5a295f32ffaab21f2bb26 to your computer and use it in GitHub Desktop.
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;
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;
}
}
// 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