From db5b7f8b0f119800e7da2aa4691a875f96904987 Mon Sep 17 00:00:00 2001 From: Ajita369 <162597493+Ajita369@users.noreply.github.com> Date: Fri, 28 Jun 2024 17:54:24 +0530 Subject: [PATCH] Added GIF search app --- .../Basic/GIF Search App/README.md | 27 +++++ .../Basic/GIF Search App/api-key.js | 2 + .../Basic/GIF Search App/index.html | 31 ++++++ .../Basic/GIF Search App/manifest.json | 19 ++++ .../Basic/GIF Search App/script.js | 73 ++++++++++++ .../Basic/GIF Search App/style.css | 104 ++++++++++++++++++ 6 files changed, 256 insertions(+) create mode 100644 Web Development/Basic/GIF Search App/README.md create mode 100644 Web Development/Basic/GIF Search App/api-key.js create mode 100644 Web Development/Basic/GIF Search App/index.html create mode 100644 Web Development/Basic/GIF Search App/manifest.json create mode 100644 Web Development/Basic/GIF Search App/script.js create mode 100644 Web Development/Basic/GIF Search App/style.css diff --git a/Web Development/Basic/GIF Search App/README.md b/Web Development/Basic/GIF Search App/README.md new file mode 100644 index 000000000..cb18b7d3b --- /dev/null +++ b/Web Development/Basic/GIF Search App/README.md @@ -0,0 +1,27 @@ +# GIF Search App + +This app will generate the Gif's of the category which user wants. + +## Features + +- This will provide 10 gifs based on the search. +- The user can copy link of gif , then can open link on another page and download it. + +## Setup + +Open `index.html` in your preferred web browser. + +## How to Use + +You can type the category of gif you need in the search box like laugh,dancing,smirk and others. + +## Project Structure + +- `index.html`: The HTML file containing the structure of the website. +- `styles.css`: The CSS file for styling the website. +- `script.js`: The JavaScript file for functionality of website +- `README.md`: The readme file you are currently reading. + +## Credits + +This was created by Ajita Gupta [github - @Ajita369] as a simple project. \ No newline at end of file diff --git a/Web Development/Basic/GIF Search App/api-key.js b/Web Development/Basic/GIF Search App/api-key.js new file mode 100644 index 000000000..96218281d --- /dev/null +++ b/Web Development/Basic/GIF Search App/api-key.js @@ -0,0 +1,2 @@ +//Paste the generated API Key here +let apiKey = "SF1FriVApRyR6efDmPYYdzbUK6dhVlOf"; \ No newline at end of file diff --git a/Web Development/Basic/GIF Search App/index.html b/Web Development/Basic/GIF Search App/index.html new file mode 100644 index 000000000..c438fd3ab --- /dev/null +++ b/Web Development/Basic/GIF Search App/index.html @@ -0,0 +1,31 @@ + + + + + Gif Search App + + + + + + +
+

GIF SEARCH APP

+
+
+
+ + +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/Web Development/Basic/GIF Search App/manifest.json b/Web Development/Basic/GIF Search App/manifest.json new file mode 100644 index 000000000..13aa164e0 --- /dev/null +++ b/Web Development/Basic/GIF Search App/manifest.json @@ -0,0 +1,19 @@ +{ + "manifest_version": 3, + "name": "GIF Search App", + "version": "1.0", + "description": "Can generate the gif you want", + "action": { + "default_popup": "index.html" + }, + "web_accessible_resources": [ + { + "resources": [ + "index.html" + ], + "matches": [ + "" + ] + } + ] +} \ No newline at end of file diff --git a/Web Development/Basic/GIF Search App/script.js b/Web Development/Basic/GIF Search App/script.js new file mode 100644 index 000000000..d7580c738 --- /dev/null +++ b/Web Development/Basic/GIF Search App/script.js @@ -0,0 +1,73 @@ +let submitBtn = document.getElementById("submit-btn"); + +let generateGif = () => { + //display loader until gif load + let loader = document.querySelector(".loader"); + loader.style.display = "block"; + document.querySelector(".wrapper").style.display = "none"; + + //Get search value (default => laugh) + let q = document.getElementById("search-box").value; + let gifCount = 10; + //API URL + let finalURL = `https://api.giphy.com/v1/gifs/search?api_key=${apiKey}&q=${q}&limit=${gifCount}&offset=0&rating=g&lang=en`; + document.querySelector(".wrapper").innerHTML = ""; + + //Make a call to API + fetch(finalURL) + .then((resp) => resp.json()) + .then((info) => { + console.log(info.data); + //All gifs + let gifsData = info.data; + gifsData.forEach((gif) => { + //Generate cards for every gif + let container = document.createElement("div"); + container.classList.add("container"); + let iframe = document.createElement("img"); + console.log(gif); + iframe.setAttribute("src", gif.images.downsized_medium.url); + iframe.onload = () => { + //if iframes has loaded correctly reduce the count when each gif loads + gifCount--; + if (gifCount == 0) { + //If all gifs have loaded then hide loader and display gifs UI + loader.style.display = "none"; + document.querySelector(".wrapper").style.display = "grid"; + } + }; + container.append(iframe); + + //Copy link button + let copyBtn = document.createElement("button"); + copyBtn.innerText = "Copy Link"; + copyBtn.onclick = () => { + let copyLink = `https://media4.giphy.com/media/${gif.id}/giphy.mp4`; + navigator.clipboard + .writeText(copyLink) + .then(() => { + alert("GIF copied to clipboard"); + }) + .catch(() => { + alert("GIF copied to clipboard"); + let hiddenInput = document.createElement("input"); + hiddenInput.setAttribute("type", "text"); + document.body.appendChild(hiddenInput); + hiddenInput.value = copyLink; + //Select input + hiddenInput.select(); + //Copy the value + document.execCommand("copy"); + //remove the input + document.body.removeChild(hiddenInput); + }); + }; + container.append(copyBtn); + document.querySelector(".wrapper").append(container); + }); + }); +}; + +//Generate Gifs on screen load or when user clicks on submit +submitBtn.addEventListener("click", generateGif); +window.addEventListener("load", generateGif); \ No newline at end of file diff --git a/Web Development/Basic/GIF Search App/style.css b/Web Development/Basic/GIF Search App/style.css new file mode 100644 index 000000000..e3781d0c2 --- /dev/null +++ b/Web Development/Basic/GIF Search App/style.css @@ -0,0 +1,104 @@ +* { + padding: 0; + margin: 0; + box-sizing: border-box; + font-family: "Poppins", sans-serif; + } + body { + background-image: linear-gradient(to right,rgb(253, 123, 214), rgb(111, 22, 129)); + } + header{ + background-color: #271d61; + text-align: center; + height: 7.5rem; + padding: 1rem; + margin-bottom: 2rem; + font-size: 2rem; + color: #eff0f7; + text-shadow: 5px 5px rgb(156, 144, 144); + } + button { + border: none; + outline: none; + cursor: pointer; + background-color: #573e68; + color: #eff0f7; + border-radius: 0.5em; + font-size: 1.5rem; + font-weight: 500; + } + button:hover{ + background-color: #3d6dd4 ; + color: aliceblue; + } + .search-container { + display: grid; + grid-template-columns: 9fr 3fr; + gap: 1em; + width: 100%; + max-width: 50em; + margin: 1em auto; + padding: 0.1em; + } + .search-container input { + padding: 0.5em; + border-radius: 0.5em; + font-size: 1.5rem; + font-weight: 400; + } + .wrapper { + display: grid; + grid-template-columns: repeat(3, 1fr); + } + .container { + background-color: #2b304d; + display: flex; + padding: 1em; + flex-direction: column; + justify-content: space-between; + margin: 1.5em; + border-radius: 0.5em; + box-shadow: 15px 8px 8px #353a53; + } + .container:hover{ + background-color: #1c286d; + } + .container img { + width: 100%; + } + .container button { + margin-top: 1em; + padding: 1em 0; + } + .loader { + display: none; + height: 15em; + width: 15em; + border: 3em solid #2b304d; + border-radius: 50%; + border-top-color: #fc23cd;; + position: absolute; + transform: translate(-50%, -50%); + left: 50%; + top: 50%; + animation: spin 3s infinite; + } + + @keyframes spin { + 100% { + transform: translate(-50%, -50%) rotate(360deg); + } + } + @media screen and (max-width: 768px) { + .wrapper { + grid-template-columns: repeat(2, 1fr); + } + .container { + margin: 0.7em; + } + } + @media screen and (max-width: 576px) { + .wrapper { + grid-template-columns: 1fr; + } + } \ No newline at end of file