2013-07-16 43 views
18

Một khách hàng đã yêu cầu tôi áp dụng a similar water ripple effect cho hình nền (và chỉ hình nền) trên trang web của họ.Hiệu ứng gợn nước trên nền của trang web

Xét rằng điều này đang sử dụng canvas, có vẻ như không thể. Có ai biết về một hiệu ứng như thế này mà tôi chỉ có thể áp dụng cho hình nền trên một trang không?

+1

Có phải không? Không. Nó sẽ là một số công việc? Vâng. – Shawn31313

+1

Bạn đã cố gắng đưa nội dung trang web lên canvas (với vị trí: tuyệt đối) chưa? –

+1

Đặt chiều rộng và chiều cao thành 100% và đặt trang web của bạn với vị trí tuyệt đối và z-index –

Trả lời

16

Để có hiệu suất cao, giải pháp hỗ trợ WebGL, hãy xem dự án này:

jQuery WebGL Ripples

Bản trình diễn có sẵn here.

Công nghệ này không khả dụng cho mọi người trong mọi thiết bị.

+0

Vui lòng hướng dẫn tôi cách triển khai điều đó? Tôi cần điều này thật tốt. Hãy giúp tôi. –

+0

@SFDC_Learner Bạn có thể xem [liên kết chính] (https://github.com/sirxemic/jquery.ripples/) cách gọi hàm JS để kích hoạt hiệu ứng trong trang của bạn. Bạn cũng có thể kiểm tra mã nguồn trực tiếp [demo page] (http://sirxemic.github.io/jquery.ripples/) để xem cách đánh dấu HTML và cách hàm JS được gọi. –

8

Hãy xem qua 2 bản demo này, mà tôi nghĩ bạn có thể dựa vào để tạo ra bản trình diễn của bạn.

29a.chmrdoob

Hope this helps 
1
.paperButton { 
    display: block; 
    text-align: center; 
    text-decoration: none; 
    position: relative; 
    overflow: hidden; 
    -webkit-transition: all 0.2s ease; 
    -moz-transition: all 0.2s ease; 
    -o-transition: all 0.2s ease; 
    transition: all 0.2s ease; 
    z-index: 0; 
    cursor:pointer; 
} 
.animate { 
    -webkit-animation: ripple 0.65s linear; 
    -moz-animation: ripple 0.65s linear; 
    -ms-animation: ripple 0.65s linear; 
    -o-animation: ripple 0.65s linear; 
    animation: ripple 0.65s linear; 
} 
@-webkit-keyframes 
ripple { 100% { 
opacity: 0; 
-webkit-transform: scale(2.5); 
} 
} 
@-moz-keyframes 
ripple { 100% { 
opacity: 0; 
-moz-transform: scale(2.5); 
} 
} 
@-o-keyframes 
ripple { 100% { 
opacity: 0; 
-o-transform: scale(2.5); 
} 
} 
@keyframes 
ripple { 100% { 
opacity: 0; 
transform: scale(2.5); 
} 
} 


$(function(){ 
    var ink, i, j, k; 
    $(".paperButton").mousedown(function(e){  
      if($(this).find(".ink").length === 0){ 
       $(this).prepend("<span class='ink'></span>"); 
      } 

      ink = $(this).find(".ink"); 
      ink.removeClass("animate"); 

      if(!ink.height() && !ink.width()){ 
       i = Math.max($(this).outerWidth(), $(this).outerHeight()); 
       ink.css({height: i, width: i}); 
      } 

      j = e.pageX - $(this).offset().left - ink.width()/2; 
      k = e.pageY - $(this).offset().top - ink.height()/2; 

      ink.css({top: k+'px', left: j+'px'}).addClass("animate"); 

}); 
}); 
+2

Điều này giống như một giải pháp tốt vì nó không dựa vào OpenGL, bất kỳ cơ hội nào bạn có thể đặt điều này vào một jsfiddle thấy chúng ta có thể thấy ví dụ làm việc trực tiếp không? –

2

Hãy thử sử dụng tập lệnh tôi đã đăng, nó sẽ hoạt động chỉ cần sao chép và dán mã vào mã của bạn. tôi đã giải thích với các nhận xét trong mã số

(function(){ 
    var canvas = document.getElementById('c'), 

     /** @type {CanvasRenderingContext2D} */ 
     ctx = canvas.getContext('2d'), 
     width = 400, 
     height = 400, 

     half_width = width >> 1, 
     half_height = height >> 1, 
     size = width * (height + 2) * 2, 

     delay = 30, 
     oldind = width, 
     newind = width * (height + 3), 

     riprad = 3, 
     ripplemap = [], 
     last_map = [], 
     ripple, 
     texture, 

     line_width = 20, 
     step = line_width * 2, 
     count = height/line_width; 

    canvas.width = width; 
    canvas.height = height; 

    /* 
    * Water ripple demo can work with any bitmap image 
    */ 
    with (ctx) { 
     fillStyle = '#a2ddf8'; 
     fillRect(0, 0, width, height); 

     fillStyle = '#07b'; 
     save(); 
     rotate(-0.785); 
     for (var i = 0; i < count; i++) { 
      fillRect(-width, i * step, width * 3, line_width); 
     } 

     restore(); 
    } 

    texture = ctx.getImageData(0, 0, width, height); 
    ripple = ctx.getImageData(0, 0, width, height); 

    for (var i = 0; i < size; i++) { 
     last_map[i] = ripplemap[i] = 0; 
    } 

    /** 
    * Main loop 
    */ 
    function run() { 
     newframe(); 
     ctx.putImageData(ripple, 0, 0); 
    } 

    /** 
    * Disturb water at specified point 
    */ 
    function disturb(dx, dy) { 
     dx <<= 0; 
     dy <<= 0; 

     for (var j = dy - riprad; j < dy + riprad; j++) { 
      for (var k = dx - riprad; k < dx + riprad; k++) { 
       ripplemap[oldind + (j * width) + k] += 128; 
      } 
     } 
    } 

    /** 
    * Generates new ripples 
    */ 
    function newframe() { 
     var a, b, data, cur_pixel, new_pixel, old_data; 

     var t = oldind; oldind = newind; newind = t; 
     var i = 0; 

     // create local copies of variables to decrease 
     // scope lookup time in Firefox 
     var _width = width, 
      _height = height, 
      _ripplemap = ripplemap, 
      _last_map = last_map, 
      _rd = ripple.data, 
      _td = texture.data, 
      _half_width = half_width, 
      _half_height = half_height; 

     for (var y = 0; y < _height; y++) { 
      for (var x = 0; x < _width; x++) { 
       var _newind = newind + i, _mapind = oldind + i; 
       data = (
        _ripplemap[_mapind - _width] + 
        _ripplemap[_mapind + _width] + 
        _ripplemap[_mapind - 1] + 
        _ripplemap[_mapind + 1]) >> 1; 

       data -= _ripplemap[_newind]; 
       data -= data >> 5; 

       _ripplemap[_newind] = data; 

       //where data=0 then still, where data>0 then wave 
       data = 1024 - data; 

       old_data = _last_map[i]; 
       _last_map[i] = data; 

       if (old_data != data) { 
        //offsets 
        a = (((x - _half_width) * data/1024) << 0) + _half_width; 
        b = (((y - _half_height) * data/1024) << 0) + _half_height; 

        //bounds check 
        if (a >= _width) a = _width - 1; 
        if (a < 0) a = 0; 
        if (b >= _height) b = _height - 1; 
        if (b < 0) b = 0; 

        new_pixel = (a + (b * _width)) * 4; 
        cur_pixel = i * 4; 

        _rd[cur_pixel] = _td[new_pixel]; 
        _rd[cur_pixel + 1] = _td[new_pixel + 1]; 
        _rd[cur_pixel + 2] = _td[new_pixel + 2]; 
       } 

       ++i; 
      } 
     } 
    } 

    canvas.onmousemove = function(/* Event */ evt) { 
     disturb(evt.offsetX || evt.layerX, evt.offsetY || evt.layerY); 
    }; 

    setInterval(run, delay); 

    // generate random ripples 
    var rnd = Math.random; 
    setInterval(function() { 
     disturb(rnd() * width, rnd() * height); 
    }, 700); 
})();