I’m trying to recreate something like this effect on a picture, just the distortion effect without any interaction on hover. A simple distortion animation of a selected picture in loop.
Do you know a simple and easy-custom code way to do something similar?
It is a little bit more complicated than that. I have rebuild a codepen removing the fish drag function and adding webflow URls. All you need to do is add a custom code embed component in your webflow layout. Within your custom code component, simply write <canvas id="canvas"></canvas>.
Then copy this modified JavaScript to the custom code part of your webflow project (Note the options module with the little emoji, those are the settings you want to modify with your own webflow site ID / images).
Here is the modified codepen. Also, you’ll need to download the displacement map image and upload it on your webflow project. Here is the path to the displacement map. (right now uploaded on my webflow project)
document.addEventListener("DOMContentLoaded", () => {
water();
});
function water() {
// 🧠 options
let webflowUrl = "https://uploads-ssl.webflow.com/"; // 🧠 the default webflow upload url
let dataWfSite = "5b05ed948ee27f736bbe9315"; // 🧠 this is your data-wf-site ID.
let displacement = "5ec29f511ff8f57ad86daa00_displacementmap2.png"; // 🧠 this is your displacement map
let image = "5ec29e93078f498c19c51855_rocks.jpg"; // 🧠 this is your image you'd like to animate
let vw = 630;
let vh = 410;
let app = new PIXI.Application(vw, vh, {
view: document.getElementById("canvas")
});
let loader = new PIXI.loaders.Loader(webflowUrl)
.add(
"displacementMap",
`${dataWfSite}/${displacement}?v=1`
)
.add(
"rocks",
`${dataWfSite}/${image}?v=1`
)
.load(init);
function init(loader, resources) {
let container = new PIXI.Container();
let background = new PIXI.Sprite(resources.rocks.texture);
let displacementSprite = new PIXI.Sprite(resources.displacementMap.texture);
let displacementFilter = new PIXI.filters.DisplacementFilter(
displacementSprite
);
container.filterArea = new PIXI.Rectangle(0, 0, vw - 20, vh - 20);
container.filters = [displacementFilter];
displacementSprite.texture.baseTexture.wrapMode = PIXI.WRAP_MODES.REPEAT;
container.position.set(-10);
container.addChild(background);
container.addChild(displacementSprite);
app.stage.addChild(container);
TweenMax.to(displacementSprite, 5, {
ease: Linear.easeNone,
repeat: -1,
x: 512,
y: 512
});
}
}
Here are some explanation what is what, hope that helps:
Oh wow! Thanks @anthonysalamin! The explanation was very clear and comprehensive.
I’m sure your code works perfectly and I’m doing something wrong because still doesn’t work on my project
I’ve tried and replicated with my options but it doesn’t show anything
not even the static image.
What I’ve done also was a trial with an empty page with only the HTLM and the code (in the body), checked many times the options and they seem ok! I can’t understand.
Maybe I can try with another system. Do you think it could work as well with an external URL for the displacement map and the picture?
Sometimes I use https://imgbb.com/ to save and then copy-paste the image’s address.
Hi @Martina_Salvaterra,
Ha ! Sorry, I forgot to mention there are actually two JavaScript libraries the author of the original codepen is using, namely TweenMax.js and pixi.js. You need to reference them aswell like so before the end of the body tag custom code section of your page:
<script>
document.addEventListener("DOMContentLoaded", () => {
water();
});
function water() {
// 🧠 options
let webflowUrl = "https://uploads-ssl.webflow.com/"; // 🧠 the default webflow upload url
let dataWfSite = "5b05ed948ee27f736bbe9315"; // 🧠 this is your data-wf-site ID.
let displacement = "5ec29f511ff8f57ad86daa00_displacementmap2.png"; // 🧠 this is your displacement map
let image = "5ec29e93078f498c19c51855_rocks.jpg"; // 🧠 this is your image you'd like to animate
let vw = 630;
let vh = 410;
let app = new PIXI.Application(vw, vh, {
view: document.getElementById("canvas")
});
let loader = new PIXI.loaders.Loader(webflowUrl)
.add(
"displacementMap",
`${dataWfSite}/${displacement}?v=1`
)
.add(
"rocks",
`${dataWfSite}/${image}?v=1`
)
.load(init);
function init(loader, resources) {
let container = new PIXI.Container();
let background = new PIXI.Sprite(resources.rocks.texture);
let displacementSprite = new PIXI.Sprite(resources.displacementMap.texture);
let displacementFilter = new PIXI.filters.DisplacementFilter(
displacementSprite
);
container.filterArea = new PIXI.Rectangle(0, 0, vw - 20, vh - 20);
container.filters = [displacementFilter];
displacementSprite.texture.baseTexture.wrapMode = PIXI.WRAP_MODES.REPEAT;
container.position.set(-10);
container.addChild(background);
container.addChild(displacementSprite);
app.stage.addChild(container);
TweenMax.to(displacementSprite, 5, {
ease: Linear.easeNone,
repeat: -1,
x: 512,
y: 512
});
}
}
</script>
Give it a try and let me know if it worked.
And yes, it should work with any public URL. If you’re using webflow, why not use webflow to host your images (displacement and the actual image you wish to animate) ?
I tried following this as well. But unfortunately it doesn’t do what I want.
Instead of creating the effect on the image. It inserts the image on top again.
(I want it on the background image of section “coral reefs” - maybe I need another image as it might not be possible to see it properly on this one. - also thought about putting it on the first one - the hero image. But then I need to separate the image in water and background and only put it on the water part, I guess).
In Photoshop tutorial I learned, we can easily add a realistic water reflection to any photo. I feel that It’s a very easy effect to create and you can add it to any photo you like, although it tends to work best with images that don’t already contain water in them. Great Feature.