React Resizing Image using reactcrop
I'm new to react and am learning to crop a photo. I've been following the codingforentreprenuers tutorial react and now canupload and crop an image. I want to take the cropped image and make it a certain size (e.g. 750x750 pixels). Thus no matter what size photo goes in, the same size photo comes out regardless of how much or how little you 'crop' it.
How can I set the width and height for this image cropper?
I'm tried the following, but it doesn't work.
crop: {
aspect: 1/1,
width: 750
}
React Code:
import React, { Component } from 'react'
import Dropzone from 'react-dropzone'
import ReactCrop from 'react-image-crop'
import './custom-image-crop.css';
import {base64StringtoFile,
downloadBase64File,
extractImageFileExtensionFromBase64,
image64toCanvasRef} from './ResuableUtils'
const imageMaxSize = 1024 * 5000 // bytes
const acceptedFileTypes = 'image/x-png, image/png, image/jpg, image/jpeg, image/gif'
const acceptedFileTypesArray = acceptedFileTypes.split(",").map((item) => {return item.trim()})
class ImgDropAndCrop extends Component {
constructor(props){
super(props)
this.imagePreviewCanvasRef = React.createRef()
this.fileInputRef = React.createRef()
this.state = {
imgSrc: null,
imgSrcExt: null,
crop: {
aspect: 1/1,
}
}
}
verifyFile = (files) => {
if (files && files.length > 0){
const currentFile = files[0]
const currentFileType = currentFile.type
const currentFileSize = currentFile.size
if(currentFileSize > imageMaxSize) {
alert("This file is not allowed. " + currentFileSize + " bytes is too large")
return false
}
if (!acceptedFileTypesArray.includes(currentFileType)){
alert("This file is not allowed. Only images are allowed.")
return false
}
return true
}
}
handleOnDrop = (files, rejectedFiles) => {
if (rejectedFiles && rejectedFiles.length > 0){
this.verifyFile(rejectedFiles)
}
if (files && files.length > 0){
const isVerified = this.verifyFile(files)
if (isVerified){
// imageBase64Data
const currentFile = files[0]
const myFileItemReader = new FileReader()
myFileItemReader.addEventListener("load", ()=>{
// console.log(myFileItemReader.result)
const myResult = myFileItemReader.result
this.setState({
imgSrc: myResult,
imgSrcExt: extractImageFileExtensionFromBase64(myResult)
})
}, false)
myFileItemReader.readAsDataURL(currentFile)
}
}
}
handleImageLoaded = (image) => {
//console.log(image)
}
handleOnCropChange = (crop) => {
this.setState({crop:crop})
}
handleOnCropComplete = (crop, pixelCrop) =>{
//console.log(crop, pixelCrop)
const canvasRef = this.imagePreviewCanvasRef.current
const {imgSrc} = this.state
image64toCanvasRef(canvasRef, imgSrc, pixelCrop)
}
handleDownloadClick = (event) => {
event.preventDefault()
const {imgSrc} = this.state
if (imgSrc) {
const canvasRef = this.imagePreviewCanvasRef.current
const {imgSrcExt} = this.state
const imageData64 = canvasRef.toDataURL('image/' + imgSrcExt)
const myFilename = "previewFile." + imgSrcExt
// file to be uploaded
const myNewCroppedFile = base64StringtoFile(imageData64, myFilename)
console.log(myNewCroppedFile)
// download file
downloadBase64File(imageData64, myFilename)
this.handleClearToDefault()
}
}
handleClearToDefault = event =>{
if (event) event.preventDefault()
const canvas = this.imagePreviewCanvasRef.current
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height)
this.setState({
imgSrc: null,
imgSrcExt: null,
crop: {
aspect: 1/1
}
})
this.fileInputRef.current.value = null
}
handleFileSelect = event => {
// console.log(event)
const files = event.target.files
if (files && files.length > 0){
const isVerified = this.verifyFile(files)
if (isVerified){
// imageBase64Data
const currentFile = files[0]
const myFileItemReader = new FileReader()
myFileItemReader.addEventListener("load", ()=>{
// console.log(myFileItemReader.result)
const myResult = myFileItemReader.result
this.setState({
imgSrc: myResult,
imgSrcExt: extractImageFileExtensionFromBase64(myResult)
})
}, false)
myFileItemReader.readAsDataURL(currentFile)
}
}
}
render () {
const {imgSrc} = this.state
return (
<div>
<h1>Drop and Crop</h1>
<input ref={this.fileInputRef} type='file' accept={acceptedFileTypes} multiple={false} onChange={this.handleFileSelect} />
<div>
{imgSrc !== null ?
<div>
<ReactCrop
src={imgSrc}
crop={this.state.crop}
onImageLoaded={this.handleImageLoaded}
onComplete = {this.handleOnCropComplete}
onChange={this.handleOnCropChange}/>
<br/>
<p>Preview Canvas Crop </p>
<canvas ref={this.imagePreviewCanvasRef}></canvas>
<button onClick={this.handleDownloadClick}>Download</button>
<button onClick={this.handleClearToDefault}>Clear</button>
</div>
:
// <div></div>
<Dropzone onDrop={this.handleOnDrop} accept={acceptedFileTypes} multiple={false} maxSize={imageMaxSize}>Drop image here or click to upload</Dropzone>
}
</div>
</div>
)
}
}
export default ImgDropAndCrop
reactjs crop
add a comment |
I'm new to react and am learning to crop a photo. I've been following the codingforentreprenuers tutorial react and now canupload and crop an image. I want to take the cropped image and make it a certain size (e.g. 750x750 pixels). Thus no matter what size photo goes in, the same size photo comes out regardless of how much or how little you 'crop' it.
How can I set the width and height for this image cropper?
I'm tried the following, but it doesn't work.
crop: {
aspect: 1/1,
width: 750
}
React Code:
import React, { Component } from 'react'
import Dropzone from 'react-dropzone'
import ReactCrop from 'react-image-crop'
import './custom-image-crop.css';
import {base64StringtoFile,
downloadBase64File,
extractImageFileExtensionFromBase64,
image64toCanvasRef} from './ResuableUtils'
const imageMaxSize = 1024 * 5000 // bytes
const acceptedFileTypes = 'image/x-png, image/png, image/jpg, image/jpeg, image/gif'
const acceptedFileTypesArray = acceptedFileTypes.split(",").map((item) => {return item.trim()})
class ImgDropAndCrop extends Component {
constructor(props){
super(props)
this.imagePreviewCanvasRef = React.createRef()
this.fileInputRef = React.createRef()
this.state = {
imgSrc: null,
imgSrcExt: null,
crop: {
aspect: 1/1,
}
}
}
verifyFile = (files) => {
if (files && files.length > 0){
const currentFile = files[0]
const currentFileType = currentFile.type
const currentFileSize = currentFile.size
if(currentFileSize > imageMaxSize) {
alert("This file is not allowed. " + currentFileSize + " bytes is too large")
return false
}
if (!acceptedFileTypesArray.includes(currentFileType)){
alert("This file is not allowed. Only images are allowed.")
return false
}
return true
}
}
handleOnDrop = (files, rejectedFiles) => {
if (rejectedFiles && rejectedFiles.length > 0){
this.verifyFile(rejectedFiles)
}
if (files && files.length > 0){
const isVerified = this.verifyFile(files)
if (isVerified){
// imageBase64Data
const currentFile = files[0]
const myFileItemReader = new FileReader()
myFileItemReader.addEventListener("load", ()=>{
// console.log(myFileItemReader.result)
const myResult = myFileItemReader.result
this.setState({
imgSrc: myResult,
imgSrcExt: extractImageFileExtensionFromBase64(myResult)
})
}, false)
myFileItemReader.readAsDataURL(currentFile)
}
}
}
handleImageLoaded = (image) => {
//console.log(image)
}
handleOnCropChange = (crop) => {
this.setState({crop:crop})
}
handleOnCropComplete = (crop, pixelCrop) =>{
//console.log(crop, pixelCrop)
const canvasRef = this.imagePreviewCanvasRef.current
const {imgSrc} = this.state
image64toCanvasRef(canvasRef, imgSrc, pixelCrop)
}
handleDownloadClick = (event) => {
event.preventDefault()
const {imgSrc} = this.state
if (imgSrc) {
const canvasRef = this.imagePreviewCanvasRef.current
const {imgSrcExt} = this.state
const imageData64 = canvasRef.toDataURL('image/' + imgSrcExt)
const myFilename = "previewFile." + imgSrcExt
// file to be uploaded
const myNewCroppedFile = base64StringtoFile(imageData64, myFilename)
console.log(myNewCroppedFile)
// download file
downloadBase64File(imageData64, myFilename)
this.handleClearToDefault()
}
}
handleClearToDefault = event =>{
if (event) event.preventDefault()
const canvas = this.imagePreviewCanvasRef.current
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height)
this.setState({
imgSrc: null,
imgSrcExt: null,
crop: {
aspect: 1/1
}
})
this.fileInputRef.current.value = null
}
handleFileSelect = event => {
// console.log(event)
const files = event.target.files
if (files && files.length > 0){
const isVerified = this.verifyFile(files)
if (isVerified){
// imageBase64Data
const currentFile = files[0]
const myFileItemReader = new FileReader()
myFileItemReader.addEventListener("load", ()=>{
// console.log(myFileItemReader.result)
const myResult = myFileItemReader.result
this.setState({
imgSrc: myResult,
imgSrcExt: extractImageFileExtensionFromBase64(myResult)
})
}, false)
myFileItemReader.readAsDataURL(currentFile)
}
}
}
render () {
const {imgSrc} = this.state
return (
<div>
<h1>Drop and Crop</h1>
<input ref={this.fileInputRef} type='file' accept={acceptedFileTypes} multiple={false} onChange={this.handleFileSelect} />
<div>
{imgSrc !== null ?
<div>
<ReactCrop
src={imgSrc}
crop={this.state.crop}
onImageLoaded={this.handleImageLoaded}
onComplete = {this.handleOnCropComplete}
onChange={this.handleOnCropChange}/>
<br/>
<p>Preview Canvas Crop </p>
<canvas ref={this.imagePreviewCanvasRef}></canvas>
<button onClick={this.handleDownloadClick}>Download</button>
<button onClick={this.handleClearToDefault}>Clear</button>
</div>
:
// <div></div>
<Dropzone onDrop={this.handleOnDrop} accept={acceptedFileTypes} multiple={false} maxSize={imageMaxSize}>Drop image here or click to upload</Dropzone>
}
</div>
</div>
)
}
}
export default ImgDropAndCrop
reactjs crop
add a comment |
I'm new to react and am learning to crop a photo. I've been following the codingforentreprenuers tutorial react and now canupload and crop an image. I want to take the cropped image and make it a certain size (e.g. 750x750 pixels). Thus no matter what size photo goes in, the same size photo comes out regardless of how much or how little you 'crop' it.
How can I set the width and height for this image cropper?
I'm tried the following, but it doesn't work.
crop: {
aspect: 1/1,
width: 750
}
React Code:
import React, { Component } from 'react'
import Dropzone from 'react-dropzone'
import ReactCrop from 'react-image-crop'
import './custom-image-crop.css';
import {base64StringtoFile,
downloadBase64File,
extractImageFileExtensionFromBase64,
image64toCanvasRef} from './ResuableUtils'
const imageMaxSize = 1024 * 5000 // bytes
const acceptedFileTypes = 'image/x-png, image/png, image/jpg, image/jpeg, image/gif'
const acceptedFileTypesArray = acceptedFileTypes.split(",").map((item) => {return item.trim()})
class ImgDropAndCrop extends Component {
constructor(props){
super(props)
this.imagePreviewCanvasRef = React.createRef()
this.fileInputRef = React.createRef()
this.state = {
imgSrc: null,
imgSrcExt: null,
crop: {
aspect: 1/1,
}
}
}
verifyFile = (files) => {
if (files && files.length > 0){
const currentFile = files[0]
const currentFileType = currentFile.type
const currentFileSize = currentFile.size
if(currentFileSize > imageMaxSize) {
alert("This file is not allowed. " + currentFileSize + " bytes is too large")
return false
}
if (!acceptedFileTypesArray.includes(currentFileType)){
alert("This file is not allowed. Only images are allowed.")
return false
}
return true
}
}
handleOnDrop = (files, rejectedFiles) => {
if (rejectedFiles && rejectedFiles.length > 0){
this.verifyFile(rejectedFiles)
}
if (files && files.length > 0){
const isVerified = this.verifyFile(files)
if (isVerified){
// imageBase64Data
const currentFile = files[0]
const myFileItemReader = new FileReader()
myFileItemReader.addEventListener("load", ()=>{
// console.log(myFileItemReader.result)
const myResult = myFileItemReader.result
this.setState({
imgSrc: myResult,
imgSrcExt: extractImageFileExtensionFromBase64(myResult)
})
}, false)
myFileItemReader.readAsDataURL(currentFile)
}
}
}
handleImageLoaded = (image) => {
//console.log(image)
}
handleOnCropChange = (crop) => {
this.setState({crop:crop})
}
handleOnCropComplete = (crop, pixelCrop) =>{
//console.log(crop, pixelCrop)
const canvasRef = this.imagePreviewCanvasRef.current
const {imgSrc} = this.state
image64toCanvasRef(canvasRef, imgSrc, pixelCrop)
}
handleDownloadClick = (event) => {
event.preventDefault()
const {imgSrc} = this.state
if (imgSrc) {
const canvasRef = this.imagePreviewCanvasRef.current
const {imgSrcExt} = this.state
const imageData64 = canvasRef.toDataURL('image/' + imgSrcExt)
const myFilename = "previewFile." + imgSrcExt
// file to be uploaded
const myNewCroppedFile = base64StringtoFile(imageData64, myFilename)
console.log(myNewCroppedFile)
// download file
downloadBase64File(imageData64, myFilename)
this.handleClearToDefault()
}
}
handleClearToDefault = event =>{
if (event) event.preventDefault()
const canvas = this.imagePreviewCanvasRef.current
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height)
this.setState({
imgSrc: null,
imgSrcExt: null,
crop: {
aspect: 1/1
}
})
this.fileInputRef.current.value = null
}
handleFileSelect = event => {
// console.log(event)
const files = event.target.files
if (files && files.length > 0){
const isVerified = this.verifyFile(files)
if (isVerified){
// imageBase64Data
const currentFile = files[0]
const myFileItemReader = new FileReader()
myFileItemReader.addEventListener("load", ()=>{
// console.log(myFileItemReader.result)
const myResult = myFileItemReader.result
this.setState({
imgSrc: myResult,
imgSrcExt: extractImageFileExtensionFromBase64(myResult)
})
}, false)
myFileItemReader.readAsDataURL(currentFile)
}
}
}
render () {
const {imgSrc} = this.state
return (
<div>
<h1>Drop and Crop</h1>
<input ref={this.fileInputRef} type='file' accept={acceptedFileTypes} multiple={false} onChange={this.handleFileSelect} />
<div>
{imgSrc !== null ?
<div>
<ReactCrop
src={imgSrc}
crop={this.state.crop}
onImageLoaded={this.handleImageLoaded}
onComplete = {this.handleOnCropComplete}
onChange={this.handleOnCropChange}/>
<br/>
<p>Preview Canvas Crop </p>
<canvas ref={this.imagePreviewCanvasRef}></canvas>
<button onClick={this.handleDownloadClick}>Download</button>
<button onClick={this.handleClearToDefault}>Clear</button>
</div>
:
// <div></div>
<Dropzone onDrop={this.handleOnDrop} accept={acceptedFileTypes} multiple={false} maxSize={imageMaxSize}>Drop image here or click to upload</Dropzone>
}
</div>
</div>
)
}
}
export default ImgDropAndCrop
reactjs crop
I'm new to react and am learning to crop a photo. I've been following the codingforentreprenuers tutorial react and now canupload and crop an image. I want to take the cropped image and make it a certain size (e.g. 750x750 pixels). Thus no matter what size photo goes in, the same size photo comes out regardless of how much or how little you 'crop' it.
How can I set the width and height for this image cropper?
I'm tried the following, but it doesn't work.
crop: {
aspect: 1/1,
width: 750
}
React Code:
import React, { Component } from 'react'
import Dropzone from 'react-dropzone'
import ReactCrop from 'react-image-crop'
import './custom-image-crop.css';
import {base64StringtoFile,
downloadBase64File,
extractImageFileExtensionFromBase64,
image64toCanvasRef} from './ResuableUtils'
const imageMaxSize = 1024 * 5000 // bytes
const acceptedFileTypes = 'image/x-png, image/png, image/jpg, image/jpeg, image/gif'
const acceptedFileTypesArray = acceptedFileTypes.split(",").map((item) => {return item.trim()})
class ImgDropAndCrop extends Component {
constructor(props){
super(props)
this.imagePreviewCanvasRef = React.createRef()
this.fileInputRef = React.createRef()
this.state = {
imgSrc: null,
imgSrcExt: null,
crop: {
aspect: 1/1,
}
}
}
verifyFile = (files) => {
if (files && files.length > 0){
const currentFile = files[0]
const currentFileType = currentFile.type
const currentFileSize = currentFile.size
if(currentFileSize > imageMaxSize) {
alert("This file is not allowed. " + currentFileSize + " bytes is too large")
return false
}
if (!acceptedFileTypesArray.includes(currentFileType)){
alert("This file is not allowed. Only images are allowed.")
return false
}
return true
}
}
handleOnDrop = (files, rejectedFiles) => {
if (rejectedFiles && rejectedFiles.length > 0){
this.verifyFile(rejectedFiles)
}
if (files && files.length > 0){
const isVerified = this.verifyFile(files)
if (isVerified){
// imageBase64Data
const currentFile = files[0]
const myFileItemReader = new FileReader()
myFileItemReader.addEventListener("load", ()=>{
// console.log(myFileItemReader.result)
const myResult = myFileItemReader.result
this.setState({
imgSrc: myResult,
imgSrcExt: extractImageFileExtensionFromBase64(myResult)
})
}, false)
myFileItemReader.readAsDataURL(currentFile)
}
}
}
handleImageLoaded = (image) => {
//console.log(image)
}
handleOnCropChange = (crop) => {
this.setState({crop:crop})
}
handleOnCropComplete = (crop, pixelCrop) =>{
//console.log(crop, pixelCrop)
const canvasRef = this.imagePreviewCanvasRef.current
const {imgSrc} = this.state
image64toCanvasRef(canvasRef, imgSrc, pixelCrop)
}
handleDownloadClick = (event) => {
event.preventDefault()
const {imgSrc} = this.state
if (imgSrc) {
const canvasRef = this.imagePreviewCanvasRef.current
const {imgSrcExt} = this.state
const imageData64 = canvasRef.toDataURL('image/' + imgSrcExt)
const myFilename = "previewFile." + imgSrcExt
// file to be uploaded
const myNewCroppedFile = base64StringtoFile(imageData64, myFilename)
console.log(myNewCroppedFile)
// download file
downloadBase64File(imageData64, myFilename)
this.handleClearToDefault()
}
}
handleClearToDefault = event =>{
if (event) event.preventDefault()
const canvas = this.imagePreviewCanvasRef.current
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height)
this.setState({
imgSrc: null,
imgSrcExt: null,
crop: {
aspect: 1/1
}
})
this.fileInputRef.current.value = null
}
handleFileSelect = event => {
// console.log(event)
const files = event.target.files
if (files && files.length > 0){
const isVerified = this.verifyFile(files)
if (isVerified){
// imageBase64Data
const currentFile = files[0]
const myFileItemReader = new FileReader()
myFileItemReader.addEventListener("load", ()=>{
// console.log(myFileItemReader.result)
const myResult = myFileItemReader.result
this.setState({
imgSrc: myResult,
imgSrcExt: extractImageFileExtensionFromBase64(myResult)
})
}, false)
myFileItemReader.readAsDataURL(currentFile)
}
}
}
render () {
const {imgSrc} = this.state
return (
<div>
<h1>Drop and Crop</h1>
<input ref={this.fileInputRef} type='file' accept={acceptedFileTypes} multiple={false} onChange={this.handleFileSelect} />
<div>
{imgSrc !== null ?
<div>
<ReactCrop
src={imgSrc}
crop={this.state.crop}
onImageLoaded={this.handleImageLoaded}
onComplete = {this.handleOnCropComplete}
onChange={this.handleOnCropChange}/>
<br/>
<p>Preview Canvas Crop </p>
<canvas ref={this.imagePreviewCanvasRef}></canvas>
<button onClick={this.handleDownloadClick}>Download</button>
<button onClick={this.handleClearToDefault}>Clear</button>
</div>
:
// <div></div>
<Dropzone onDrop={this.handleOnDrop} accept={acceptedFileTypes} multiple={false} maxSize={imageMaxSize}>Drop image here or click to upload</Dropzone>
}
</div>
</div>
)
}
}
export default ImgDropAndCrop
reactjs crop
reactjs crop
asked Nov 21 '18 at 5:44
Micah PearceMicah Pearce
397411
397411
add a comment |
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53405897%2freact-resizing-image-using-reactcrop%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53405897%2freact-resizing-image-using-reactcrop%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown