Open tmddk2709 opened 5 years ago
import React from 'react'; import { connect } from 'react-redux' import {fabric} from 'fabric'; import {CirclePicker} from 'react-color'; //import ThreeScene from './ThreeScene'; import FabricCanvas from './FabricCanvas'; //import TemplateList from './TemplateList' //import TemplateListItem from './TemplateListItem' //import {back_sleeve, back_banding, back_body, back_stripe, front_sleeve, front_body, front_button, front_stripe, front_banding} from './images/templates/templatelist'; import MyGroupList from '../GroupPage/MyGroupList'; //import ImageUploader from 'react-images-upload'; import { toSaveDesign, toPostDesign, toNewDesign } from '../../actions/index.js'; //import ThreeScene from './ThreeScene'; //the templates are imported as images and passed as porps to the TemplateList components. //if the user chooses any of the properties, the state gets updated in the DesignPage component //it gets passed onto FabricCanvas as prop //FabricCanvas uses lifecycle method ComponentWillReceiveProps() to update the canvas //about saveToCanvas: use a method from fabric named TODataUrl() // export default class DesignPage extends React.Component { class DesignPage extends React.Component { constructor(props){ console.log("DesignPage - constructor") super(props); this.state = { design : { body: this.props.now_design.detail_body, sleeve: this.props.now_design.detail_sleeve, banding: this.props.now_design.detail_banding, stripe: this.props.now_design.detail_stripes, button: this.props.now_design.detail_buttons }, text : { frontchest: { textvalue: "S", fontFamily: "arial", fill: "#fe0e0e", fontStyle: "bold", fontSize: 50, left: 100, top: 100, }, rightarm: { textvalue: "19", fontFamily: "arial", fill: "#e91e63", fontStyle: "bold", fontSize: 50 }, upperback: { textvalue: "SEOUL NAT'L", fontFamily: "arial", fill: "#e91e63", fontStyle: "bold", fontSize: 25 }, middleback: { textvalue: "UNIVERSITY", fontFamily: "arial", fill: "#e91e63", fontStyle: "bold", fontSize: 20 }, lowerback: { textvalue: "Department of\nComputer Science", fontFamily: "arial", fill: "#e91e63", fontStyle: "italic", fontSize: 15 } // frontchest: this.props.now_design.front_chest, // rightarm: this.props.now_design.right_arm, // upperback: this.props.now_design.upper_back, // middleback: this.props.now_design.middle_back, // lowerback: this.props.now_design.lower_back // { // textvalue: text.text_value, // fontFamily: text.font_family, // fill: text.font_fill, // fontStyle: text.font_style, // fontSize: text.font_size // }, }, // activeBackProperty : null, // activeFrontProperty : null, clickedWhat: null, textClickedWhat: "frontchest" }; this.onDrop = this.onDrop.bind(this); this.handleDesignChange = this.handleDesignChange.bind(this); this.handleTextChange = this.handleTextChange.bind(this); this.handleDesignChangeComplete = this.handleDesignChangeComplete.bind(this); this.handleTextChangeComplete = this.handleTextChangeComplete.bind(this); this.handleTextColorChangeComplete = this.handleTextColorChangeComplete.bind(this); this.clickedButton = this.clickedButton.bind(this); console.log("design page state: ", this.state.design) //this.handleFontChangeComplete = this.handleFontChangeComplete.bind(this); } componentWillMount() { console.log("DesignPage - componentWillMount") this.body_color = ["#f29c9f", "#fff45c", "#80c269", "#00b7ee", "#aa89bd", "#910000", "#f39800", "#097c25", "#0075a9", "#601986", "#580b0b", "#cfcfcf", "#626262", "#001c58", "#232323"]; this.sleeve_color = ["#f29c9f", "#fff45c", "#80c269", "#00b7ee", "#aa89bd", "#910000", "#f39800", "#097c25", "#0075a9", "#601986", "#580b0b", "#fcfcfc", "#626262", "#001c58", "#232323"]; this.stripe_color = ["#f29c9f", "#fff45c", "#80c269", "#00b7ee", "#aa89bd", "#910000", "#f39800", "#097c25", "#0075a9", "#601986", "#580b0b", "#fcfcfc", "#cfcfcf", "#001c58", "#232323"]; this.banding_color = ["#f29c9f", "#fff45c", "#80c269", "#00b7ee", "#aa89bd", "#910000", "#f39800", "#097c25", "#0075a9", "#601986", "#580b0b", "#cfcfcf", "#626262", "#001c58", "#232323"]; this.button_color = ["#f29c9f", "#fff45c", "#80c269", "#00b7ee", "#aa89bd", "#910000", "#f39800", "#097c25", "#0075a9", "#601986", "#580b0b", "#cfcfcf", "#626262", "#001c58", "#232323"]; this.text_style_id = ["text_area", "text_font", "text_style", "text_size", "text_colour"] } handleDesignChangeComplete(color, event) { console.log("DesignPage - handleDesignChangeComplete") let design_element = document.getElementById("design_element").value; this.setState({design : ({...this.state.design, [design_element]: color.hex})}) // switch(design_element) { // case 'body': // console.log("body") // this.setState({design : ({...this.state.design, body: color.hex})}) // break; // case 'sleeve': // this.setState({design : ({...this.state.design, sleeve: color.hex})}) // break; // case 'banding': // this.setState({design : ({...this.state.design, banding: color.hex})}) // break; // case 'stripe': // this.setState({design : ({...this.state.design, stripe: color.hex})}) // break; // case 'button': // this.setState({design : ({...this.state.design, button: color.hex})}) // break; // default: // this.setState({design : ({...this.state.design})}); // break; // } } handleTextChangeComplete(e) { let text_element = document.getElementById("text_element").value; console.log("DesignPage - handleTextChangeComplete e.target: ", e.target, " text element: ", text_element) this.setState({text : ({...this.state.text, [text_element]: ({...this.state.text[text_element], [e.target.name]:e.target.value}) })}); console.log("this.state: ", this.state) //this.forceUpdate(); } handleTextColorChangeComplete(color) { let text_element = document.getElementById("text_element").value; console.log("DesignPage - handleTextColorChangeComplete") this.setState({text : ({...this.state.text, [text_element]: ({...this.state.text[text_element], fill: color.hex}) })}); } addText() { console.log("DesignPage - addText") let text = new fabric.IText(document.getElementById("text_area").value, { fontFamily: document.getElementById("text_font").value, fill: this.fontcolor, fontStyle: document.getElementById("text_style").value, fontSize: document.getElementById("text_size").value, zIndex: 10 }) console.log(text) } handleDesignChange(e){ console.log("DesignPage - handleDesignChange") let value = e.target.value; if (value == "body") { this.setState({clickedWhat: "body"}); } else if (value == "sleeve"){ this.setState({clickedWhat: "sleeve"}); } else if (value == "banding") { this.setState({clickedWhat: "banding"}); } else if (value == "stripe"){ this.setState({clickedWhat: "stripe"}); } else if (value == "button"){ this.setState({clickedWhat: "button"}); } else { this.setState({clickedWhat: this.state.clickedWhat}); } //this.forceUpdate(); } handleTextChange(e){ console.log("DesignPage - handleTextChange") let value = e.target.value; if (value == "frontchest") { this.setState({textClickedWhat: "frontchest"}); } else if (value == "rightarm"){ this.setState({textClickedWhat: "rightarm"}); } else if (value == "upperback") { this.setState({textClickedWhat: "upperback"}); } else if (value == "middleback"){ this.setState({textClickedWhat: "middleback"}); } else if (value == "lowerback"){ this.setState({textClickedWhat: "lowerback"}); } else { this.setState({textClickedWhat: this.state.textClickedWhat}); } //this.forceUpdate(); } onDrop = (e) => { console.log("hey"); e.preventDefault(); var preview = document.getElementById('img'); var file = document.getElementById('input').files[0]; var canvas = this.the_front_canvas; let reader = new FileReader(); reader.addEventListener("load", function() { preview.src = reader.result; var imgInstance = new fabric.Image(preview, { width: 899, height:959, the_type: "upload", zIndex: 12 }); console.log("imgInstance set"); imgInstance.set({ scaleY: 0.1, scaleX: 0.1, originX: "center", originY: "center" }); console.log("imgInstance scale"); },false); if (file) { reader.readAsDataURL(file); } this.the_front_canvas = canvas; } clickedButton = (e) => { this.forceUpdate(); } clickedInitButton = (e) => { this.setState({clickedWhat: "body"}); this.forceUpdate(); } render() { console.log("DesignPage - render") const clickedWhat = this.state.clickedWhat; let colorPicker; if (clickedWhat == "body") { colorPicker = <CirclePicker width = "220" id="design_colour" onChangeComplete={this.handleDesignChangeComplete} colors={this.body_color}/>; //this.forceUpdate(); } else if (clickedWhat == "sleeve") { colorPicker = <CirclePicker width = "220" id="design_colour" onChangeComplete={this.handleDesignChangeComplete} colors={this.sleeve_color}/>; //this.forceUpdate(); } else if (clickedWhat == "banding") { colorPicker = <CirclePicker width = "220" id="design_colour" onChangeComplete={this.handleDesignChangeComplete} colors={this.banding_color}/>; //this.forceUpdate(); } else if (clickedWhat == "stripe") { colorPicker = <CirclePicker width = "220" id="design_colour" onChangeComplete={this.handleDesignChangeComplete} colors={this.stripe_color}/>; //this.forceUpdate(); } else if (clickedWhat == "button") { colorPicker = <CirclePicker width = "220" id="design_colour" onChangeComplete={this.handleDesignChangeComplete} colors={this.button_color}/>; //this.forceUpdate(); } else { // colorPicker = <CirclePicker // width = "220" id="design_colour" onChangeComplete={this.handleDesignChangeComplete} colors={this.body_color}/>; colorPicker = <button onClick={(e) => this.clickedInitButton(e)}>DEFAULT</button> } return ( <div> <section className="wrap clear col3"> <div className="aside"> <h2 className="h_white">SELECT STYLE</h2> <div className="content"> {/*<!--======================================== Design section =========================================-->*/} <h1>Design</h1> <center><select id="design_element" onChange={(e)=>this.handleDesignChange(e)}> <option value = "body">body</option> <option value = "sleeve">sleeve</option> <option value = "banding">banding</option> <option value = "stripe">stripe</option> <option value = "button">button</option> </select></center> <br></br> {colorPicker} <br></br> <div className="Button-Field-Side"> <button onClick={(e) => this.clickedButton(e)}>ADD</button> </div> {/* <div class="design_tool"> */} {/*<!--======================================== Text section =========================================-->*/} <h1>Text</h1> <center><select id="text_element" onChange={(e)=>this.handleTextChange(e)}> <option value="frontchest">Front Chest</option> <option value="rightarm">Right Arm</option> <option value="upperback">Upper Back</option> <option value="middleback">Middle Back</option> <option value="lowerback">Lower Back</option> </select> {console.log("default: ", this.state.text[this.state.textClickedWhat].textvalue)} <textarea id="text_area" placeholder={this.state.text[this.state.textClickedWhat].textvalue} name="textvalue" onChange={(e)=>this.handleTextChangeComplete(e)}/> <p>Font</p> <select id="text_font" name="fontFamily" onChange={(e)=>this.handleTextChangeComplete(e)}> <option>arial</option> <option>tahoma</option> <option>times new roman</option> <option>anton</option> <option>Akronim</option> <option>Alex Brush</option> <option>Aguafina Script</option> </select> <p>Text style</p> <select id="text_style" name="fontStyle" onChange={(e)=>this.handleTextChangeComplete(e)}> <option>normal</option> <option>italic</option> <option>oblique</option> <option>bold</option> </select> <p>Text size</p> <input type="range" min="0" max="200" defaultValue="100" id="text_size" name="fontSize" onChange={(e)=>this.handleTextChangeComplete(e)}/> <p>Colour</p> <CirclePicker id="text_colour" name="fill" onChangeComplete={this.handleTextColorChangeComplete}/> </center> </div> <div> <button class="front_btn" type="button" onClick={() => this.addText()}>Enter</button> </div> {/*<!--======================================== Image Upload Modal =========================================-->*/} <h1>Logo</h1> <input type = "file" id = "input" onChange = {this.onDrop} /> <img src = "" id = "img" /> </div> {/* </div> */} <div className="main"> <h2 className="h_white">SAMPLE VIEW</h2> <div className="content"> {/*<!--======================================== front-back button section =========================================-->*/} {/*<ThreeScene/>*/} <FabricCanvas design = {this.state.design} text = {this.state.text} // activeFrontProperty = {this.state.activeFrontProperty} // activeBackProperty = {this.state.activeBackProperty} /> {/* {console.log("DesignPage - render - activeFrontProperty: ", this.state.activeFrontProperty)} {console.log("DesignPage - render - activeBackProperty: ", this.state.activeBackProperty)} */} {this.props.isLoggedIn ? (<div> <button className="new_btn" type="button" onClick={() => this.props.onNew()}>NEW</button> <button className="save_btn" type="button" onClick={() => this.props.onSave(this.props.now_design.id, this.state.design)}>SAVE</button> </div>) : <div> <button className="new_btn" type="button" onClick={() => this.props.onNew()}>NEW</button> </div> } </div> </div> <div className="aside"> <h2 className="h_black">MY GROUP</h2> <div className="content"> {this.props.isLoggedIn? <MyGroupList /> : <p>로그인을 해주세요</p>} </div> </div> </section> </div> ); } } const mapStateToProps = (state) => ({ isLoggedIn: state.authorization, now_design: state.now_design, my_groups: state.my_groups, }) const mapDispatchToProps = (dispatch) => ({ onNew: () => dispatch(toNewDesign()), onSave: (designid, design_detail) => dispatch(toSaveDesign(designid, design_detail)), onPost: (designid, groupid, design_detail) => dispatch(toPostDesign(designid, groupid, design_detail)), }) export default connect (mapStateToProps, mapDispatchToProps)(DesignPage)
import React from 'react'; import {fabric} from 'fabric'; //import './App.css'; class FabricCanvas extends React.Component{ constructor(props) { super(props); console.log("FabricCanvas - constructor - props: ", props) this.state = { pictures : [], front_property : null, back_property: null }; this.onDrop = this.onDrop.bind(this); this.designElementToImage = this.designElementToImage.bind(this); this.updateFrontCanvasforImage = this.updateFrontCanvasforImage.bind(this); this.updateBackCanvasforImage = this.updateBackCanvasforImage.bind(this); this.design_element = ["body", "sleeve", "stripe", "banding", "button"] this.text_element = ["frontchest", "rightarm", "upperback", "middleback", "lowerback"] } /*I do not know why but setting either of willupdate or didupdate works*/ componentWillUpdate(nextProps, nextState) { this.the_front_canvas.renderAll(); this.the_back_canvas.renderAll(); } // componentDidUpdate(nextProps, nextState) { // this.the_front_canvas.renderAll(); // this.the_back_canvas.renderAll(); // } componentWillMount() { } componentDidMount() { console.log("FabricCanvas - componentDidMount") this.the_front_canvas = new fabric.Canvas('front-canvas', { preserveObjectStacking: true, height:460, width:430, }); this.the_back_canvas = new fabric.Canvas('back-canvas', { preserveObjectStacking: true, height:460, width:430, }); this.the_front_canvas.add(this.designElementToImage(this.props.design.body, "front_body", 0)) this.the_back_canvas.add(this.designElementToImage(this.props.design.body, "back_body", 0)) this.the_front_canvas.add(this.designElementToImage(this.props.design.sleeve, "front_sleeve", 0)) this.the_back_canvas.add(this.designElementToImage(this.props.design.sleeve, "back_sleeve", 0)) this.the_front_canvas.add(this.designElementToImage(this.props.design.banding, "front_banding", 0)) this.the_back_canvas.add(this.designElementToImage(this.props.design.banding, "back_banding", 0)) this.the_front_canvas.add(this.designElementToImage(this.props.design.stripe, "front_stripe", 2)) this.the_back_canvas.add(this.designElementToImage(this.props.design.stripe, "back_stripe", 2)) this.the_front_canvas.add(this.designElementToImage(this.props.design.button, "front_button", 2)) this.the_front_canvas.add(this.textElementToImage(this.props.text.frontchest, "frontchest")) this.the_front_canvas.add(this.textElementToImage(this.props.text.rightarm, "rightarm")) this.the_back_canvas.add(this.textElementToImage(this.props.text.upperback, "upperback")) this.the_back_canvas.add(this.textElementToImage(this.props.text.middleback, "middleback")) this.the_back_canvas.add(this.textElementToImage(this.props.text.lowerback, "lowerback")) // console.log("the_front_canvas: ", this.the_front_canvas); //this.the_front_canvas.renderAll(); //this.the_back_canvas.renderAll(); } designElementToImage(color, type, z_Index) { console.log("FabricCanvas - designElementToImage - color: ", color, "type: ", type) var imgElement = document.createElement("img"); var src = './images/templates/' + type + '/' + type + color.substring(1)+'.png'; // console.log("src: ", src) imgElement.setAttribute("src", require(src)); var imgInstance = new fabric.Image(imgElement, { width: 430, height: 460, the_type: type , zIndex: z_Index }); // console.log("imgInstance: ", imgInstance) return imgInstance } textElementToImage(text, type) { console.log("FabricCanvas - textElementToImage") let imgInstance; switch(type) { case "frontchest": imgInstance = new fabric.IText(text.textvalue, { fontFamily: text.fontFamily, fill: text.fill, fontStyle: text.fontStyle, fontSize: text.fontSize, the_type: type, zIndex: 10, left: text.left, top: text.top, textAlign: "center" }) break; case "rightarm": imgInstance = new fabric.IText(text.textvalue, { fontFamily: text.fontFamily, fill: text.fill, fontStyle: text.fontStyle, fontSize: text.fontSize, the_type: type, zIndex: 10, left: 50, top: 120, textAlign: "center" }) break; case "upperback": imgInstance = new fabric.IText(text.textvalue, { fontFamily: text.fontFamily, fill: text.fill, fontStyle: text.fontStyle, fontSize: text.fontSize, the_type: type, zIndex: 10, left: 140, top: 120, textAlign: "center" }) break; case "middleback": imgInstance = new fabric.IText(text.textvalue, { fontFamily: text.fontFamily, fill: text.fill, fontStyle: text.fontStyle, fontSize: text.fontSize, the_type: type, zIndex: 10, left: 160, top: 145, textAlign: "center" }) break; case "lowerback": imgInstance = new fabric.IText(text.textvalue, { fontFamily: text.fontFamily, fill: text.fill, fontStyle: text.fontStyle, fontSize: text.fontSize, the_type: type, zIndex: 10, // left: 120, // top: 170, textAlign: "center" }) break; default: break; } console.log("text imgInstance: ", imgInstance) return imgInstance } componentWillReceiveProps = (newprops) => { console.log("FabricCanvas - componentWillReceiveProps newprops: ", newprops) // If Updated Item is not the same as the old one // => Update the canvas with newer item for(let element of this.design_element){ if(newprops.design[element] !== this.props.design[element]) { if(element === "stripe" ) { this.updateFrontCanvasforImage(this.designElementToImage(newprops.design[element], 'front_'+element, 2)) this.updateBackCanvasforImage(this.designElementToImage(newprops.design[element], 'back_'+element, 2)) } else if (element === "button") { this.updateFrontCanvasforImage(this.designElementToImage(newprops.design[element], 'front_'+element, 2)) } else { this.updateFrontCanvasforImage(this.designElementToImage(newprops.design[element], 'front_'+element, 0)) this.updateBackCanvasforImage(this.designElementToImage(newprops.design[element], 'back_'+element, 0)) //this.forceUpdate(); //console.log("force update"); } } } for(let element of this.text_element){ if(newprops.text[element] !== this.props.text[element]) { switch(element) { case "frontchest": this.updateFrontCanvasforImage(this.textElementToImage(newprops.text.frontchest, "frontchest")) break; case "rightarm": this.updateFrontCanvasforImage(this.textElementToImage(newprops.text.rightarm, "rightarm")) break; case "upperback": this.updateBackCanvasforImage(this.textElementToImage(newprops.text.upperback, "upperback")) break; case "middleback": this.updateBackCanvasforImage(this.textElementToImage(newprops.text.middleback, "middleback")) break; case "lowerback": this.updateBackCanvasforImage(this.textElementToImage(newprops.text.lowerback, "lowerback")) break; default: break; } } } } updateFrontCanvasforImage = (next) => { console.log("FabricCanvas - updateFrontCanvasForImage next: ", next) if(next){ let to_remove; // Find the same kind of element this.the_front_canvas.forEachObject( (object) => { if(object.the_type === next.the_type){ console.log("obcject.the_type: ", object.the_type, " next.the_type: ", next.the_type) to_remove = object; this.the_front_canvas.remove(to_remove); } } ); //this.the_front_canvas.remove(to_remove); // console.log("remove front canvas"); //this.the_front_canvas.renderAll(); // if(next.the_type === 'bg'){ // this.the_front_canvas.setBackgroundImage(next); // this.the_front_canvas.renderAll(); // return; // } this.the_front_canvas.add(next); // console.log("add to front canvas"); //this.the_front_canvas.requestRenderAll(); this.the_front_canvas.moveTo(next, next.zIndex); this.the_front_canvas.renderAll(); //this.forceUpdate(); //console.log("rerender"); } } updateBackCanvasforImage = (next) => { console.log("FabricCanvas - updateBackCanvasForImage") if(next){ let to_remove; // Find the same kind of element this.the_back_canvas.forEachObject( (object) => { if(object.the_type === next.the_type){ to_remove = object; this.the_back_canvas.remove(to_remove); } } ); //this.the_back_canvas.remove(to_remove); //this.the_back_canvas.renderAll(); // if(next.the_type === 'bg'){ // this.the_back_canvas.setBackgroundImage(next); // this.the_back_canvas.renderAll(); // return; // } this.the_back_canvas.add(next); //this.the_back_canvas.renderAll(); this.the_back_canvas.moveTo(next, next.zIndex); //this.the_back_canvas.renderAll(); } } onDrop = (e) => { console.log("hey"); e.preventDefault(); var preview = document.getElementById('img'); //var img = new Image(40, 40); var file = document.getElementById('input').files[0]; var canvas = this.the_front_canvas; var canvas2 = this.the_back_canvas; let reader = new FileReader(); reader.addEventListener("load", function() { preview.src = reader.result; //img.src = reader.result; /*var imgInstance = new fabric.Image(preview, { width: 40, height: 40, the_type: "upload", zIndex: 2 });*/ console.log(preview.width); console.log(preview.height); var imgInstance = new fabric.Image(preview, { width: 899, height:959, the_type: "upload", zIndex: 10 }); console.log("imgInstance set"); imgInstance.set({ scaleY: 0.1, scaleX: 0.1, originX: "center", originY: "center" }); console.log("imgInstance scale"); canvas.add(imgInstance); canvas2.add(imgInstance); canvas.renderAll(); canvas2.renderAll(); canvas.moveTo(imgInstance, imgInstance.zIndex); canvas2.moveTo(imgInstance, imgInstance.zIndex); canvas.renderAll(); canvas2.renderAll(); console.log("imgInstance add"); //var imgInstance = new fabric.Image(preview); /*this.the_canvas = new fabric.Canvas('main-canvas', { preserveObjectStacking: true, height:959, width:899, });*/ },false); /*reader.onloadend = () => { var img = new Image(40,40); img.src = reader.result; var imgInstance = new fabric.Image(img, { width: 899, height: 959, the_type: "upload", zIndex: 2 }); this.the_canvas.add(imgInstance); }*/ if (file) { reader.readAsDataURL(file); } //console.log(img.src); /*var imgInstance = new fabric.Image(img, { width: 40, height: 40, the_type: "upload", zIndex: 2 });*/ //var imgInstance = new fabric.Image(img); //this.the_canvas.add(imgInstance); this.the_front_canvas = canvas; } saveToCanvas = () => { console.log("FabricCanvas - saveToCanvas") let link = document.createElement("a"); link.href = this.the_canvas.toDataURL({format: 'png'}); link.download = "design.png"; link.click(); } fileChangedHandler = (event) => { const file = event.target.files[0]; this.setState({selectedFile: file}); } render(){ console.log("FabricCanvas - render - this.state: ", this.state) return ( <div className= "main-canvas-container"> <button class="front_btn" type="button">Front</button> <canvas id='front-canvas'> </canvas> {/*<input type = "file" id = "input" onChange = {this.onDrop} /> <img src = "" id = "img" />*/} <button class="back_btn" type="button">Back</button> <canvas id='back-canvas'> </canvas> </div> ); } } export default FabricCanvas;
혹시라도 합치는 과정에서 제가 실수로 지워버린 것들이 있을까봐 올려놓을게요!