diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 000000000..328e6612c Binary files /dev/null and b/.DS_Store differ diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..6f3c990b6 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "chrome", + "request": "launch", + "name": "Launch Chrome against localhost", + "url": "http://localhost:8080", + "webRoot": "${workspaceFolder}" + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..aef844305 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "liveServer.settings.port": 5501 +} \ No newline at end of file diff --git a/README.md b/README.md index 6de202be2..87ce572c3 100644 --- a/README.md +++ b/README.md @@ -1,46 +1,23 @@ -# Hang In There - -A boilerplate repo. - -## Set Up - -1. Fork this repository -2. Clone down your new, forked repo -3. `cd` into the repository -4. Open it in your text editor -5. Add your project manager as a collaborator on the repository - -Project spec & rubric can be found [here](https://curriculum.turing.edu/module2/projects/hang-in-there/index) - -To view your project: - -1. In your terminal, navigate to your project repo -2. Run the command `open index.html` - -______________________________________________________ -# README Template -Before turning this project in, erase this line and everything above it and fill in the info below. -______________________________________________________ - # Hang in There ### Abstract: -[//]: <> (Briefly describe what you built and its features. What problem is the app solving? How does this application solve that problem?) - +[/x/]: <> (Briefly describe what you built and its features. What problem is the app solving? How does this application solve that problem?) +Here we have a wonderful application devoted to providing its users with a randomized source of motivation and inspiration. From the homepage our users can choose to create random motivational posters that pull from a curated collection of images, titles, and quotes to build an image that is sure to brighten your day(or at least make you laugh). You can also create your own custom posters using whatever image and text you can come up with. The sky is the limit! Whenever you either stumble across a randomly generated poster that really speaks to you, or you create a poster that you are especially proud of, you can save the poster and return to it later in our Saved Posters gallery. But that's not all! For those who are less inclined towards positivity, we also provide our users with a gallery filled with Anti-Motivational to peruse at their whim. Are you in the mood to destroy some negativity? Well then wait until you hear this, when a user double clicks on one of our Anti-Motivational Posters, it will disapear forever (or at least until you completely reload the page)! ### Installation Instructions: -[//]: <> (What steps does a person have to take to get your app cloned down and running?) - +[/x/]: <> (What steps does a person have to take to get your app cloned down and running?) +To access this application, please clone down a copy from this [GitHub repository](https://github.com/SmilodonP/hanging-in-there). Once that is complete, from your terminal, cd into the project file and enter "code ." into your terminal. This will open the project in your VSCode. From here simply right click on the "index.html" file and select "Open With Live Server". This should open the application in a new browser window where you can interact with it to your heart's content. If you do not have the Live Server VSCode extension installed, you can use the alternative method of navigating to the "Run" column at the top of the page and clicking "Run Without Debugging". ### Preview of App: [//]: <> (Provide ONE gif or screenshot of your application - choose the "coolest" piece of functionality to show off. gifs preferred!) - +![Karl's app gif](./assets/app.gif) ### Context: [//]: <> (Give some context for the project here. How long did you have to work on it? How far into the Turing program are you?) - +This was our first project in the second module of The Turing School of Software & Design's fullstack software engineering program, and the first front end project that we have been assigned. We were given 10 days to complete the project. ### Contributors: [//]: <> (Who worked on this application? Link to your GitHub. Consider also providing LinkedIn link) - +I worked on this project by myself. My name is Karl. [Github](https://github.com/SmilodonP) | [LinkedIn](https://www.linkedin.com/in/karlfallenius/) ### Learning Goals: [//]: <> (What were the learning goals of this project? What tech did you work with?) - +This was a brown field project that tested and grew our ability to read, understand, and work with code that was already written by someone else, and then to extrapolate upon the given code, establishing and expanding its functionality. We worked with JavaScript, HTML, & CSS. ### Wins + Challenges: [//]: <> (What are 2-3 wins you have from this project? What were some challenges you faced - and how did you get over them?) +This was by far my most successful project at Turing to date. This feels extra special as I am brand new to working with these languages. I am really proud of everything I accomplished with this project. \ No newline at end of file diff --git a/assets/app.gif b/assets/app.gif new file mode 100644 index 000000000..2c6a172bb Binary files /dev/null and b/assets/app.gif differ diff --git a/index.html b/index.html index ca0707621..0a51068f2 100644 --- a/index.html +++ b/index.html @@ -18,6 +18,7 @@

Quote

+ + \ No newline at end of file diff --git a/src/main.js b/src/main.js index d818a0ab6..9da260ff9 100644 --- a/src/main.js +++ b/src/main.js @@ -1,7 +1,7 @@ -// query selector variables go here 👇 +var posterImage = document.querySelector('.poster-img'); +var posterTitle = document.querySelector('.poster-title'); +var posterQuote = document.querySelector('.poster-quote'); -// we've provided you with some data to work with 👇 -// tip: you can tuck this data out of view with the dropdown found near the line number where the variable is declared var images = [ "./assets/bees.jpg", "./assets/bridge.jpg", @@ -60,52 +60,195 @@ var titles = [ "wisdom" ]; var quotes = [ - "Don’t downgrade your dream just to fit your reality, upgrade your conviction to match your destiny.", - "You are braver than you believe, stronger than you seem and smarter than you think.", - "You are confined only by the walls you build yourself.", - "The one who has confidence gains the confidence of others.", - "Act as if what you do makes a difference. It does.", - "Success is not final, failure is not fatal: it is the courage to continue that counts.", - "Never bend your head. Always hold it high. Look the world straight in the eye.", - "What you get by achieving your goals is not as important as what you become by achieving your goals.", - "Believe you can and you're halfway there.", - "When you have a dream, you've got to grab it and never let go.", - "I can't change the direction of the wind, but I can adjust my sails to always reach my destination.", - "No matter what you're going through, there's a light at the end of the tunnel.", - "It is our attitude at the beginning of a difficult task which, more than anything else, will affect its successful outcome.", - "Life is like riding a bicycle. To keep your balance, you must keep moving.", - "Just don't give up trying to do what you really want to do. Where there is love and inspiration, I don't think you can go wrong.", - 'Limit your "always" and your "nevers."', - "You are never too old to set another goal or to dream a new dream.", - "Try to be a rainbow in someone else's cloud.", - "You do not find the happy life. You make it.", - "Inspiration comes from within yourself. One has to be positive. When you're positive, good things happen.", - "Sometimes you will never know the value of a moment, until it becomes a memory.", - "The most wasted of days is one without laughter.", - "You must do the things you think you cannot do.", - "It isn't where you came from. It's where you're going that counts.", - "It is never too late to be what you might have been.", - "Happiness often sneaks in through a door you didn't know you left open.", - "We must be willing to let go of the life we planned so as to have the life that is waiting for us.", - "Never limit yourself because of others’ limited imagination; never limit others because of your own limited imagination.", - "Be the change that you wish to see in the world.", - "Let us make our future now, and let us make our dreams tomorrow's reality.", - "You don't always need a plan. Sometimes you just need to breathe, trust, let go, and see what happens.", - "If I cannot do great things, I can do small things in a great way.", - "Don't wait. The time will never be just right.", - "With the right kind of coaching and determination you can accomplish anything.", - "If you have good thoughts they will shine out of your face like sunbeams and you will always look lovely.", - "No matter what people tell you, words and ideas can change the world.", - "Each person must live their life as a model for others.", - "A champion is defined not by their wins but by how they can recover when they fall." + "Don't wait until it's urgent. Just go pee. Minimize your potential for bladder stones.", + "Don’t downgrade your ego to fit your reality, upgrade your imagination to match your ego.", + "You are braver than you believe, stronger than you seem, and smarter than you think. So, stop acting cowardly, weak, and stupid.", + "We forge the chains we wear in life.", + "Those confident ones, whose confidence is unwaivering, gain the confidence of others by being so dang confident.", + "Act as if what you do makes a difference. Even if it doesn't.", + "Success is not success, failure is not failure: everything is relative.", + "Never bend your head. Always hold it high. Look the world straight in the eye and headbutt it right in the nose.", + "What you get by achieving your goals is not as important as what you become by achieving your goals. - The Unibomber", + "Believe you can and you're halfway there. - John Wayne Gacy", + "When you have a dream, you've got to grab it by the throat and never let it go. That's how you kill your sleep paralysis demon.", + "I can't change the direction of the wind, but I can make my own wind with my butt.", + "No matter what you're going through, there's a light at the end of the tunnel. Do not go towards the light.", + "It is your appetite at the beginning of a difficult task which, more than anything else, will affect your appetite at the outcome.", + "Life is like riding a bicycle. Your butt will hurt and you wil sweat a lot.", + "Just don't give up trying to do what you really want to do. Where there is love and inspiration, I don't think you can go wrong. -Charles Manson", + "Limit your intake of saturated fats, sodium, and refined sugars.", + "You are never too old to set another goal or to dream a new dream. - Sam Little ", + "Try to be a rainbow in the dark.", + "You do not find the happy life. It finds you...", + "Inspiration comes from within your imagination. One has to be vigilant in their positivity. When you're aggressively positive, good things might happen sometimes... maybe.", + "You will never know the value of a moment, until it becomes a memory. - Hannibal Lecter", + "The most wasted of days are those spent without doing crimes.", + "You must do the things. You must.", + "It isn't when you came from. It's the how and the why.", + "It is never too late to try eating an entire ham.", + "Happiness often sneaks in through a door you didn't know you left open. Then, Happiness robs your house. Don't forget to close and lock your doors. Happiness needs money to buy drugs.", + "We must be willing to let go of the life we planned so as to have space for the life that is waiting for us. Keep your expectations low and you'll rarely be disappointed.", + "Never limit yourself because of others’ limited imagination; never limit others because of your own limited imagination. Imagine all of the imaginations and all of imagining that they could imagine. Just imagine it.", + "Be the food that you wish to taste in the world.", + "Let us make our future our past, and let us make our dreams tomorrow's nightmare.", + "You don't always need to go to the bathroom. Sometimes you just need to breathe, trust, let go, and see what happens.", + "If I cannot do things, I can maybe do other things instead.", + "Don't wait! Call now to start saving money today!", + "With the right kind of coaching, determination, and networking skills you potentially might be able to accomplish something someday.", + "If you have good thoughts they will shine out of your eyes like sunbeams and and burn evil to a crispy bacon like texture.", + "No matter what people tell you, words and ideas can't change the world as much as money and blackmail.", + "Each person must live their life as a model for an art class.", + "A champion is defined not by their wins but by their losses." ]; +const unmotivationalPosters = [ + { + name: "FAILURE", + description: "Why bother trying? It's probably not worth it.", + price: 68.00, + year: 2019, + vintage: true, + img_url: "./assets/failure.jpg", + }, + { + name: "MEDIOCRITY", + description: "Dreams are just that—dreams.", + price: 127.00, + year: 2021, + vintage: false, + img_url: "./assets/mediocrity.jpg", + }, + { + name: "REGRET", + description: "Hard work rarely pays off.", + price: 89.00, + year: 2018, + vintage: true, + img_url: "./assets/regret.jpg", + }, + { + name: "FUTILITY", + description: "You're not good enough.", + price: 150.00, + year: 2016, + vintage: false, + img_url: "./assets/futility.jpg", + }, + { + name: "DEFEAT", + description: "It's too late to start now.", + price: 35.00, + year: 2023, + vintage: false, + img_url: "./assets/defeat.jpg", + }, + { + name: "HOPELESSNESS", + description: "Stay in your comfort zone; it's safer.", + price: 112.00, + year: 2020, + vintage: true, + img_url: "./assets/hopelessness.jpg", + }, + { + name: "LAZINESS", + description: "You can't change anything.", + price: 25.00, + year: 2022, + vintage: false, + img_url: "./assets/laziness.jpg", + }, + { + name: "PROCRASTINATION", + description: "Better to avoid failure by not trying at all.", + price: 48.00, + year: 2017, + vintage: true, + img_url: "./assets/procrastination.jpg", + }, + { + name: "DESPAIR", + description: "Let someone else do it; you’ll just mess it up.", + price: 73.00, + year: 2015, + vintage: false, + img_url: "./assets/despair.jpg", + }, + { + name: "NEGLECT", + description: "Happiness is overrated.", + price: 160.00, + year: 2019, + vintage: true, + img_url: "./assets/neglect.jpg", + }, + { + name: "FEAR", + description: "Giving up is always an option.", + price: 91.00, + year: 2014, + vintage: false, + img_url: "./assets/fear.jpg", + }, + { + name: "APATHY", + description: "No one cares about your effort.", + price: 110.00, + year: 2016, + vintage: true, + img_url: "./assets/apathy.jpg", + }, + { + name: "MISERY", + description: "Why take risks when you can stay stagnant?", + price: 55.00, + year: 2021, + vintage: false, + img_url: "./assets/misery.jpg", + }, + { + name: "BLAME", + description: "Expect disappointment and you'll never be disappointed.", + price: 39.00, + year: 2017, + vintage: true, + img_url: "./assets/blame.jpg", + }, + { + name: "DOUBT", + description: "Success is for other people, not you.", + price: 140.00, + year: 2020, + vintage: false, + img_url: "./assets/doubt.jpg", + } +]; + var savedPosters = []; -var currentPoster; +var currentPoster = null; +var currentUnmotivationalPosters = [...unmotivationalPosters]; -// event listeners go here 👇 +document.querySelector('.show-random').addEventListener('click', createRandomPoster); +document.querySelector('.show-form').addEventListener('click', toggleCreateNew); +document.querySelector('.show-main').addEventListener('click', toggleCreateNew); +document.querySelector('.show-saved').addEventListener('click', toggleShowSaved); +document.querySelector('.back-to-main').addEventListener('click', toggleShowSaved); +document.querySelector('.save-poster').addEventListener('click', savePoster); +document.querySelector('.make-poster').addEventListener('click', function(event) { + createCustomPoster(event); + toggleCreateNew(); +}); +document.querySelector('.show-unmotivational').addEventListener('click', toggleShowUnmotivational); +document.querySelector('.hide-unmotivational').addEventListener('click', toggleShowUnmotivational); +document.querySelector('.unmotivational-posters-grid').addEventListener('dblclick', function(event) { + let target = event.target; + while (target && !target.classList.contains('unmotivational-poster')) { + target = target.parentElement; + } + if (target) { + deletePoster(target); + } +}); -// functions and event handlers go here 👇 -// (we've provided two to get you started)! function getRandomIndex(array) { return Math.floor(Math.random() * array.length); } @@ -115,5 +258,160 @@ function createPoster(imageURL, title, quote) { id: Date.now(), imageURL: imageURL, title: title, - quote: quote} -} \ No newline at end of file + quote: quote + }; +} + +function createRandomPoster() { + const randomImage = images[getRandomIndex(images)]; + const randomTitle = titles[getRandomIndex(titles)]; + const randomQuote = quotes[getRandomIndex(quotes)]; + + currentPoster = updatePosterContent(randomImage, randomTitle, randomQuote); +} + +function createCustomPoster (event) { + event.preventDefault(); + + const newImage = document.querySelector('#poster-image-url').value; + const newTitle = document.querySelector('#poster-title').value; + const newQuote = document.querySelector('#poster-quote').value; + + saveInputData(newImage, newTitle, newQuote); + + currentPoster = updatePosterContent(newImage, newTitle, newQuote); +} + +function saveInputData(imageURL, title, quote){ + images.push(imageURL); + titles.push(title); + quotes.push(quote); +} + +function updatePosterContent(imageURL, title, quote) { + + posterImage.src = imageURL; + posterTitle.innerText = title; + posterQuote.innerText = quote; + + return createPoster(imageURL, title, quote); +} + +function savePoster() { + if (currentPoster && !savedPosters.some(poster => poster.id === currentPoster.id)) { + alert("Your Poster Has Successfully Been Saved") + savedPosters.push(currentPoster); + } + else + alert("Duplicate Posters WILL NOT Be Saved") +} + +function displaySavedPosters() { + const savedPostersGrid = document.querySelector('.saved-posters-grid'); + savedPostersGrid.innerHTML = ''; +// look into how I would refactor this method using string interpolation + savedPosters.forEach(poster => { + let miniaturePoster = document.createElement('div'); + miniaturePoster.classList.add('mini-poster'); + + let miniImage = document.createElement('img'); + miniImage.src = poster.imageURL; + miniImage.alt = 'Miniature Poster Image' + miniaturePoster.appendChild(miniImage); + + let miniTitle = document.createElement('h2'); + miniTitle.innerText = poster.title; + miniaturePoster.appendChild(miniTitle); + + let miniQuote = document.createElement('h4'); + miniQuote.innerText = poster.quote; + miniaturePoster.appendChild(miniQuote); + + savedPostersGrid.appendChild(miniaturePoster); + }); +} + +function loadUnmotivationalPosters() { + const unmotivationalPostersGrid = document.querySelector('.unmotivational-posters-grid'); + unmotivationalPostersGrid.innerHTML = ''; + + currentUnmotivationalPosters.forEach(poster => { + const posterElements = cleanData(poster); + unmotivationalPostersGrid.appendChild(posterElements); + }); +} + +function cleanData(poster) { + let unmotivationalPoster = document.createElement('div'); + unmotivationalPoster.classList.add('unmotivational-poster'); + + let unmotivationalImage = document.createElement('img'); + unmotivationalImage.src = poster.img_url; + unmotivationalImage.alt = 'Anti-Motivational Poster Image' + unmotivationalPoster.appendChild(unmotivationalImage); + + let unmotivationalTitle = document.createElement('h2'); + unmotivationalTitle.innerText = poster.name; + unmotivationalPoster.appendChild(unmotivationalTitle); + + let unmotivationalQuote = document.createElement('h4'); + unmotivationalQuote.innerText = poster.description; + unmotivationalPoster.appendChild(unmotivationalQuote); + + return unmotivationalPoster; +} + +function deletePoster(poster){ + if (confirm("Confirm Delete Poster") == true) { + poster.classList.add('zoom-out'); + poster.addEventListener('animationend', function() { + const posterIndex = Array.from(poster.parentNode.children).indexOf(poster); + poster.remove(true); + currentUnmotivationalPosters.splice(posterIndex, 1); + } + ,{ once: true }); + } +} + +function toggleCreateNew() { + // add clear all input fields and repopulate placeholders functionality + document.querySelector('.main-poster').classList.toggle('hidden'); + document.querySelector('.poster-form').classList.toggle('hidden'); +} + +function toggleShowSaved() { + displaySavedPosters(); + document.querySelector('.main-poster').classList.toggle('hidden'); + document.querySelector('.saved-posters').classList.toggle('hidden'); +} + +function toggleShowUnmotivational() { + loadUnmotivationalPosters(); + document.querySelector('.main-poster').classList.toggle('hidden'); + document.querySelector('.unmotivational-posters').classList.toggle('hidden'); +} + +// This is how I first handled the various view changing button functionalities: + +// function toggleDisplay(selectors) { +// selectors.forEach(selector => { +// let element = document.querySelector(selector); +// element.style.display = window.getComputedStyle(element).display === "none" ? "block" : "none"; +// }); +// } + +// function toggleCreateNew() { +// toggleDisplay(['.main-poster', '.poster-form']); +// } + +// function toggleShowSaved() { +// displaySavedPosters(); +// toggleDisplay(['.main-poster', '.saved-posters']); +// } + +// function toggleShowUnmotivational() { +// loadUnmotivationalPosters(); +// toggleDisplay(['.main-poster', '.unmotivational-posters']); +//} + +window.onload = createRandomPoster; \ No newline at end of file diff --git a/styles.css b/styles.css index 0402eaee9..99feb635f 100644 --- a/styles.css +++ b/styles.css @@ -30,7 +30,7 @@ button:hover { } .hidden { - display: none!important; + display: none } /* ~~~~~ MAIN POSTER SECTION ~~~~~ */ @@ -56,13 +56,14 @@ button:hover { .poster-title, .poster-quote { + font-size: 20px; color: white; line-height: 1; width: 90%; } .poster-title { - font-size: 60px; + font-size: 40px; font-weight: normal; letter-spacing: 20px; margin-bottom: 10px; @@ -74,7 +75,7 @@ button:hover { } /* ~~~~~ POSTER FORM SECTION ~~~~~ */ -.poster-form { +.poster-form hidden { display: flex; flex-direction: column; height: 100vh; @@ -105,7 +106,7 @@ button:hover { } /* ~~~~~ SAVED POSTER SECTION ~~~~~ */ -.saved-posters { +.saved-posters hidden{ padding: 40px; } @@ -144,3 +145,72 @@ button:hover { margin-bottom: 10px; text-transform: uppercase; } + +/* ~~~~~ ANTI-MOTIVATIONAL POSTER SECTION ~~~~~ */ +.unmotivational-posters hidden{ + padding: 40px; +} + +.unmotivational-posters-grid { + display: flex; + flex-wrap: wrap; + justify-content: space-evenly; + padding: 20px; +} + +.unmotivational-poster { + display: block; + cursor: pointer; + background: rgb(135, 135, 135); + flex: 0 1 calc(33.33% - 20px); + margin: 5px; + box-sizing: border-box; + color: white; + border-radius: 2%; + text-align: center; + padding: 25px; + height: 340px; + width: 425px; +} + +.unmotivational-poster.zoom { + animation: zoom forwards 0.7s ease-out 1; +} + +.unmotivational-poster img { + height:200px; + width: 300px; +} + +.unmotivational-poster h2, +.unmotivational-poster h4, +.delete { + color: white; + line-height: 1; + width: 90%; +} + +.unmotivational-poster h2 { + color: black; + font-size: 30px; + font-weight: normal; + letter-spacing: 5px; + margin-bottom: 10px; + text-transform: uppercase; +} + + +@keyframes zoomOut { + 0% { + transform: scale(1); + opacity: 1; + } + 100% { + transform: scale(0); + opacity: 0; + } +} + +.zoom-out { + animation: zoomOut 0.33s ease-out forwards; +} \ No newline at end of file