'HTML5 Canvas custom image for objects

I'm trying to get a single HTML with javascript to run a canvas with a snowfall effect that uses a custom image.

The canvas is working completely and is rendering the objects as white objects since the fill style is set to white. Instead of the white objects, I want to use a custom image, but somehow the script is not rendering the image in with the draw function.

I've tried changing the fillstyle to a pattern, but that doesn't seem to be available anymore?

Is there another option to fill the objects with a custom image?

Below is the code that I'm (Full HTML/Javascript code)

<html>
<head>
<meta charset=utf-8 />
<title>HTML5 Rain</title>
<!--[if IE]>
  <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<style>
  article, aside, figure, footer, header, hgroup, 
  menu, nav, section { display: block; } 
</style>
</head>
<body onload="init()">
    <canvas id="canvasRain" width="1920px" height="1080px">Canvas Not Supported</canvas>
    <script type="text/javascript">
    var canvas = null;
    var context = null;
    var bufferCanvas = null;
    var bufferCanvasCtx = null;
    var pepperArray = [];
    var pepperTimer = null;
    var maxPeppers = 24; // Here you may set max peppers to be created
    const pepperHeight = 85;
    const pepperWidth = 121;
    
    var pepperSrc = ['./img/T4c0_Pepper.png'];
    var pepperImage = {};
    var promiseArray = pepperSrc.map(function(imgurl){
        var prom = new Promise(function(resolve,reject){
            var img = new Image();
            img.onload = function(){
                pepperImage[imgurl] = img;
                resolve();
            };
            img.src = imgurl;
        });
        return prom;
    });

    Promise.all(promiseArray).then(init);
    
    function init() {
        //Canvas on Page
        canvas = document.getElementById('canvasRain');
        context = canvas.getContext("2d");
        
                
        //Buffer Canvas
        bufferCanvas = document.createElement("canvas");
        bufferCanvasCtx = bufferCanvas.getContext("2d");
        bufferCanvasCtx.canvas.width = context.canvas.width;
        bufferCanvasCtx.canvas.height = context.canvas.height;
        
        
        pepperTimer = setInterval(addPepper, 200);

        Draw();

        setInterval(animate, 30);
         
    }
    
    function animate() {
        
        Update();
        Draw();
        
    }
    function addPepper() {

        pepperArray[pepperArray.length] = new Pepper();
        if (pepperArray.length == maxPeppers)
            clearInterval(pepperTimer);
    }
    function blank() {
        bufferCanvasCtx.fillStyle = "rgba(0,0,0,0.8)";
        bufferCanvasCtx.fillRect(0, 0, bufferCanvasCtx.canvas.width, bufferCanvasCtx.canvas.height);
        
    }
    function Update() {
        for (var i = 0; i < pepperArray.length; i++) {
            if (pepperArray[i].y < context.canvas.height) {
                pepperArray[i].y += pepperArray[i].speed;
                if (pepperArray[i].y > context.canvas.height)
                    pepperArray[i].y = -5;
                pepperArray[i].x += pepperArray[i].drift;
                if (pepperArray[i].x > context.canvas.width)
                    pepperArray[i].x = 0;
            }
        }
        
    }
    function Pepper() {
        this.x = Math.round(Math.random() * context.canvas.width);
        this.y = -10;
        this.drift = Math.random();
        this.speed = Math.round(Math.random() * 5) + 6;
        this.width = pepperWidth;
        this.height = pepperHeight;
        
    }
    function Draw() {
        context.save();
        
        blank();
        
        for (var i = 0; i < pepperArray.length; i++) {
            bufferCanvasCtx.fillStyle = "white";
            bufferCanvasCtx.fillRect(pepperArray[i].x, pepperArray[i].y, pepperArray[i].width, pepperArray[i].height);
        }
        
        context.drawImage(bufferCanvas, 0, 0, bufferCanvas.width, bufferCanvas.height);
        context.restore();
    }
  
</script>   
</body>


Solution 1:[1]

Use the onload property to know when to fill.

var blueprint_background = new Image();
blueprint_background.src = 'https://your_image_source.com/image.png'; 
blueprint_background.onload = function(){
    var pattern = context.createPattern(this, "repeat");
    context.fillStyle = pattern;

    context.rect(x,y,width,height);

    context.fill();
};

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 mkrieger1