Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 72 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,72 @@
# 📊 Project: Complex API 2

### Goal: Use data returned from one api to make a request to another api and display the data returned

### How to submit your code for review:

- Fork and clone this repo
- Create a new branch called answer
- Checkout answer branch
- Push to your fork
- Issue a pull request
- Your pull request description should contain the following:
- (1 to 5 no 3) I completed the challenge
- (1 to 5 no 3) I feel good about my code
- Anything specific on which you want feedback!

Example:
```
I completed the challenge: 5
I feel good about my code: 4
I'm not sure if my constructors are setup cleanly...
```
# 🌀📚 Word to GIF Translator

Turn your words into art! Type in any word in English to hear it spoken aloud, read its definition, and instantly see a GIF that brings it to life.

---

## ✨ Features
- 🔈 Hear pronunciation played automatically (no controls shown)
- 📖 Fetch real definitions and examples from a dictionary API
- 🎞️ Dynamic GIF generation that visually represents your word
- 🪄 Minimalist UI with a quirky dictionary aesthetic
- 🖤 Responsive design for desktop and mobile
---

## 🛠️ Built With
- **HTML5** – structure
- **CSS3** – animations, gradients, responsive design
- **JavaScript** – fetches from both Dictionary & Giphy APIs dynamically

---

## 🎯 How to Use
1. Open the app in your browser
2. Type a word into the input
3. Click "gif me!!"
4. Listen, learn, and see your word come alive! 🎧🌀

---

## 📦 Installation & Setup
1. Clone this repository:

```bash
git clone https://github.com/your-username/complex-api2.git
```

2. Navigate into the project folder:

```bash
cd complex-api2
```

3. Open index.html in your browser.


4. You’re ready to play with words!

---

## 📸 Screenshots

<div align = "center"> <img width="738" height="866" alt="pineapple-screenshot" src="https://github.com/user-attachments/assets/3b4f91ee-3c0b-4419-bd08-4879bf84b277" /> </div>

---

<div align = "center"> <img width="750" height="854" alt="party-screenshot" src="https://github.com/user-attachments/assets/ed4f303a-d72e-43d7-8d54-4c726cdd7131" /> </div>

---

## 🤝 Contributing

Contributions are welcome!

If you’d like to add new features (e.g., alternate dictionary sources, custom GIF filters, etc.), feel free to fork the repo and submit a pull request.

---

## 🙌🏽 Acknowledgments
- 🧠 Dictionary API: https://dictionaryapi.dev
- 🎞️ Giphy API: https://developers.giphy.com
- 🎨 Inspired by Gen-Z chaos, random words, and internet culture

30 changes: 30 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="description" content="This is where your description goes" />
<meta name="keywords" content="one, two, three" />

<title>Word to Speech/Gif App</title>

<!-- external CSS link -->
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<h1>Visualize my word into...</h1>

<input id="word" type="text" value="" placeholder="type in word" />

<button>gif me!!</button>

<!-- show in the h2 the word -->
<h2></h2>
<!-- play the audio -->
<h3></h3>

<!-- show gifs here -->
<p></p>

<script src="main.js"></script>
</body>
</html>
87 changes: 87 additions & 0 deletions main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
document.querySelector("button").addEventListener("click", convertWordToAudio);

function convertWordToAudio() {
const word = document.getElementById("word").value;

//dictionary api website https://dictionaryapi.dev/

const url = `https://api.dictionaryapi.dev/api/v2/entries/en/${word}`;

fetch(url)
.then((res) => res.json())

.then((data) => {
console.log("dictionary sends info", data);

console.log("show me the data", data);

// document.querySelector("h2").innerText = data[0].phonetic;
document.querySelector(
"h2"
).innerText = ` (${data[0].meanings[0].partOfSpeech}) Definition: ${data[0].meanings[0].definitions[0].definition} ${
data[0].meanings[0].definitions[0]?.example ||
data[0].meanings[0].definitions[1]?.example ||
""
} `;

// here we use || and '' to make sure it populates one or the other or just not undefined if no example exists (for [0] or [1]) the ? makes sure it doesn't crash....found this explanation on chatgpt and reused it for adding audio part below

// find a way to clean up the dom so after a new word is shown, another one appears

// adding audio here
const audioUrl =
data[0].phonetics[0]?.audio || data[0].phonetics[1]?.audio;

if (audioUrl) {
const audio = new Audio(audioUrl);
audio.play();

const h3 = document.querySelector("h3");
h3.innerText = "🔊 Playing audio...";

// remove the message after 3 seconds / audio ends
audio.addEventListener("ended", () => {
h3.innerText = "";
});
} else {
document.querySelector("h3").innerText = "No audio avaiable.";
}
})
.catch((err) => {
console.error("error", err);
});

// next api that uses gif to pull video

const urlNew = `https://api.giphy.com/v1/gifs/search?api_key=e55YGccgW3ta0PpM7qrpU4mdbUlOSIpL&q=${word}}`;

fetch(urlNew)
.then((res) => res.json())

.then((data) => {
console.log("giphy sends info", data);

console.log("show me the giphs", data);

// document.querySelector("p").innerText += ` ${data[0].embed_url[0]} `; this did not work, asked for help from chatgpt

document.querySelector(
"p"
).innerHTML = `<iframe src="${data.data[0].embed_url}"></iframe>`;
})
.catch((err) => {
console.error("error", err);
});
}

// completed with chatgpt assistance
const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!?@#$%^&*";
for (let i = 0; i < 25; i++) {
const span = document.createElement("span");
span.className = "letter";
span.style.left = Math.random() * 100 + "vw";
span.style.fontSize = 12 + Math.random() * 36 + "px";
span.style.animationDuration = 5 + Math.random() * 10 + "s";
span.innerText = letters.charAt(Math.floor(Math.random() * letters.length));
document.body.appendChild(span);
}
141 changes: 141 additions & 0 deletions styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: "Comic Neue", "Courier New", Courier, monospace;
}

body {
background-color: #000;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
padding: 30px 15px;
min-height: 100vh;
text-align: center;
overflow: hidden;
}

/*floating letters container */
.letter {
position: absolute;
color: rgba(0, 255, 102, 0.2);
font-size: 2rem;
font-weight: bold;
pointer-events: none;
animation: float 10s linear infinite;
}

/*animate letters vertically */
@keyframes float {
0% {
transform: translateY(120vh) rotate(0deg);
opacity: 0;
}
10% {
opacity: 1;
}
100% {
transform: translateY(-10vh) rotate(360deg);
opacity: 0;
}
}
h1 {
font-size: 60px;
margin-bottom: 25px;
padding-bottom: 20px;
letter-spacing: 2px;
text-shadow: 0 0 10px #0fe8ec, 0 0 20px #0073ff;
}

h2 {
font-size: 1.5rem;
margin: 20px 20px;
color: #7d5ed1;
text-shadow: 0 0 8px #7606f6;
}

h3 {
font-size: 1.2rem;
margin: 10px 0;
color: #14dbdf;
text-shadow: 0 0 6px #089ff7;
}

p {
margin: 20px 0;
}

input#word {
padding: 15px 20px;
width: 300px;
max-width: 90%;
font-size: 1.1rem;
border-radius: 12px;
border: 2px solid #0888f1;
background: #111;
color: #05e2f2;
outline: none;
margin-bottom: 20px;
transition: all 0.3s ease;
}

input#word::placeholder {
color: #33d6ff;
font-style: italic;
}

input#word:focus {
border-color: #00bfac;
box-shadow: 0 0 10px #21e3ea;
}

button {
padding: 12px 25px;
font-size: 1.2rem;
background: linear-gradient(90deg, #fc3509, #17e2d4);
color: #000;
border: none;
border-radius: 15px;
cursor: pointer;
font-weight: bold;
box-shadow: 0 4px 15px rgba(30, 242, 115, 0.941);
transition: all 0.3s ease;
}

button:hover {
transform: translateY(-3px) rotate(-2deg);
box-shadow: 0 6px 20px rgb(145, 98, 246);
}

/* gif*/
p iframe {
margin-top: 15px;
width: 100%;
height: 300px;
border: 2px solid #00f2ff;
border-radius: 12px;
box-shadow: 0 0 15px #00aeff;
}

/* responsive */
@media (max-width: 600px) {
h1 {
font-size: 2rem;
}

h2,
h3 {
font-size: 1rem;
}

input#word {
width: 90%;
}

p iframe {
width: 90%;
height: 200px;
}
}