Code viewer for World: Anime Profile Picture (clo...

// Cloned by Saurav Nambiar on 3 Dec 2024 from World "Anime Profile Picture" by Ivan Shvydchenko 
// Please leave this clone trail here.
 
// function sets API key (snippet used from Chat with GPT model)

function setkey()          
{
	apikey =  jQuery("input#apikey").val();
	apikey = apikey.trim();
	$("#enterkey").html ( "<b> API key has been set. </b>" );
}

async function generateImage() {
  const promptInput = document.getElementById('promptInput').value;
  const loadingText = document.getElementById('loadingText');
  loadingText.style.display = 'block';

  // loops through loadingMessages showing the user that the page didn't freeze and that the generation is in progress
  const loadingMessages = ['Generating image', 'Generating image.', 'Generating image..', 'Generating image...'];
  let messageIndex = 0;

  const updateLoadingText = () => {
    loadingText.innerText = loadingMessages[messageIndex];
    messageIndex = (messageIndex + 1) % loadingMessages.length;
  };

  // Update loading text every 500 milliseconds
  const loadingInterval = setInterval(updateLoadingText, 500);


  // RapidAPI Snippet code we used the javascript fetch option with a few changes
  const url = 'https://animimagine-ai.p.rapidapi.com/generateImage';
  const options = {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-RapidAPI-Key': apikey,
      'X-RapidAPI-Host': 'animimagine-ai.p.rapidapi.com',
    },
    body: JSON.stringify({
      selected_model_id: 'anything-v5',
      selected_model_bsize: '512',
      // passes users input to the POST request
      prompt: promptInput,
    }),
  };

  try {
    const response = await fetch(url, options);
    const result = await response.json();

    // gets image and goes into displayImage function to display image else gives the Error for wrong API key or 503 error.
    if (result.imageUrl) {
      displayImage(result.imageUrl);
    } else {
      console.log("error")
      console.error('Image URL not found in the response.');
      const errorText = document.getElementById('errorText');
      errorText.style.display = 'block';
    }
  } catch (error) {
      console.error(error);
    
  } finally {
    // Stop the loading animation loop and hide loading text
    clearInterval(loadingInterval);
    loadingText.style.display = 'none';
  }
}

// function to display Image and display downloadButton also
function displayImage(imageUrl) {
  const outputImage = document.getElementById('outputImage');
  const img = new Image();
  img.src = imageUrl;

  img.onload = function () {
    outputImage.innerHTML = ''; // Clear previous content
    outputImage.appendChild(img);
  };
  
  const downloadButton = document.getElementById('downloadButton');
  downloadButton.style.display = 'block';
}

function downloadImage() {
  const outputImage = document.getElementById('outputImage');
  const img = outputImage.querySelector('img');

  if (!img) {
    console.error('Image not found.');
    return;
  }

  //Download functionality
  const imageUrl = img.src;

  const downloadLink = document.createElement('a');
  downloadLink.href = imageUrl;
  downloadLink.download = 'generated_image.png';

  document.body.appendChild(downloadLink);
  downloadLink.click();
  document.body.removeChild(downloadLink);
}

document.write ( `
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
  <title>Display Generated Image</title>
  <style>
    body {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    font-family: Arial, sans-serif;
    background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="visual" viewBox="0 0 900 600" width="900" height="600" version="1.1"><rect x="0" y="0" width="900" height="600" fill="%23001220"/><path d="M0 388L13.7 383.8C27.3 379.7 54.7 371.3 82 359.7C109.3 348 136.7 333 163.8 315.3C191 297.7 218 277.3 245.2 282.3C272.3 287.3 299.7 317.7 327 321.3C354.3 325 381.7 302 409 297.5C436.3 293 463.7 307 491 319C518.3 331 545.7 341 573 336C600.3 331 627.7 311 654.8 308.8C682 306.7 709 322.3 736.2 315.5C763.3 308.7 790.7 279.3 818 273.3C845.3 267.3 872.7 284.7 886.3 293.3L900 302L900 601L886.3 601C872.7 601 845.3 601 818 601C790.7 601 763.3 601 736.2 601C709 601 682 601 654.8 601C627.7 601 600.3 601 573 601C545.7 601 518.3 601 491 601C463.7 601 436.3 601 409 601C381.7 601 354.3 601 327 601C299.7 601 272.3 601 245.2 601C218 601 191 601 163.8 601C136.7 601 109.3 601 82 601C54.7 601 27.3 601 13.7 601L0 601Z" fill="%23fa7268"/><path d="M0 311L13.7 313.5C27.3 316 54.7 321 82 325C109.3 329 136.7 332 163.8 348.3C191 364.7 218 394.3 245.2 397.3C272.3 400.3 299.7 376.7 327 365.5C354.3 354.3 381.7 355.7 409 354.3C436.3 353 463.7 349 491 357.5C518.3 366 545.7 387 573 397.3C600.3 407.7 627.7 407.3 654.8 398.8C682 390.3 709 373.7 736.2 358.2C763.3 342.7 790.7 328.3 818 332.2C845.3 336 872.7 358 886.3 369L900 380L900 601L886.3 601C872.7 601 845.3 601 818 601C790.7 601 763.3 601 736.2 601C709 601 682 601 654.8 601C627.7 601 600.3 601 573 601C545.7 601 518.3 601 491 601C463.7 601 436.3 601 409 601C381.7 601 354.3 601 327 601C299.7 601 272.3 601 245.2 601C218 601 191 601 163.8 601C136.7 601 109.3 601 82 601C54.7 601 27.3 601 13.7 601L0 601Z" fill="%23ef5f67"/><path d="M0 427L13.7 433.8C27.3 440.7 54.7 454.3 82 455.8C109.3 457.3 136.7 446.7 163.8 446.3C191 446 218 456 245.2 448.8C272.3 441.7 299.7 417.3 327 418.5C354.3 419.7 381.7 446.3 409 449.7C436.3 453 463.7 433 491 423.7C518.3 414.3 545.7 415.7 573 420.5C600.3 425.3 627.7 433.7 654.8 428.7C682 423.7 709 405.3 736.2 395C763.3 384.7 790.7 382.3 818 385C845.3 387.7 872.7 395.3 886.3 399.2L900 403L900 601L886.3 601C872.7 601 845.3 601 818 601C790.7 601 763.3 601 736.2 601C709 601 682 601 654.8 601C627.7 601 600.3 601 573 601C545.7 601 518.3 601 491 601C463.7 601 436.3 601 409 601C381.7 601 354.3 601 327 601C299.7 601 272.3 601 245.2 601C218 601 191 601 163.8 601C136.7 601 109.3 601 82 601C54.7 601 27.3 601 13.7 601L0 601Z" fill="%23e34c67"/><path d="M0 486L13.7 490.3C27.3 494.7 54.7 503.3 82 506.5C109.3 509.7 136.7 507.3 163.8 497.5C191 487.7 218 470.3 245.2 469.7C272.3 469 299.7 485 327 487.8C354.3 490.7 381.7 480.3 409 474.5C436.3 468.7 463.7 467.3 491 461.8C518.3 456.3 545.7 446.7 573 446.3C600.3 446 627.7 455 654.8 463.5C682 472 709 480 736.2 476C763.3 472 790.7 456 818 454.8C845.3 453.7 872.7 467.3 886.3 474.2L900 481L900 601L886.3 601C872.7 601 845.3 601 818 601C790.7 601 763.3 601 736.2 601C709 601 682 601 654.8 601C627.7 601 600.3 601 573 601C545.7 601 518.3 601 491 601C463.7 601 436.3 601 409 601C381.7 601 354.3 601 327 601C299.7 601 272.3 601 245.2 601C218 601 191 601 163.8 601C136.7 601 109.3 601 82 601C54.7 601 27.3 601 13.7 601L0 601Z" fill="%23d53867"/><path d="M0 499L13.7 506.5C27.3 514 54.7 529 82 530.8C109.3 532.7 136.7 521.3 163.8 524.2C191 527 218 544 245.2 545.3C272.3 546.7 299.7 532.3 327 529.8C354.3 527.3 381.7 536.7 409 537.3C436.3 538 463.7 530 491 529.2C518.3 528.3 545.7 534.7 573 534.2C600.3 533.7 627.7 526.3 654.8 518.7C682 511 709 503 736.2 499.5C763.3 496 790.7 497 818 499.3C845.3 501.7 872.7 505.3 886.3 507.2L900 509L900 601L886.3 601C872.7 601 845.3 601 818 601C790.7 601 763.3 601 736.2 601C709 601 682 601 654.8 601C627.7 601 600.3 601 573 601C545.7 601 518.3 601 491 601C463.7 601 436.3 601 409 601C381.7 601 354.3 601 327 601C299.7 601 272.3 601 245.2 601C218 601 191 601 163.8 601C136.7 601 109.3 601 82 601C54.7 601 27.3 601 13.7 601L0 601Z" fill="%23c62368"/></svg>');
    background-size: cover;
    color: white;
    }
    }

    #outputImage {
    width: 300px; 
    height: 300px; 
    overflow: hidden; /* Hide any overflow content */
    border-radius: 50%; /* Make the container circular */
    margin: auto; /* Center the container */
    }

    #outputImage img {
    width: 100%; 
    height: 100%; 
    object-fit: cover; /* Maintain the aspect ratio and cover the container */
    border-radius: 50%; /* Make the image circular */
    }
    
    #loadingText {
    font-size: 20px; /* Adjust the font size */
    font-family: 'Courier New', monospace; /* Change the font family */
    margin-top: 20px; /* Adjust this value to move the text down */
    }
    
    #errorText {
    font-size: 20px; /* Adjust the font size */
    font-family: 'Courier New', monospace; /* Change the font family */
    margin-top: 20px;
    color: #f5e642;
    }
    </style>
</head>
<body>
<h1> Create an Anime Profile Picture! </h1><br>

<p>To use this API you need an API key from RapidAPI. <br>
Register for free and get your API key 
<a href='https://rapidapi.com/hub'>here.</a></p>
<br>
<div id=enterkey>
Enter API key: 
	<input    style='width:25vw;'    maxlength='2000'   NAME="apikey"    id="apikey"       VALUE='' >  
	<button onclick='setkey()'  class="btn btn-success" >Set API key</button>
</div><br>
  <div>
    <label for="promptInput">Prompt:</label>
    <input type="text" id="promptInput" placeholder="Enter your description here">
    <button onclick="generateImage()" class="btn btn-success" id="generateButton">Generate Image</button>
  </div>
  <br>
  <div id="loadingText" style="display: none;">Generating image...</div>
  <div id="errorText" style="display: none;"> ERROR WITH GENERATION: Problem with server or API key used. Reload page and try again.</div>
  <div id="outputImage"></div>
  <div id="downloadButton" style="display: none;">
    <br><button onclick="downloadImage()" class="btn btn-success" id="generateButton">Download Image</button>
    </div>
</body>
</html>
` );