diff --git a/.DS_Store b/.DS_Store index c511b2d..c0dc41c 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/demo-site/Tape.js b/demo-site/Tape.js index 3d70a80..54cb50a 100644 --- a/demo-site/Tape.js +++ b/demo-site/Tape.js @@ -1,24 +1,259 @@ -import React from 'react' -import styled from '@emotion/styled' +import React from "react"; +import styled from "@emotion/styled"; +import { keyframes, css } from "@emotion/core"; +import quotes from './quotes' export default ({ svg }) => { + const [currentBarcodeSVG, setCurrentBarcodeSVG] = React.useState(svg); + const [isPrinting, setIsPrinting] = React.useState(false); + const [isTearing, setIsTearing] = React.useState(false); + const [currentQuote, setCurrentQuote] = React.useState(0) + + React.useEffect(() => { + if (prevSVG.current === null && svg) { + setCurrentBarcodeSVG(svg); + setIsPrinting(true); + } else if (prevSVG.current !== null && prevSVG.current !== undefined) { + setIsTearing(true); + } + }, [svg]); + + const prevSVG = React.useRef(); + React.useEffect(() => { + prevSVG.current = svg; + }); + + const handleAnimationEnd = () => { + if (isTearing) { + setCurrentQuote(x => x === quotes.length - 1 ? 0 : x + 1) + setIsTearing(false); + setCurrentBarcodeSVG(svg); + } + }; + + const handleTransitionEnd = () => { + if (isPrinting) { + setIsPrinting(false); + } + }; + return ( - svg ? - + + + + + + + + + {quotes[currentQuote]} + + + + + {/* */} + + + + - : null - ) -} + ); +}; -const Wrapper = styled('div')` +const Wrapper = styled("div")` display: flex; - margin-top: 100px; justify-content: center; - width: 500px; -` + align-items: center; + width: 100%; + height: 100%; +`; + +const BarcodeWrapper = styled("div")` + width: 100%; + padding: 15px; +`; + +const Barcode = styled("img")` + width: 100%; + max-height: 100px; +`; + +const Slot = styled("div")` + width: 400px; + height: 10px; + background: linear-gradient( + to right, + rgb(65, 65, 65) 0%, + rgb(31, 31, 31) 2%, + rgb(31, 31, 31) 98%, + rgb(65, 65, 65) 100% + ); + box-shadow: inset 0px -4px 4px rgba(255, 255, 255, 0.1), + inset 0px 3px 3px rgba(0, 0, 0, 0.4); + border-radius: 4px; + position: relative; +`; + +const Cutter = styled("div")` + position: absolute; + left: 15px; + bottom: 0px; + width: calc(100% - 30px); + height: 1px; + background: #d7d7d7; + &::after { + background: linear-gradient(-45deg, #ffffff 2px, transparent 0), + linear-gradient(45deg, #d7d7d7 2px, transparent 0); + background-position: left-bottom; + background-repeat: repeat-x; + background-size: 4px 4px; + content: " "; + display: block; + position: absolute; + bottom: 0px; + left: 0px; + width: 100%; + height: 4px; + } +`; -const Barcode = styled('img')` +const ReceiptPositioner = styled("div")` width: 100%; - max-height: 130px; + height: 39px; + position: absolute; + left: 0px; + bottom: 0px; + display: flex; + justify-content: center; +`; + +const ReceiptHider = styled("div")` + width: 100%; + overflow: hidden; + display: flex; + justify-content: center; + height: 450px; +`; + +const ReceiptColumn = styled("div")` + display: flex; + align-items: center; + flex-direction: column; + position: relative; + &::after{ + content: ""; + width: 340px; + height: 30px; + background: linear-gradient(to bottom, rgba(0,0,0,.3), rgba(0,0,0,0)); + position: absolute; + left: 0px; + top: 0px; + z-index: 9; + transition: opacity 500ms; + opacity: ${({show}) => show ? 1 : 0}; + } +`; + +const printPaper = keyframes` + 0%{ + transform: translateY(-100%); + } + 100%{ + transform: translateY(0%); + } +`; + +const tearPaper = keyframes` + 0%{ + transform: translateY(0%) rotate(0deg); + } + 25%{ + transform: translateY(3%) rotate(3deg); + } + 65%{ + opacity: 1; + } + 100%{ + transform: translateY(100%) rotate(10deg); + opacity: 0; + } +`; + +const ReceiptPaper = styled("div")` + width: 340px; + background: #fff; + position: relative; + box-shadow: 0px 10px 10px -4px rgba(0, 0, 0, 0.2); + transform: translateY(-100%); + z-index: 3; + animation: ${({ tearing, printing }) => + tearing + ? css` + ${tearPaper} 700ms + ` + : printing + ? css` + ${printPaper} 1000ms + ` + : ""}; + animation-fill-mode: forwards; + animation-timing-function: linear; + transform-origin: top left; + &::after { + background: linear-gradient(-45deg, white 4px, transparent 0), + linear-gradient(45deg, white 4px, transparent 0); + transform: rotate(180deg); + background-position: left-bottom; + background-repeat: repeat-x; + background-size: 8px 8px; + content: " "; + display: block; + position: absolute; + bottom: -8px; + left: 0px; + width: 100%; + height: 8px; + } + &::before { + background: linear-gradient(-45deg, white 4px, transparent 0), + linear-gradient(45deg, white 4px, transparent 0); + background-position: left-bottom; + background-repeat: repeat-x; + background-size: 8px 8px; + content: " "; + display: block; + position: absolute; + top: -8px; + left: 0px; + width: 100%; + height: 8px; + } +`; + +const Quote = styled('p')` + font-family: "VT323", monospace; + white-space: pre-wrap; + margin: 0px; + padding: 15px; + font-size: 24px; + padding-bottom: 0px; ` + +// const ReceiptShadow = styled("div")` +// position: absolute; +// width: calc(100% + 20px); +// height: 100%; +// background: rgba(0, 0, 0, 0.2); +// filter: blur(15px); +// left: -10px; +// top: 0px; +// content: ""; +// transform: perspective(1000px) rotateX(-30deg); +// z-index: -2; +// `; diff --git a/demo-site/digital.ttf b/demo-site/digital.ttf new file mode 100644 index 0000000..5a98d7a Binary files /dev/null and b/demo-site/digital.ttf differ diff --git a/demo-site/index.css b/demo-site/index.css index 0e8b279..5a39e4f 100644 --- a/demo-site/index.css +++ b/demo-site/index.css @@ -1,3 +1,8 @@ +@font-face { + font-family: "Digital"; + font-weight: 400; + src: url('./digital.ttf') format("truetype"); +} *{ box-sizing: border-box; } @@ -5,5 +10,5 @@ body, input, textarea, button{ font-family: 'Montserrat', sans-serif; } body{ - background: #efeeee; + background: #d5d8d9; } diff --git a/demo-site/index.html b/demo-site/index.html index 4a72a5e..577a04b 100644 --- a/demo-site/index.html +++ b/demo-site/index.html @@ -1,5 +1,7 @@ + + Barcode Generator | Tecuity diff --git a/demo-site/index.js b/demo-site/index.js index e209312..15e32c2 100644 --- a/demo-site/index.js +++ b/demo-site/index.js @@ -18,18 +18,27 @@ const App = () => { Barcode Generator - - setCode(e.target.value.replace(/ /g, ""))} - onKeyDown={e => { - if (e.keyCode === 13) generate(); - }} - /> - - - + + + setCode(e.target.value.replace(/ /g, ""))} + onKeyDown={e => { + if (e.keyCode === 13) generate(); + }} + /> +
+ + +
+
+ + + +
); @@ -48,57 +57,119 @@ const Column = styled("div")` padding-top: 100px; `; +const PerspectiveWrapper = styled('div')` + position: relative; +` + +const TapeContainer = styled('div')` + content: ""; + z-index: 0; + width: calc(100% + 8px); + height: 70px; + background: linear-gradient(to right, #424242 0%, #6c6c6c 3%, #6c6c6c 65%, #6c6c6c 97%, #424242 100%); + box-shadow: inset 0px -30px 30px rgba(0,0,0,.3); + bottom: -60px; + left: -4px; + position: absolute; + border: 1px solid rgb(103, 103, 103); + border-radius: 3px 3px 6px 6px; +` + const Row = styled("div")` display: flex; align-items: center; - padding: 10px; - border: 1px solid rgba(255, 255, 255, 0.3); - border-radius: 5px; - background: #efeeee; - box-shadow: -6px -6px 16px rgba(255, 255, 255, 0.7), 6px 6px 16px #d1cdc780; + padding: 15px; + border: 1px solid rgba(0,0,0, 0.2); + border-radius: 8px; + background: linear-gradient(to right, #505050 0%, #6a6a6a 3%, #797777 35%, #6b6b6b 97%, #505050 100%); + box-shadow: inset 0px 0px 5px rgba(255,255,255,.2); + transform: perspective(1000px) rotateX(20deg); + position: relative; + z-index: 1; `; const Title = styled("h1")` - font-family: "Montserrat", sans-serif; + font-family: "VT323", monospace; font-weight: 300; - margin-bottom: 50px; + margin-bottom: 30px; + font-size: 48px; `; const Input = styled("input")` border: 1px solid rgba(255, 255, 255, 0.3); - background: none; + background: rgb(197, 208, 161); + color: rgb(33, 43, 39); border-radius: 5px; box-shadow: inset 0px 7px 15px -5px rgba(0, 0, 0, 0.2), inset 0px -7px 15px -5px rgba(255, 255, 255, 1); - font-size: 40px; + font-size: 70px; width: 400px; height: 70px; padding: 10px; - text-align: center; + padding-top: 20px; margin-right: 10px; + font-family: "Digital"; &:focus { - background: rgba(255, 255, 255, 0.2); + background: rgb(208, 215, 183); outline: none; } `; const Button = styled("button")` - font-size: 35px; + font-size: 25px; font-weight: 600; text-transform: uppercase; height: 70px; + width: 70px; + ${'' /* border: 1px solid rgba(0,0,0,.6); */} + ${'' /* border-bottom-color: #e2e1c5; */} border: none; - background: linear-gradient(to bottom, #95c93d, #88ba33); + background: linear-gradient(to top, #dddcc0, #f7f7e7); border-radius: 5px; - padding: 12px; - color: #fff; + color: #838374; text-shadow: 0px 1px white, 0px -1px 1px #979e90; + display: flex; + justify-content: center; + align-items: center; + padding: 0px; + position: relative; + will-change: transform; + margin-top: -7px; + transition: transform 100ms; &:focus { outline: none; } &:hover { - background: linear-gradient(to bottom, #a6dd4a, #99cd41); + transform: translateY(-2px); + } + &:active { + transform: translateY(2px); } `; +const ButtonBottom = styled('div')` + content: ""; + width: 100%; + height: 10px; + border-radius: 0px 0px 5px 5px; + position: absolute; + left: 0px; + bottom: -4px; + ${'' /* background: #b6b596; */} + z-index: -1; + ${'' /* border: 1px solid rgba(0,0,0,.5); */} + background: linear-gradient(to right, #d2d2b7 0%, #b6b596 7%, #b6b596 93%, #d2d2b7 100%); +` + +const Circle = styled("div")` + display: flex; + justify-content: center; + align-items: center; + width: 55px; + height: 55px; + border-radius: 100%; + background: linear-gradient(to bottom, #dddcc0, #f7f7e7); + ${'' /* border: 2px solid rgba(255,255,255,.2); */} +` + ReactDOM.render(, document.getElementById("root")); diff --git a/demo-site/quotes.json b/demo-site/quotes.json new file mode 100644 index 0000000..774b833 --- /dev/null +++ b/demo-site/quotes.json @@ -0,0 +1,21 @@ +[ + "It was many and many a year ago,\nIn a kingdom by the sea", + "That a maiden there lived whom you may know\nBy the name of Annabel Lee;", + "And this maiden she lived with no other thought\nThan to love and be loved by me.", + "But we loved with a love that was more than love—\nI and my Annabel Lee—", + "With a love that the wingèd seraphs of Heaven\nCoveted her and me.", + "And this was the reason that, long ago,\nIn this kingdom by the sea,", + "A wind blew out of a cloud, chilling\nMy beautiful Annabel Lee;", + "So that her highborn kinsmen came\nAnd bore her away from me", + "To shut her up in a sepulchre\nIn this kingdom by the sea.", + "The angels, not half so happy in Heaven,\nWent envying her and me—", + "Yes!—that was the reason (as all men know,\nIn this kingdom by the sea)", + "That the wind came out of the cloud by night,\nChilling and killing my Annabel Lee.", + "But our love it was stronger by far than the love\nOf those who were older than we—\nOf many far wiser than we—", + "And neither the angels in Heaven above\nNor the demons down under the sea", + "Can ever dissever my soul from the soul\nOf the beautiful Annabel Lee;", + "For the moon never beams, without bringing me dreams\nOf the beautiful Annabel Lee;", + "And the stars never rise, but I feel the bright eyes\nOf the beautiful Annabel Lee;", + "And so, all the night-tide, I lie down by the side\nOf my darling—my darling—my life and my bride,", + "In her sepulchre there by the sea—\nIn her tomb by the sounding sea." +]