Utilizing the power of `jsgif` to create dynamic overlays on top of animated GIFs

Seeking assistance with utilizing the impressive libgif.js library.

The goal is to overlay an animated gif on top of a png text image with a transparent background, allowing the resulting image to be copied to the clipboard.

Used the libgif.js library to create an animated canvas from a gif successfully, but encountered difficulty displaying the text image on the final canvas.

Any insights into why the textImage appears to be properly sized and positioned on the canvas but not displayed in the end result?

Also, curious about the quick initial completion of the progress bar followed by slower progress - any explanations for this behavior?

JS code snippet from the JSFiddle:

function doit() {
  var isGIF = true; 
  var previewContainer = document.getElementById("previewContainer");
  var textImage = document.getElementById("textImage");
  var templateImage = document.getElementById("templateImage");
  var w = document.getElementById("templateImage").width;
  var h = document.getElementById("templateImage").height;

  previewContainer.removeChild(previewContainer.children[1]);

  if (isGIF) {
    var gif = new SuperGif({
      gif: templateImage,
      progressbar_height: 5,
      auto_play: true,
      loop_mode: true,
      draw_while_loading: true
    });

    gif.load();
    var canvas = gif.get_canvas();
    var context = canvas.getContext('2d');
    context.drawImage(textImage, 0, 0, w, h);

    previewContainer.replaceChild(canvas, previewContainer.children[0]);
  }
}

Note: based on Arend's solution from this question on this JSFiddle.

Answer №1

To gain access to the rendering loop of the library, such as a frame_rendered event, some adjustments would be required.
This modification would allow you to overlay any additional content on top of the image rendered by the library at each frame.

However, due to my reluctance to delve deep into it, here's a workaround :

Rather than directly inserting the canvas returned by the library into the document, you could maintain it offscreen and then draw it onto another visible canvas.
On this new canvas, you can also add your text/image using a requestAnimationFrame loop.

function customize() {
  var displayContainer = document.getElementById("displayContainer");
  var textImage = document.getElementById("textImage");
  var originalImage = document.getElementById("originalImage");
  var width = originalImage.width;
  var height = originalImage.height;
  displayContainer.removeChild(displayContainer.children[1]);

  var gifObject = new SuperGif({
    gif: originalImage,
    progressbar_height: 5,
    auto_play: true,
    loop_mode: true,
    draw_while_loading: true
  });

  gifObject.load();

  var gifCanvas = gifObject.get_canvas(); // the lib canvas
  // a duplicated canvas to be added to the doc
  var customCanvas = gifCanvas.cloneNode();
  var context = customCanvas.getContext('2d');

  function animate(time) { // our animation loop
    context.clearRect(0,0,customCanvas.width,customCanvas.height); // clear for transparency
    context.drawImage(gifCanvas, 0, 0); // render the gif frame
    context.drawImage(textImage, 0, 0, width, height); // followed by the text/image
    requestAnimationFrame(animate);
  };
  animate();

  displayContainer.replaceChild(customCanvas, displayContainer.children[0]);
}
<script src="https://cdn.rawgit.com/buzzfeed/libgif-js/master/libgif.js"></script>
<div>
  <input type="submit" id="customize" value="Customize!" onclick="customize()" />
</div>
<div id="displayContainer">
  <img id="originalImage" src="https://i.imgur.com/chWt4Yg.gif" />
  <img id="textImage" src="https://i.sstatic.net/CmErq.png" />
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Creating an AJAX data form in a JSP scenario

I want to correctly set up the data parameter for the ajax call. <script type="text/javascript"> $(document).ready(function() { $('#call').click(function () { $.ajax({ type: "post", ...

Angular 10: handling undefined error even with if statement checking for null values

After fetching a product from the backend, I ensure that if it contains images, they are also loaded. This functionality is already functioning properly when images are present. However, I need to implement a conditional check to skip products without imag ...

Issue with Rails: Content_For not functioning properly when combined with AJAX or when attempting to rehydrate JavaScript files

Currently, I am utilizing ajax to load all my views, and it's functioning perfectly except for one issue. My view pages that are being loaded are not referencing my JavaScript files. Below is an example of my coffee-script: jQuery(function() { Stri ...

Reveal the inner workings of functions within the Vuex Plugin

I am currently working on setting up a Vuex plugin where I want to make the undo function accessible for use in my component's click events. // plugin.js const timeTravel = store => { // .. other things function undo () { store.commit(&a ...

Extracting live content from a website within a native Webview

Running an eCommerce website along with a simple mobile app for both iOS and Android that features a basic tab bar menu, including icons like a shopping cart, profile, refresh button, etc., as well as a Webview to display the website content. The App' ...

Explore various THREE.JS 3D models through a clickable link

I am struggling to make each object open a new page using a URL when clicked. No matter what I try, it doesn't seem to work properly. Can someone point out what I might be missing or doing wrong? Here is the click event code for the objects. If needed ...

Struggling with creating a responsive page design using Bootstrap to fit all screen sizes

Seeking advice on optimizing my Vue.js landing page for small screens. Bootstrap documentation was helpful but struggling to make it look clean and presentable on tablets and smartphones. Any tips or suggestions on how I can modify the layout for better ...

A guide on iterating through a multi-dimensional array in Javascript and organizing the results in a specified sequence

Updated on 18th January, 2021 (refer to bold changes) I'm currently facing difficulties while attempting to iterate through a nested array and then organize the output in a specific order. Can you assist me in finding a solution to make this work or ...

I keep encountering the issue where I receive the message "Unable to access property 'innerText' of an undefined element" when running the Array forEach function. This problem seems to be happening within the HTMLInputElement section of the code

I am facing an issue where the error occurs because "cardTxt" is not recognized as a string. I verified this using typeof syntax, but I'm unable to understand why it can't be a string. This code snippet includes the use of bootstrap for styling. ...

The requested property 'x' is not found in the object type '{}' but is necessary in the 'Pick<Interface, "x">' type. TS2741

My challenge involves passing data from a redux store to a component using the connect function. Below is the code snippet I am working with: Parent Component: export const MainPage = ( { count, handleIncrementClick, selectedOfferId, }: Ma ...

What could be causing my header component to rerender even when there are no new props being received?

https://codesandbox.io/s/crimson-field-83hx6 In my project, I have a Header component that simply displays a fixed text and includes a console.log statement: const Header = props => { console.log("header render"); return ( <header> ...

Troubleshooting Vue.js: Why is .bind(this) not behaving as anticipated?

Demo: https://codesandbox.io/s/23959y5wnp I have a function being passed down and I'm trying to rebind the this by using .bind(this) on the function. However, the data that is returned still refers to the original component. What could I be missing h ...

How to create an empty @POST() body in NestJS for HTTPS requests

I am currently utilizing NestJS with HTTPS for my project. import { NestFactory } from '@nestjs/core'; import { fstat } from 'fs'; import { AppModule } from './app.module'; {readFileSync} from 'fs' async function boo ...

Troubleshooting in ReactJS and NodeJS: Understanding the "Pass --update-binary to reinstall or --build-from-source to recompile" error

After moving a ReactJS + NodeJS project from one computer to another, I attempted to install dependencies by running npm install in the terminal. However, I received the following response: > [email protected] install /Users/Joshua/Projects/practi ...

Passing data between functions in a JavaScript file

I need some guidance on implementing an angularjs google column chart. Specifically, I have a requirement to transfer the value from one JavaScript function to another variable defined in a separate JavaScript function. Here is an example snippet of code ...

What could be causing the malfunction in my jQuery .each loop when trying to access the attribute of each element?

I am currently working on a script that is meant to extract the 'title' attribute from each child element within a form. It successfully retrieves the title when I use console.log('title'). However, I am facing an issue when trying to i ...

Displaying a pop-up message over the "Login button" for users who are not currently logged in

I am currently in the process of developing a website using node.js and express. I have successfully integrated all the login functionality through passport, allowing users to easily log in or out by utilizing res.user. However, I now want to enhance the ...

Encountering a DOM exception with React 16.6 due to lazy loading/Susp

I am currently working on implementing dynamic import in my React application. Most of the React examples I have seen involve rendering the application to a specific tag and replacing its content, like this: ReactDOM.render(<App />, document.getEle ...

Using React hooks to implement drag and drop functionality

As a backend engineer primarily, I've been struggling to implement a simple drag and drop feature for a slider I'm creating in React. Here's the behavior without using debounce: no-debounce And here's the behavior with debounce: with- ...

The $.Get method does not retain its value within an each() loop

When using the jQuery each() method on a DropDown select, I iterate through an li element. However, my $.get() function takes time to fetch data from the server, so I use a loading image that toggles visibility. The issue is that the each() method does not ...