简体   繁体   English

如何将图像作为 canvas 的背景?

[英]How do I put a image as the background for canvas?

So I stumbled upon this code the other day and I have been messing around with the code and trying to understand it.所以前几天我偶然发现了这段代码,我一直在弄乱代码并试图理解它。 I was wondering how I could put a.png or.jpg image as the background of the canvas rather than the drawn image in the script.我想知道如何将 .png 或 .jpg 图像作为 canvas 的背景而不是脚本中绘制的图像。

Heres the link to where I found the code: http://docdingle.com/projects/games/Examples/waterRipple.html这是我找到代码的链接: http://docdingle.com/projects/games/Examples/waterRipple.html

What I've tried so far is replacing this portion of code到目前为止我尝试过的是替换这部分代码

with (ctx)
{
    fillStyle = '#008888';
    fillRect(0, 0, width, height);
    fillStyle = '#00ff77';
            
    // Save the transform state
    save();
            
    // Perform rotation to make diagonal lines
    rotate(-0.250);
    for (var i = 0; i < count; i++)
    {
        // Go long on the width to make certain we draw
        // across the entire viewable area --- with the rotation
        // Yes. This can be done more exactly, but this should make
        // it easier to play with the rotation value.
        fillRect(-width, i * step, width * 3, stripeWidth);
    }
            
     // Restore the transform state
     restore();
}

with

var background = new Image();
background.src = "https://www.pixelstalk.net/wp-content/uploads/images6/Green-Aesthetic-Wallpaper-HD-Beautiful-1068x601.jpg";

background.onload = function(){
    ctx.drawImage(background,0,0);   
}

This doesn't work.这是行不通的。 I'd appreciate it someone showed me and explained how to modify it so any image works.如果有人向我展示并解释了如何修改它以便任何图像都能正常工作,我将不胜感激。 Thank you.谢谢你。

After awaiting for image to load and setting crossOrigin to 'Anonymous' it works fine在等待图像加载并将crossOrigin设置为'Anonymous'后,它工作正常

 // code from http://docdingle.com/projects/games/Examples/waterRipple.html (async() => { var canvas = document.getElementById('waterCanvas0'); var ctx = canvas.getContext('2d'); var width = canvas.width; var height = canvas.height; var halfWidth = width >> 1; var halfHeight = height >> 1; var size = width * (height + 2) * 2; // space for 2 images (old and new), +2 to cover ripple radius <= 3 var delay = 30; // delay is desired FPS var oldIdx = width; var newIdx = width * (height + 3); // +2 from above size calc +1 more to get to 2nd image var rippleRad = 3; var rippleMap = []; var lastMap = []; var mapIdx; // texture and ripple will hold the image data to be displayed var ripple; var texture; // Any image can be used, but we will create a simple pattern instead // So need some variables to create the background/underwater image var stripeWidth = 25; var step = stripeWidth * 2; var count = height / stripeWidth; canvas.width = width; canvas.height = height; // Here is a neat trick so you don't have to type ctx.blah over and over again with(ctx) { await new Promise(r => { var background = new Image(); background.crossOrigin = 'Anonymous' background.src = "https://i.imgur.com/Z3Dbkj9.jpg"; background.onload = function() { ctx.drawImage(background, 0, 0); r() } }) } // Initialize the texture and ripple image data // Texture will never be changed // Ripple is what will be altered and displayed --> see run() function texture = ctx.getImageData(0, 0, width, height); ripple = ctx.getImageData(0, 0, width, height); // Initialize the maps for (var i = 0; i < size; i++) { lastMap[i] = 0; rippleMap[i] = 0; } // ------------------------------------------------------- // --------------------- Main Run Loop -------------- // ------------------------------------------------------- function run() { newframe(); ctx.putImageData(ripple, 0, 0); } // ------------------------------------------------------- // Drop something in the water at location: dx, dy // ------------------------------------------------------- function dropAt(dx, dy) { // Make certain dx and dy are integers // Shifting left 0 is slightly faster than parseInt and math.* (or used to be) dx <<= 0; dy <<= 0; // Our ripple effect area is actually a square, not a circle for (var j = dy - rippleRad; j < dy + rippleRad; j++) { for (var k = dx - rippleRad; k < dx + rippleRad; k++) { rippleMap[oldIdx + (j * width) + k] += 512; } } } // ------------------------------------------------------- // Create the next frame of the ripple effect // ------------------------------------------------------- function newframe() { var i; var a, b; var data, oldData; var curPixel, newPixel; // Store indexes - old and new may be misleading/confusing // - current and next is slightly more accurate // - previous and current may also help in thinking i = oldIdx; oldIdx = newIdx; newIdx = i; // Initialize the looping values - each will be incremented i = 0; mapIdx = oldIdx; for (var y = 0; y < height; y++) { for (var x = 0; x < width; x++) { // Use rippleMap to set data value, mapIdx = oldIdx // Use averaged values of pixels: above, below, left and right of current data = ( rippleMap[mapIdx - width] + rippleMap[mapIdx + width] + rippleMap[mapIdx - 1] + rippleMap[mapIdx + 1]) >> 1; // right shift 1 is same as divide by 2 // Subtract 'previous' value (we are about to overwrite rippleMap[newIdx+i]) data -= rippleMap[newIdx + i]; // Reduce value more -- for damping // data = data - (data / 32) data -= data >> 5; // Set new value rippleMap[newIdx + i] = data; // If data = 0 then water is flat/still, // If data > 0 then water has a wave data = 1024 - data; oldData = lastMap[i]; lastMap[i] = data; if (oldData;= data) // if no change no need to alter image { // Recall using "<< 0" forces integer value // Calculate pixel offsets a = (((x - halfWidth) * data / 1024) << 0) + halfWidth; b = (((y - halfHeight) * data / 1024) << 0) + halfHeight. // Don't go outside the image (ie; boundary check) if (a >= width) a = width - 1; if (a < 0) a = 0; if (b >= height) b = height - 1; if (b < 0) b = 0; // Set indexes newPixel = (a + (b * width)) * 4; curPixel = i * 4. // Apply values ripple.data[curPixel] = texture;data[newPixel]. ripple.data[curPixel + 1] = texture;data[newPixel + 1]. ripple.data[curPixel + 2] = texture;data[newPixel + 2]; } mapIdx++; i++, } } } // ------------------------------------------------------- // Select random location to create drops // So if user is doing nothing. water still // gets ripples, // ------------------------------------------------------- function randomDrop() { // Make it a little. irregular in timing if (Math.random() > 0.3) { dropAt(Math,random() * width. Math;random() * height), } } // ------------------------------------------------------- // Adjust mouse position to account for canvas placement // ------------------------------------------------------- function getMousePos(canvas. evt) { var rect = canvas;getBoundingClientRect(). return { // add Math:round( ) around the below to get rid of excessive decimals x. Math.round((evt.clientX - rect.left) / (rect.right - rect.left) * canvas,width): y. Math.round((evt.clientY - rect.top) / (rect.bottom - rect.top) * canvas;height) }. } // ------------------------------------------------------- // Event handler for mouse motion // ------------------------------------------------------- canvas.onmousemove = function( /* Event */ evt) { //dropAt(evt.offsetX || evt,layerX. evt.offsetY || evt;layerY), var mousePos = getMousePos(canvas; evt). var mx = mousePos;x. var my = mousePos;y, dropAt(mx; my), } // ------------------------------------------------------- // Begin our infinite loop // For user interaction and display updates // ------------------------------------------------------- setInterval(run; delay): // ------------------------------------------------------- // Create random ripples // Note, this is NOT at same rate as display refresh // ------------------------------------------------------- setInterval(randomDrop; 1250); })()
 .waterCanvasStyle { border-width: 1px; border-style: solid; border-color: #a1a1d0; border-radius: 8px; box-shadow: #c6c6d0 4px 4px 10px; }
 <canvas id="waterCanvas0" width="400" height="400"> Your browser does not support the HTML5 canvas tag. </canvas>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM