├── .nvmrc ├── .gitignore ├── .gitattributes ├── screenshot.png ├── public ├── favicon.ico ├── stranger-ipsum-title.png └── index.hbs ├── src ├── Button.jsx ├── index.js ├── App.css ├── generator.js └── App.jsx ├── .babelrc ├── .eslintrc.json ├── README.md ├── LICENSE ├── webpack.config.js ├── package.json └── yarn.lock /.nvmrc: -------------------------------------------------------------------------------- 1 | v8.11.3 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .DS_Store 4 | .vscode 5 | .idea -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertcoopercode/stranger-ipsum/HEAD/screenshot.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertcoopercode/stranger-ipsum/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /src/Button.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | function Buttion() { 4 | return ; 5 | } 6 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/env", "@babel/preset-react"], 3 | "plugins": ["@babel/proposal-class-properties"] 4 | } 5 | -------------------------------------------------------------------------------- /public/stranger-ipsum-title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertcoopercode/stranger-ipsum/HEAD/public/stranger-ipsum-title.png -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | ReactDOM.render(, document.getElementById('root')); 5 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "parserOptions": { 4 | "ecmaVersion": 6, 5 | "sourceType": "module", 6 | "ecmaFeatures": { 7 | "jsx": true 8 | } 9 | }, 10 | "plugins": ["babel"], 11 | "rules": { 12 | "semi": ["error", "always"], 13 | "quotes": ["error", "single"], 14 | "babel/semi": 0 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Stranger Ipsum V2 2 | 3 | Built a Lorem Ipsum Generator that spits out Stranger Things quotes. [V1 was built with Node](https://github.com/robertcoopercode/stranger-ipsum/tree/v1.0.1) and this version is built with React. 4 | 5 | You're able to select the number of paragraphs you'd like to generate and there is also a button that allows you to easily copy all the generated text. 6 | 7 | ![Stranger Ipsum Screenshot](/screenshot.png?raw=true "Stranger Ipsum Screenshot") 8 | 9 | ## Running the App Locally 🏃‍ 10 | 11 | Begin by running app.js in your terminal with the command `yarn start` and then access the application in your browser at _localhost:3000_. 12 | 13 | ## Deployment 🚀 14 | 15 | The repository deploys to Netlify on every commit to master. 16 | 17 | ## Credits 📜 18 | 19 | - Used this [Lorem Ipsum Generator](https://github.com/trohweder85/ipsum) to help with some of the JavaScript required to select random sentences. 20 | - Got the "Stranger Ipsum" font as well as the background video from [makeitstranger.com](http://makeitstranger.com/) 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Robert Cooper 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /public/index.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Stranger Ipsum 12 | 13 | 14 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 4 | const CopyWebpackPlugin = require('copy-webpack-plugin'); 5 | const CleanWebpackPlugin = require('clean-webpack-plugin'); 6 | 7 | module.exports = { 8 | entry: './src/index.js', 9 | module: { 10 | rules: [ 11 | { 12 | test: /\.(js|jsx)$/, 13 | exclude: /(node_modules|bower_components)/, 14 | loader: 'babel-loader', 15 | options: { presets: ['@babel/env'] }, 16 | }, 17 | { 18 | test: /\.css$/, 19 | use: ['style-loader', 'css-loader'], 20 | }, 21 | { 22 | test: /\.hbs$/, 23 | loader: 'handlebars-loader', 24 | }, 25 | ], 26 | }, 27 | resolve: { extensions: ['*', '.js', '.jsx'] }, 28 | output: { 29 | path: path.resolve(__dirname, 'dist/'), 30 | filename: 'bundle.js', 31 | }, 32 | devServer: { 33 | contentBase: path.join(__dirname, 'dist/'), 34 | port: 3000, 35 | hotOnly: true, 36 | }, 37 | plugins: [ 38 | new webpack.HotModuleReplacementPlugin(), 39 | new CleanWebpackPlugin(['dist']), 40 | new HtmlWebpackPlugin({ 41 | template: 'public/index.hbs', 42 | favicon: 'public/favicon.ico', 43 | }), 44 | new CopyWebpackPlugin([{ from: 'public/stranger-ipsum-title.png' }]), 45 | ], 46 | }; 47 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lorem-ipsum-generator", 3 | "version": "2.0.0", 4 | "description": "A lorem ipsum generator", 5 | "main": "app.js", 6 | "scripts": { 7 | "start": "webpack-dev-server --mode development", 8 | "build": "webpack --mode production" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/Engineering-Robert/lorem-ipsum-generator.git" 13 | }, 14 | "keywords": [ 15 | "lorem ipsum", 16 | "text", 17 | "random words" 18 | ], 19 | "author": "Robert Cooper", 20 | "license": "MIT", 21 | "bugs": { 22 | "url": "https://github.com/Engineering-Robert/lorem-ipsum-generator/issues" 23 | }, 24 | "homepage": "https://github.com/Engineering-Robert/lorem-ipsum-generator#readme", 25 | "dependencies": { 26 | "express": "^4.16.2", 27 | "react": "^16.6.0", 28 | "react-dom": "^16.6.0" 29 | }, 30 | "engines": { 31 | "node": "8.11.3" 32 | }, 33 | "devDependencies": { 34 | "@babel/cli": "7.1.0", 35 | "@babel/core": "7.1.0", 36 | "@babel/plugin-proposal-class-properties": "7.1.0", 37 | "@babel/preset-env": "7.1.0", 38 | "@babel/preset-react": "7.0.0", 39 | "babel-eslint": "^10.0.1", 40 | "babel-loader": "8.0.2", 41 | "clean-webpack-plugin": "^0.1.19", 42 | "copy-webpack-plugin": "^4.5.4", 43 | "css-loader": "1.0.0", 44 | "eslint": "^5.8.0", 45 | "eslint-plugin-babel": "^5.2.1", 46 | "handlebars": "^4.0.12", 47 | "handlebars-loader": "^1.7.0", 48 | "html-webpack-plugin": "^3.2.0", 49 | "style-loader": "0.23.0", 50 | "webpack": "4.19.1", 51 | "webpack-cli": "3.1.1", 52 | "webpack-dev-server": "3.1.8" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | @import url(https://fonts.googleapis.com/css?family=Poppins:400,700); 2 | @import url(https://fonts.googleapis.com/css?family=Open+Sans:300); 3 | @import url(https://necolas.github.io/normalize.css/3.0.2/normalize.css); 4 | 5 | body { 6 | color: #0D0630; 7 | background-color: #000; 8 | text-align: center; 9 | margin: 40px auto; 10 | max-width: 800px; 11 | padding: 0 40px; 12 | font: 16px 'Open Sans', sans-serif; 13 | } 14 | 15 | p { 16 | font-size: 20px; 17 | } 18 | 19 | form { 20 | margin-top: 25px; 21 | margin-bottom: 25px; 22 | } 23 | 24 | hr { 25 | border-color: #00171F; 26 | width: 400px; 27 | margin-bottom: 30px; 28 | } 29 | 30 | label { 31 | display: block; 32 | font-weight: bold; 33 | } 34 | 35 | input { 36 | font-size: 16px; 37 | padding: 5px; 38 | margin: 10px 0; 39 | text-align: center; 40 | border: 1px solid #fff; 41 | color: #2C3238; 42 | } 43 | 44 | input:focus { 45 | outline: none; 46 | } 47 | 48 | input[type=number]::-webkit-inner-spin-button, 49 | input[type=number]::-webkit-outer-spin-button { 50 | -webkit-appearance: none; 51 | margin: 0; 52 | } 53 | 54 | .video-container { 55 | position: absolute; 56 | left: 0; 57 | top: 0; 58 | width: 100%; 59 | height: 100vh; 60 | z-index: -1; 61 | } 62 | 63 | .video-background { 64 | position: fixed; 65 | top: 50%; 66 | left: 50%; 67 | min-width: 100%; 68 | min-height: 100%; 69 | width: auto; 70 | height: auto; 71 | transform: translate(-50%, -50%); 72 | } 73 | 74 | .main-content { 75 | z-index: 10; 76 | } 77 | 78 | .title-image { 79 | max-width: 100%; 80 | width: 500px; 81 | box-shadow: 0px 0px 40px 20px #000; 82 | margin-bottom: 20px; 83 | } 84 | 85 | .description { 86 | font-family: 'Poppins'; 87 | font-weight: 700; 88 | text-transform: uppercase; 89 | color: #fff; 90 | font-size: 16px; 91 | word-spacing: 3px; 92 | letter-spacing: 1px; 93 | } 94 | 95 | .paragraph-number { 96 | max-width: 80px; 97 | margin: 0; 98 | margin-right: 10px; 99 | padding-top: 6px; 100 | padding-bottom: 6px; 101 | height: 37px; 102 | transition: box-shadow 500ms; 103 | } 104 | 105 | .paragraph-number:focus { 106 | box-shadow: 0px 0px 50px 5px #f61b1b; 107 | } 108 | 109 | .generate-button, 110 | .copy-button { 111 | font-family: 'Poppins', Helvetica, serif; 112 | border-width: 0px; 113 | padding: 6px 12px; 114 | background-color: #f61b1b; 115 | color: #fff; 116 | transition: background-color 500ms, color 500ms, box-shadow 500ms; 117 | } 118 | 119 | .copy-button:hover { 120 | cursor: pointer; 121 | } 122 | 123 | .generate-button:hover, 124 | .copy-button:hover, 125 | .generate-button:focus, 126 | .copy-button:focus { 127 | background-color: #000; 128 | color: #f61b1b; 129 | box-shadow: 0px 0px 50px 5px #f61b1b; 130 | outline: none; 131 | } 132 | 133 | .copy-button { 134 | display: inline-block; 135 | text-decoration: none; 136 | margin-top: -20px; 137 | } 138 | 139 | .generated-text { 140 | padding: 20px; 141 | color: #313131; 142 | background-color: #fff; 143 | box-shadow: #fff 0px 0px 5px 4px; 144 | margin-top: 40px; 145 | margin-bottom: 40px; 146 | } 147 | 148 | .generated-text p { 149 | font-size: 16px; 150 | text-align: left; 151 | animation: fadein 2s; 152 | } 153 | 154 | .generated-text p:first-child { 155 | margin-top: 0; 156 | } 157 | 158 | .generated-text p:last-child { 159 | margin-bottom: 0; 160 | } 161 | 162 | @keyframes fadein { 163 | from { opacity: 0; } 164 | to { opacity: 1; } 165 | } 166 | 167 | #copyOverlay { 168 | position: fixed; 169 | top: 0; 170 | background: rgba(0, 0, 0, 0.8); 171 | width: 100vw; 172 | left: 0; 173 | height: 100vh; 174 | z-index: 100; 175 | transition: opacity 1.5s linear; 176 | } 177 | 178 | .modal--show { 179 | visibility: visible; 180 | opacity: 0; 181 | } 182 | 183 | .modal--hidden { 184 | visibility: hidden; 185 | opacity: 1; 186 | transition: visibility 0s 1.5s; 187 | } 188 | 189 | #copyText { 190 | margin-top: 40vh; 191 | } 192 | 193 | #copyText p { 194 | font-size: 30px; 195 | font-family: 'Poppins'; 196 | font-weight: bold; 197 | color: #fff; 198 | } 199 | 200 | .github-button-wrapper { 201 | display: block; 202 | margin-top: 2rem; 203 | } -------------------------------------------------------------------------------- /src/generator.js: -------------------------------------------------------------------------------- 1 | // Code that generators the random lorem ipsum text 2 | 3 | // Create a new object called loremIpsum by invoking the GenerateNewText constructor function 4 | export const loremIpsum = new GenerateNewText(); 5 | 6 | // Constructor function that creates an object with the words property 7 | function GenerateNewText() { 8 | // Add property to the object 9 | this.sentences = 10 | [ 11 | 'Friends don\'t lie.', 12 | 'It\'s just, sometimes... people don\'t really say what they\'re really thinking. But when you capture the right moment, it says more.', 13 | 'This is not yours to fix alone. You act like you’re all alone out there in the world, but you’re not. You’re not alone.', 14 | 'Why are you keeping this curiosity door lock?', 15 | 'Do you know anything about sensory deprivation tanks? Specifically how to build one?', 16 | 'If anyone asks where I am, I\'ve left the country.', 17 | 'YOU BETTER RUN! She\'s our friend, and she\'s crazy!', 18 | 'Mouth-breather.', 19 | 'Nancy, seriously, you\'re gonna be so cool now, it\'s ridiculous.', 20 | 'Um, I\'m happy you\'re home.', 21 | 'You’re going to take out the demigorgon with a slingshot?', 22 | 'Mornings are for coffee and contemplation.', 23 | 'You shouldn\'t like things because people tell you you\'re supposed to.', 24 | 'No... no El, you\'re not the monster. You saved me. Do you understand? You saved me.', 25 | 'We never would\'ve upset you if we knew you had superpowers.', 26 | 'Just wait till we tell Will that Jennifer Hayes was crying at his funeral.', 27 | 'You\'re an idiot, Steve Harrington. You\'re beautiful, Nancy Wheeler.', 28 | 'Oh... candy, leftovers, Eggo\'s... she really likes Eggo\'s.', 29 | 'Don’t take it so personally, okay? I don’t like most people. He’s in the vast majority.', 30 | 'Why do we even need weapons anyway? We have her.', 31 | 'She shut one door! With her mind!', 32 | 'He’s a sensitive kid. Lonnie used to say he was queer. Called him a fag. Is he? He’s missing, is what he is!', 33 | 'Yeah, I want a date with Bo Derek. We all want things.', 34 | 'It’s finger-lickin’ good.', 35 | 'You’re going to be home by 8, listening to the Talking Heads and reading Vonnegut or something. That sounds like a nice night.', 36 | 'You’re right. You are a freak…. Who would you rather be friends with: Bowie or Kenny Rogers?', 37 | 'Nobody normal ever accomplished anything meaningful in this world.', 38 | 'You are such a nerd. No wonder you only hang out with boys.', 39 | 'If we’re both going crazy, then we’ll go crazy together, right?', 40 | 'You’re pretty cute, you know that?', 'I need my paddles!', 'Why’s he gotta kick the door?', 'Hey kiddo, would you like a balloon?', 'Mistakes have been made.', 'Let’s burn that lab to the ground.', 'You act like you want me to be your friend and then you treat me like garbage.', 'It’s about the shadow monster, isn’t it?', 41 | 'So, Jonathan, how was the pull-out?', 42 | 'Bitchin\'' 43 | ]; 44 | } 45 | 46 | // Method to the GenerateNewText constructor function that generates a random sentence 47 | GenerateNewText.prototype.getRandomSentence = function() { 48 | let randomSentence = this.sentences[Math.floor(Math.random() * this.sentences.length)]; 49 | return randomSentence; 50 | }; 51 | 52 | // Method to the GenerateNewText constructor function that generates a paragraph from random sentences 53 | GenerateNewText.prototype.getParagraph = function() { 54 | let paragraph = ''; 55 | // Set the minimum number of words 56 | let minimumCharacterLength = 250; 57 | let firstSentence = true; 58 | while (paragraph.length < minimumCharacterLength) { 59 | if (firstSentence) { 60 | paragraph = paragraph.concat(this.getRandomSentence()); 61 | firstSentence = false; 62 | } else { 63 | paragraph = paragraph.concat(' ' + this.getRandomSentence()); 64 | } 65 | } 66 | return paragraph; 67 | }; 68 | 69 | // Method to the GenerateNewText constructor function that gerates multiple paragraphs from paragraphs 70 | GenerateNewText.prototype.getAllParagraphs = function(numberOfParagraphs) { 71 | let allParagraphs = []; 72 | // Generate the number of paragraphs as specified by the user 73 | while (allParagraphs.length < numberOfParagraphs) { 74 | allParagraphs.push(this.getParagraph()); 75 | } 76 | // Convert array into HTML string 77 | let paragraphHTML = ''; 78 | allParagraphs.forEach(function (paragraph) { 79 | paragraphHTML += '

' + paragraph + '

'; 80 | }); 81 | return paragraphHTML; 82 | }; 83 | -------------------------------------------------------------------------------- /src/App.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { loremIpsum } from './generator'; 3 | import './App.css'; 4 | 5 | class App extends Component { 6 | state = { 7 | showCopyModal: false, 8 | numberOfParagraphs: '', 9 | text: '', 10 | }; 11 | 12 | handleSubmit = e => { 13 | e.preventDefault(); 14 | const numberOfParagraphs = parseFloat(this.state.numberOfParagraphs); 15 | const HTMLParagraphs = loremIpsum.getAllParagraphs(numberOfParagraphs); 16 | this.setState({ text: HTMLParagraphs }); 17 | }; 18 | handleCopy = () => { 19 | const el = document.createElement('textarea'); // Create a