What is the best way to superimpose an image onto a canvas?

I am working on a cool project where I have created a canvas that displays matrix binary code raining down. However, I would like to enhance it by adding an image overlay on top of the canvas.

Here is my current setup:

<div class="rain">
            <canvas id="Matrix"></canvas>
             <div class ="imgclass">
                <img class="imgclass" src="assets/image.jpg"/>
            </div>
        </div>

This is the JavaScript code responsible for the animation on the canvas:

const canvas = document.getElementById('Matrix');
const context = canvas.getContext('2d');

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const latin = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
const nums = '0123456789';

const alphabet = latin + nums;

const fontSize = 16;
const columns = canvas.width/fontSize;

const rainDrops = [];

for( let x = 0; x < columns; x++ ) {
    rainDrops[x] = 1;
}

const draw = () => {
    context.fillStyle = 'rgba(0, 0, 0, 0.05)';
    context.fillRect(0, 0, canvas.width, canvas.height);
    
    context.fillStyle = '#0F0';
    context.font = fontSize + 'px monospace';

    for(let i = 0; i < rainDrops.length; i++)
    {
        const text = alphabet.charAt(Math.floor(Math.random() * alphabet.length));
        context.fillText(text, i*fontSize, rainDrops[i]*fontSize);
        
        if(rainDrops[i]*fontSize > canvas.height && Math.random() > 0.975){
            rainDrops[i] = 0;
        }
        rainDrops[i]++;
    }
};

setInterval(draw, 30);

and here's the CSS styling:

.rain {
    background: black;
    height: 40%;
    overflow: hidden;
}

canvas {
    background-image: url("assets/img.jpg");
}

The issue I am facing is that the image does not appear on the canvas as intended, instead, it displays below the canvas. I'm looking for a solution to position the image in the middle of the canvas.

Answer №1

To create a CRT effect on your canvas, simply wrap the canvas in a div element and apply the necessary CSS properties to mimic the desired effect.

Below is an example of how you can achieve a Matrix-style animation on your canvas:

const canvas = document.getElementById('Matrix');
const context = canvas.getContext('2d');

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const latin = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
const nums = '0123456789';

const alphabet = latin + nums;

const fontSize = 16;
const columns = canvas.width / fontSize;

const rainDrops = [];

for (let x = 0; x < columns; x++) {
  rainDrops[x] = 1;
}

const draw = () => {
  context.fillStyle = 'rgba(0, 0, 0, 0.05)';
  context.fillRect(0, 0, canvas.width, canvas.height);

  context.fillStyle = '#0F0';
  context.font = fontSize + 'px monospace';

  for (let i = 0; i < rainDrops.length; i++) {
    const text = alphabet.charAt(Math.floor(Math.random() * alphabet.length));
    context.fillText(text, i * fontSize, rainDrops[i] * fontSize);

    if (rainDrops[i] * fontSize > canvas.height && Math.random() > 0.975) {
      rainDrops[i] = 0;
    }
    rainDrops[i]++;
  }
};

setInterval(draw, 30);
@keyframes flicker {
  50% {
    top: -3px;
  }
}

.crt::before {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  content: "";
  display: block;
  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAGCAYAAADkOT91AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVBhXYxTiF68WZ2TQeqLE8o3hicEbJgY0gFNgHRBvBuK9hLQwMAAAF54HHx1Goh0AAAAASUVORK5CYII=");
  background-size: 4px, 6px;
  opacity: 0.9;
  background-repeat: repeat;
  image-rendering: optimizeSpeed;
  pointer-events: none;
  filter: contrast(50%);
  animation: flicker 0.08s step-end infinite;
}

html,
body {
  margin: 0;
  padding: 0;
  overflow: hidden;
}
<div class="crt">
  <canvas id="Matrix"></canvas>
</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

Break down objects into arrays of objects in JavaScript

Hello, I'm struggling with transforming this object into an array of objects. The 'number' and 'reason' fields are currently stored as strings separated by commas. I need to split them into their own separate objects. The example ...

What is the method to extract a value from the $emit payload using Vue.js?

I have a situation where I am sending an event with different values from my ConversationList component (child) to the ConversationModel component (parent). Conversation List getConversation(conversation_id, receiver_id, username, avatar){ this.$emit(& ...

Struggling with incorporating a button into a ReactJS table

I am trying to display a (view) button in the table, but I encountered the following error: Module parse failed: Unexpected token < in JSON at position 165 while parsing near '...2021", "view": <button type="submit...' You m ...

Import of Bootstrap causing disruption in positioning of <figure> element

Check out this codepen example: https://codepen.io/anon/pen/Xgqjyq h2 { color: #111; font-family: 'Open Sans', sans-serif; font-size: 20px; font-weight: bold; text-align: center; } .content { margin-left: 5px; margin-right: 5px; t ...

What is the best way to retrieve data from divs that are nested within another element using Javascript?

I am currently working on implementing a modal that will showcase specific information based on the event-card it originates from. Here is an HTML snippet showcasing an example event-card: <div class="event-card upcoming hackathon"> <d ...

Ensure that the user's credentials are accessible to all views in Node.js

I'm currently developing an Android application that utilizes Node.js web services. The initial interface requires the user to connect to a host using an IP address, login, and password in order to access all databases. I aim to save these credentials ...

Dealing with Error TS2769 in Visual Studio Code when passing props to a custom component in Vue 2 with Typescript

I've encountered an issue with a Vue JS component that involves passing a custom prop. I am utilizing the Vue Options API without utilizing the class component syntax. Whenever I pass ANY prop to my custom component the-header, I receive an error sta ...

Refresh meta tags in a Next.js/React app

In the process of optimizing a website for SEO, I am facing the challenge of updating the meta description's content dynamically without using any third-party libraries. While I have successfully implemented the functionality, it currently requires a ...

What is the best way to display the letter X (Clear) in the Chrome INPUT field with the type

A custom application was developed that utilizes an input field of the number type: <input type="number" min="-1000000" max="1000000" step="0.01"> Within Internet Explorer, there is a small "clear" or [X] button on the right side of the input field ...

Tips for setting up a webpacked vue.js application with an express/koa backend!

Struggling with setting up a vue.js project for easy debugging in combination with a koa server? The cross-env NODE_ENV=development webpack-dev-server --open --hot command from the webpack-simple generated configuration looks promising, but how should it b ...

Having trouble with res.render() when making an axios request?

I am encountering an issue with my axios requests. I have two requests set up: one to retrieve data from the API and another to send this data to a view route. const response = await axios({ method: 'POST', url: 'http:// ...

Understanding JavaScript's JSON Path Variables

I've scoured the internet for solutions to a similar issue but haven't been able to find any helpful information yet. My current challenge involves accessing a picture path (in JSON format) based on the material type of the selected element. Her ...

Unable to retrieve input using jquery selector

I am attempting to detect the click event on a checkbox. The Xpath for the element provided by firebug is as follows, starting with a table tag in my JSP (i.e. the table is within a div). /html/body/div[1]/div/div/div[2]/div/div[2]/div[1]/div/div[2]/table ...

Having issues with the Email type in the JQuery Validation Plugin?

Recently, I set up a Grunt file to consolidate all my libraries and code into a single JS file for inclusion in my website. However, after adding the JQuery Validate plugin (http://jqueryvalidation.org/), I noticed that it's not working as expected. I ...

Div text with superfluous line breaks

Whenever a user clicks the sign-up button ("Cadastrar" in Portuguese) on my website, the newsletter form successfully hides. However, there seems to be unnecessary line breaks in the success message. Why is this happening? I am trying to make sure that th ...

Tips for adding an image to HTML after clicking on a div element

Is there a way to prompt users to upload an image by clicking on a <div> that contains an <img>? The current code I have is: <div class="container"> <img src="..." alt="Profile image" class="profileImg"> ...

CSS prefers to remain within its original controller and does not want to be uploaded from any other source

My webpage includes headers and footers with CSS in them. Strangely, when I load the view using one controller, the CSS displays correctly. But when I try to load the same view using a different controller, the CSS doesn't appear at all. What could b ...

How can I fix the issue of the header background image not resizing properly? Any suggestions?

I am currently working on improving the responsiveness of my website when a user resizes their browser window. One specific issue I'm facing is resizing the banner image as the window size changes. The website in question can be found at The CSS code ...

CSS slider experiencing issues

I'm currently working on creating a custom CSS ticker by referencing various examples online. I've managed to develop something that functions well, but it seems to only cycle through the initial 4 list items. Once it reaches the 4th item, it loo ...

Assessing the validity of a boolean condition as either true or false while iterating through a for loop

I am facing an issue that involves converting a boolean value to true or false if a string contains the word "unlimited". Additionally, I am adding a subscription to a set of values and need to use *NgIf to control page rendering based on this boolean. &l ...