gpt4 book ai didi

javascript - 图像上的涟漪

转载 作者:行者123 更新时间:2023-11-29 21:06:05 26 4
gpt4 key购买 nike

如何在图像而不是原始 Canvas 上实现类似的效果?

/**
* Water ripple effect.
* Original code (Java) by Neil Wallis
* @link http://www.neilwallis.com/java/water.html
*
* @author Sergey Chikuyonok (serge.che@gmail.com)
* @link http://chikuyonok.ru
*/
(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,
mapind,
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
* (see example here: http://media.chikuyonok.ru/ripple/)
* But I need to draw simple artwork to bypass 1k limitation
*/
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] += 512;
}
}
}

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

i = oldind;
oldind = newind;
newind = i;

i = 0;
mapind = oldind;

// create local copies of variables to decrease
// scope lookup time in Firefox
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;

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

++_mapind;
++i;
}
}

mapind = _mapind;
}

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

})();
<canvas id="c"></canvas>

最佳答案

看看这只雄伟的独 Angular 兽:codepen . Data URI 用于避免 CORS 问题,它适用于任意数量的图像(默认情况下所有图像)。

JS:

window.addEventListener('load',()=>{
document.querySelectorAll('img').forEach((img)=>{
var cont = document.createElement('div');
cont.style.position = 'relative'
cont.style.display = 'inline-block'
img.parentNode.insertBefore(cont,img);
img.style.verticalAlign = 'top';
cont.appendChild(img)
console.dir(img)
var c = document.createElement('canvas');
c.width = img.clientWidth
c.height = img.clientHeight
c.style.position = 'absolute'
c.style.top = '0px'
c.style.left = '0px'
cont.appendChild(c)
console.log(c)
makeRipple(c,img)
})
})

function makeRipple(el,img){

var canvas = el,
/** @type {CanvasRenderingContext2D} */
ctx = canvas.getContext('2d'),
width = img.clientWidth,
height = img.clientHeight,
half_width = width >> 1,
half_height = height >> 1,
size = width * (height + 2) * 2,
delay = 30,
oldind = width,
newind = width * (height + 3),
riprad = 3,
mapind,
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
* (see example here: http://media.chikuyonok.ru/ripple/)
* But I need to draw simple artwork to bypass 1k limitation
*/
ctx.drawImage(img,0,0,img.clientWidth,img.clientHeight)

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() {
console.log('bbb')
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] += 512;
}
}
}

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

i = oldind;
oldind = newind;
newind = i;

i = 0;
mapind = oldind;

// create local copies of variables to decrease
// scope lookup time in Firefox
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;

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

++_mapind;
++i;
}
}

mapind = _mapind;
}

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

setInterval(run, delay);

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

};

关于javascript - 图像上的涟漪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43997909/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com