Heeeey guys!
My name is Gustavo Scarpim, and I will show you how to make Upload image in base64 with React.
To get started, create a new project with yarn create react-app myapp --template typescript or npx create-react-app myapp --template typescript.
Add dependencies: yarn add or npm i styled-components react-icons
Upload.tsx
import React, { useState } from 'react';
import * as S from './upload';
import { BsUpload } from 'react-icons/bs';
import { ImSpinner2 } from 'react-icons/im';
import Logo from '../assets/logo.png';
import { setTimeout } from 'timers';
export default function Upload() {
const [file, setFile] = useState<string>();
const [imagePreview, setImagePreview] = useState<any>("");
const [base64, setBase64] = useState<string>();
const [name, setName] = useState<string>();
const [size, setSize] = useState<string>();
const [isLoading, setIsLoading] = useState<boolean>(false);
const onChange = (e: any) => {
console.log("file", e.target.files[0]);
let file = e.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = _handleReaderLoaded
reader.readAsBinaryString(file)
}
}
const _handleReaderLoaded = (readerEvt: any) => {
let binaryString = readerEvt.target.result;
setBase64(btoa(binaryString))
}
const onFileSubmit = (e: any) => {
setIsLoading(true);
e.preventDefault()
console.log("bine", base64)
let payload = { image: base64 }
console.log("payload", payload)
setTimeout(() => {
setIsLoading(false)
}, 2000)
}
const photoUpload = (e: any) => {
e.preventDefault();
const reader = new FileReader();
const file = e.target.files[0];
console.log("reader", reader)
console.log("file", file)
if (reader !== undefined && file !== undefined) {
reader.onloadend = () => {
setFile(file)
setSize(file.size);
setName(file.name)
setImagePreview(reader.result)
}
reader.readAsDataURL(file);
}
}
const remove = () => {
setFile("")
setImagePreview("")
setBase64("")
setName("")
setSize("")
}
return (
<S.Container>
<form onSubmit={(e) => onFileSubmit(e)} onChange={(e) => onChange(e)}>
<S.Card logo={Logo}
width={imagePreview === "" ? 310 : 310}
height={imagePreview === "" ? 400 : 480} >
<S.Perfil top={imagePreview === "" ? 0 : -140}
width={imagePreview === "" ? 120 : 145}
height={imagePreview === "" ? 120 : 145} >
{imagePreview === "" ?
<BsUpload /> :
<img src={imagePreview} alt="Icone adicionar" />
}
<input type="file" name="avatar" id="file" accept=".jpef, .png, .jpg" onChange={photoUpload} src={imagePreview} />
</S.Perfil>
{imagePreview !== "" &&
<>
<section>
<label>Nome</label>
<span>{name}</span>
<label>Tamanho</label>
<span>{size}</span>
</section>
<button type="submit" >
{isLoading ?
<S.Spinner>
<ImSpinner2 />
</S.Spinner> :
<>
Salvar
</>
}
</button>
<button type="button" onClick={remove} >Remover</button>
</>
}
</S.Card>
</form>
</S.Container>
)
}
Upload.ts
import styled from 'styled-components';
export const Container = styled.div`
display: flex;
justify-content: center;
align-items: center;
width: 100vw;
height: 100vh;
background: #000;
.flip-container {
width: 300px;
height: 200px;
perspective: 1000px;
}
.flipper {
position: relative;
width: 100%;
height: 100%;
transition: transform 0.8s;
transform-style: preserve-3d;
}
.flip-container:hover .flipper{
transform: rotateY(180deg);
}
.front, .back{
position: absolute;
width: 100%;
height: 100%;
}
`
export const Card = styled.div<{ logo: string, width: number, height: number }>`
display: flex;
flex-direction: column;
align-items: center;
position: relative;
/* width: 310px;
height: 600px; */
width: ${props => props.width}px;
height: ${props => props.height}px;
padding: 15px;
margin-top: 40px;
border-radius: 25px;
display: flex;
justify-content: center;
transition: all 1s;
box-shadow: 0px 0px 10px 0px #FFF;
background: #fff;
background-image: url(${props => props.logo});
background-repeat: no-repeat, no-repeat;
background-position: 50% 5%, 200% -40%;
background-size: 55%, 80%;
animation: effectShow .4s cubic-bezier(.1,.82,.25,1);
&:hover {
transition: all 0.6s;
box-shadow: 0px 0px 20px 10px #387289;
}
@keyframes effectShow {
0% {
transform: scale(1.4);
opacity: 0;
}
100% {
transform: scale(1);
opacity: 1;
}
}
button {
&:nth-last-child(2) {
bottom: 55px !important;
width: 80%;
background: #387289;
&:hover {
transition: all 1s;
background: #66CBBC;
}
}
position: absolute;
bottom: 15px;
border-radius: 20px;
border: none;
background: #ed3a53;
width: 50%;
color: #fff;
height: 30px;
font-weight: bold;
cursor: pointer;
&:hover {
transition: all 1s;
background: #fd637b;
}
}
section {
display: flex;
justify-content: center;
flex-direction: column;
position: absolute;
margin-top: 120px;
width: 80%;
text-align: center;
padding-top: 20px;
transition: all 1.6s;
label {
font-size: 20px;
margin-bottom: 8px;
transition: all 1.6s;
}
span {
transition: all 1.6s;
font-size: 16px;
margin-bottom: 8px;
height: 18px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
`
export const Perfil = styled.div<{ top: number, width: number, height: number }>`
width: ${props => props.width}px;
height: ${props => props.height}px;
margin-top: ${props => props.top}px;
background: aliceblue;
border-radius: 100%;
display: flex;
justify-content: center;
align-items: center;
transition: all 1s;
svg {
width: 80px;
height: 80px;
transition: all 1s;
}
img {
width: ${props => props.width}px;
height: ${props => props.height}px;
border-radius: 100%;
transition: all 1s;
}
input[type="file"] {
opacity: 0;
position: absolute;
border-radius: 100%;
cursor: pointer;
z-index: 99999;
width: 145px;
height: 145px;
}
&:hover {
transition: all 1s;
box-shadow: 0px 0px 15px 2px #387289;
}
`
export const Spinner = styled.div`
position: absolute;
display: flex;
justify-content: center;
margin-top: 7px;
width: 100%;
z-index: 9999;
top: 0;
animation: spin 1s 0.1s ease-in-out infinite both;
@keyframes spin {
from {
transform: rotate(0);
}
to {
transform: rotate(360deg);
}
}
`
Index.ts
import React from 'react';
import ReactDOM from 'react-dom';
import reportWebVitals from './reportWebVitals';
import Upload from './pages/Upload';
import GlobalStyles from './globalStyles';
ReactDOM.render(
<React.StrictMode>
<GlobalStyles />
<Upload />
</React.StrictMode>,
document.getElementById('root')
);
reportWebVitals();
And ready, your upload base64 project:
See the complete code here on GitHub Click here
Check out the Project in action Deploy
Thanks for reading.
Top comments (0)