canvas 水波效果
看到某些工具上有水波效果,想能不能用canvas实现呢,于是就google了一下还真有在这里与大家分享吧!
这里有一篇教程,介绍实现原理的,水波纹原理
下面是js实现的源代码
var ripple = (function(img_src, container){
var img = new Image, img_data, delay = 30, width, height, half_width, half_height, riprad = 5, oldind, newind, mapind, size, ripplemap = [], last_map = [], ripple, ripple_data, texture, texture_data, is_running = true, is_disturbed = false, timer_id, canvas = document.createElement('canvas'), /** @type {CanvasRenderingContext2D} */ ctx;
function init(){
width = img.width;
height = img.height;
half_width = width >> 1;
half_height = height >> 1;
size = width * (height + 2) * 2;
canvas.width = width;
canvas.height = height;
oldind = width;
newind = width * (height + 3);
/** @type {CanvasRenderingContext2D} */
ctx = canvas.getContext('2d');
container.appendChild(canvas);
ctx.drawImage(img, 0, 0, width, height);
for (var i = 0; i < size; i++) {
last_map[i] = ripplemap[i] = 0;
}
texture = ctx.getImageData(0, 0, width, height);
texture_data = texture.data;
ripple = ctx.getImageData(0, 0, width, height);
ripple_data = ripple.data;
canvas.addEventListener('mousemove', function(/* Event */evt){
disturb(evt.offsetX || evt.layerX, evt.offsetY || evt.layerY);
}, false);
start();
disturb(180,130);
}
function stop(){
if (timer_id)
clearInterval(timer_id);
}
function start(){
stop();
timer_id = setInterval(run, delay);
}
function run(){
if (is_disturbed) {
newframe(width, height);
ctx.putImageData(ripple, 0, 0);
}else{
}
}
function disturb(dx, dy){
dx <<= 0;
dy <<= 0;
is_disturbed = true;
for (var j = dy - riprad; j < dy + riprad; j++) {
for (var k = dx - riprad; k < dx + riprad; k++) {
ripplemap[oldind + (j * width) + k] += 4048;
}
}
//newframe(width, height);
//ctx.putImageData(ripple, 0, 0);
}
function newframe(){
var i, a, b, data, cur_pixel, new_pixel, old_data;
i = oldind;
oldind = newind;
newind = i;
i = 0;
mapind = oldind;
var _width = width, _height = height, _ripplemap = ripplemap, _mapind = mapind, _newind = newind, _last_map = last_map, _rd = ripple.data, _td = texture.data, _half_width = half_width, _half_height = half_height, _is_disturbed = false;
for (var y = 0; y < _height; y++) {
for (var x = 0; x < _width; x++) {
data = (_ripplemap[_mapind - _width] +
_ripplemap[_mapind + _width] +
_ripplemap[_mapind - 1] +
_ripplemap[_mapind + 1]) >>
1;
data -= _ripplemap[_newind + i];
data -= data >> 5;
_ripplemap[_newind + i] = 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
_is_disturbed = true;
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];
//_rd[cur_pixel + 3] = _td[new_pixel + 3];
}
++_mapind;
++i;
}
}
mapind = _mapind;
is_disturbed = _is_disturbed;
}
img.onload = init;
img.src = img_src;
return {
start: start,
stop: stop,
disturb: disturb
}
});
与大家分享了!!!
分割线---------------------------------------------------------------------------------

浙公网安备 33010602011771号