簡體   English   中英

如何將圖像作為 canvas 的背景?

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

所以前幾天我偶然發現了這段代碼,我一直在弄亂代碼並試圖理解它。 我想知道如何將 .png 或 .jpg 圖像作為 canvas 的背景而不是腳本中繪制的圖像。

這是我找到代碼的鏈接: http://docdingle.com/projects/games/Examples/waterRipple.html

到目前為止我嘗試過的是替換這部分代碼

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();
}

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);   
}

這是行不通的。 如果有人向我展示並解釋了如何修改它以便任何圖像都能正常工作,我將不勝感激。 謝謝你。

在等待圖像加載並將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