2013-08-05 2 views
1

질문이 하나 있습니다. 나는 물 파급 효과를 만들기 위해 지침을 따르고 배경을 내 이미지로 바꿨다. 그 효과는 꽤 잘 돌아 간다. 하지만 문제가 있습니다. 처음로드 할 때 브라우저가 내 배경 (내 이미지)을로드 할 수 없으며 브라우저를 다시로드 (F5)하거나 검색 주소창에 다시 입력해야 효과를 볼 수 있습니다. 해결 방법을 알려주세요. 모두들 !!물 리플 - 처음에는 이미지를로드 할 수 없습니다.

(제 영어에 대한 미안 해요, 난 구글 번역 사용)

내 코드 :

<!DOCTYPE html> 
<html> 
<head> 
    <title>Water Ripple HTML5</title> 
    <meta name="author" content="Brent Dingle"> 
    <meta name="description" content="HTML5 canvas example of water ripple effect"> 

    <style > 
     .waterCanvasStyle 
     { 
      border-width: 1px; 
      border-style: solid; 
      border-color:#a1a1d0; 
      border-radius: 8px; 
      box-shadow: #c6c6d0 4px 4px 10px; 
     } 
</style> 
</head> 
<body> 
    <canvas id="waterCanvas0" width="400" height="400" > 
     Your browser does not support the HTML5 canvas tag. 
    </canvas> 
    <script> 
     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; 

     var img = new Image(); 
     img.src = "sea.jpg"; 

     // Here is a neat trick so you don't have to type ctx.blah over and over again 
     with (ctx) 
     { 
      drawImage(img,0,0); 
      save(); 
      restore(); 
     } 

     // 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 (i.e. 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); 
      } 
     } 
     // ------------------------------------------------------- 
     // Event handler for mouse motion 
     // ------------------------------------------------------- 
     canvas.onmousemove = function(/* Event */ evt) 
     { 
      dropAt(evt.offsetX || evt.layerX, evt.offsetY || evt.layerY); 
     } 

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

    </script> 
</body> 
+0

모두 도와주세요. – liemphan

+0

도와주세요, 제발! – liemphan

답변

1

이러한 유형의 문제가 발생하는 일반적인 오류, 당신이 그것을하기 전에 이미지를 그릴하려고하는 것입니다 잔뜩. img.onload 기능을 사용하여 그림이 모두로드 될 때까지 기다린 다음 주 루프를 실행하기 시작하십시오.

+0

도움을 주셔서 감사합니다. 나는 너의 지시를 따를거야. – liemphan

관련 문제