<main>
	<section>
		<figure>
      <canvas id="target">
        <img id="source-from" src="https://images.unsplash.com/photo-1612958859485-b6812253f59e?crop=fill&w=854&h=480&cs=srgb&fm=jpg&ixid=MXwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHw&ixlib=rb-1.2.1&q=85" alt=""/>
				<img id="source-to" data-src="https://images.unsplash.com/photo-1612733619095-4ea8ed978657?crop=entropy&cs=srgb&fm=jpg&ixid=MXwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHw&ixlib=rb-1.2.1&q=85&w=854&h=480" alt=""/>
			</canvas>
		<figure>
	</section>
</main>
* {
  margin: 0;
}
import * as kampos from "https://cdn.skypack.dev/[email protected]";

function loadImage (src) {
   return new Promise(resolve => {
       const img = new Image();
       img.crossOrigin = 'anonymous';

       img.onload = function () {
           resolve(this);
       };

       img.src = src;
   });
}
// get the image URLs
const imageFromSrc = document.querySelector('#source-from').src;
const imageToSrc = document.querySelector('#source-to').dataset.src;
// load images
const promisedImages = [
    loadImage(imageFromSrc),
    loadImage(imageToSrc)
];

const turbulence = kampos.effects.turbulence({ noise: kampos.noise.perlinNoise });

const WIDTH = 854;
const HEIGHT = 480;
const CELL_FACTOR = 2;
const AMPLITUDE = CELL_FACTOR / WIDTH;

turbulence.frequency = { x: AMPLITUDE, y: AMPLITUDE };
turbulence.octaves = 1;
turbulence.isFractal = true;

const mapTarget = document.createElement('canvas');
mapTarget.width = WIDTH;
mapTarget.height = HEIGHT;

const dissolveMap = new kampos.Kampos({ target: mapTarget, effects: [turbulence], noSource: true });

dissolveMap.draw();

const dissolve = kampos.transitions.dissolve();

dissolve.map = mapTarget;
dissolve.high = 0.03; // for liquid-like effect

const target = document.querySelector('#target');
const hippo = new kampos.Kampos({ target, effects: [dissolve] });

Promise.all(promisedImages).then(([fromImage, toImage]) => {
    hippo.setSource({ media: fromImage, width: WIDTH, height: HEIGHT });

    dissolve.to = toImage;
}).then(function () {
    hippo.play(time => {
        dissolve.progress = Math.abs(Math.sin(time * 4e-4)); // multiply time by a factor to slow it down a bit
    });
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.