Launch Week Day 5: Introducing Reachability for PHP.Learn More
Socket
Book a DemoSign in
Socket

kampos

Package Overview
Dependencies
Maintainers
1
Versions
45
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

kampos - npm Package Compare versions

Comparing version
0.2.2
to
0.3.0
+14
.travis.yml
language: node_js
node_js:
- 10
install:
- npm install xvfb-maybe
- npm install
before_script:
- export DISPLAY=':99.0'
- Xvfb :99 -screen 0 1024x768x24 -extension RANDR &
script:
- xvfb-maybe npm test

Sorry, the diff of this file is not supported yet

/*
Name: dracula
Author: Michael Kaminsky (http://github.com/mkaminsky11)
Original dracula color scheme by Zeno Rocha (https://github.com/zenorocha/dracula-theme)
*/
.cm-s-dracula.CodeMirror, .cm-s-dracula .CodeMirror-gutters {
background-color: #282a36 !important;
color: #f8f8f2 !important;
border: none;
}
.cm-s-dracula .CodeMirror-gutters { color: #282a36; }
.cm-s-dracula .CodeMirror-cursor { border-left: solid thin #f8f8f0; }
.cm-s-dracula .CodeMirror-linenumber { color: #6D8A88; }
.cm-s-dracula .CodeMirror-selected { background: rgba(255, 255, 255, 0.10); }
.cm-s-dracula .CodeMirror-line::selection, .cm-s-dracula .CodeMirror-line > span::selection, .cm-s-dracula .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); }
.cm-s-dracula .CodeMirror-line::-moz-selection, .cm-s-dracula .CodeMirror-line > span::-moz-selection, .cm-s-dracula .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); }
.cm-s-dracula span.cm-comment { color: #6272a4; }
.cm-s-dracula span.cm-string, .cm-s-dracula span.cm-string-2 { color: #f1fa8c; }
.cm-s-dracula span.cm-number { color: #bd93f9; }
.cm-s-dracula span.cm-variable { color: #50fa7b; }
.cm-s-dracula span.cm-variable-2 { color: white; }
.cm-s-dracula span.cm-def { color: #50fa7b; }
.cm-s-dracula span.cm-operator { color: #ff79c6; }
.cm-s-dracula span.cm-keyword { color: #ff79c6; }
.cm-s-dracula span.cm-atom { color: #bd93f9; }
.cm-s-dracula span.cm-meta { color: #f8f8f2; }
.cm-s-dracula span.cm-tag { color: #ff79c6; }
.cm-s-dracula span.cm-attribute { color: #50fa7b; }
.cm-s-dracula span.cm-qualifier { color: #50fa7b; }
.cm-s-dracula span.cm-property { color: #66d9ef; }
.cm-s-dracula span.cm-builtin { color: #50fa7b; }
.cm-s-dracula span.cm-variable-3, .cm-s-dracula span.cm-type { color: #ffb86c; }
.cm-s-dracula .CodeMirror-activeline-background { background: rgba(255,255,255,0.1); }
.cm-s-dracula .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

const {Kampos, effects, noise} = window.kampos;
const target = document.createElement('canvas');
target.width = 854;
target.height = 480;
const target2 = document.querySelector('#target');
const media1 = document.querySelector('#video5');
// uncomment here if you want to see just the turbulence
//target2.parentNode.replaceChild(target, target2);
// create the effects we need
const turbulence = effects.turbulence(noise.perlinNoise);
// create a simple effect that converts the turbulence return value into the output color
const render = {fragment: {main: 'color = vec3(turbulenceValue);'}};
const disp = effects.displacement();
// try playing with this factor
const AMPLITUDE = 2 * 1 / target.width;
turbulence.frequency = {x: AMPLITUDE, y: AMPLITUDE};
turbulence.octaves = 8;
// change to false (or comment out) if you want to see the turbulence noise variant
turbulence.isFractal = true;
// init kampos
const instance = new Kampos({target, effects:[turbulence, render], noSource: true});
const instance2 = new Kampos({target: target2, effects:[disp]});
// start playing the noise map in a loop
const start = Date.now();
// you can increase/decrease the time factor for a faster/slower animation
instance.play(
() => turbulence.time = (Date.now() - start) * 2
);
prepareVideos([media1])
.then(() => {
const width = media1.videoWidth;
const height = media1.videoHeight;
// set media source
instance2.setSource({media: media1, width, height});
disp.map = target;
disp.scale = {x: 0.15, y: -0.15};
disp.textures[0].update = true; // to update
// start kampos
instance2.play();
});

Sorry, the diff of this file is not supported yet

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="cache-control" content="no-cache" />
<title>kampos | Tiny and fast effects compositor on WebGL</title>
<link href="https://fonts.googleapis.com/css?family=Nova+Round&display=swap" rel="stylesheet">
<script async defer src="https://buttons.github.io/buttons.js"></script>
<style>
body {
min-height: 100vh;
margin: 0;
background-image: linear-gradient(-45deg, peachpuff, palegreen, plum, peachpuff, palegreen, plum),
linear-gradient(45deg, purple, darkblue, rebeccapurple, purple, darkblue, rebeccapurple),
url('./kampos.svg');
background-blend-mode: screen;
background-repeat: no-repeat;
background-position: center;
font-family: "Nova round", cursive, fantasy;
font-size: 16px;
color: darkslateblue;
}
nav > ul {
display: flex;
width: 100vw;
margin: 0;
padding: 0;
list-style: none;
}
nav li {
flex: 1 auto;
padding: 1rem .5rem;
}
nav li.nav-items {
font-size: 16px;
font-weight: bold;
}
nav a,
nav a:visited {
color: darkslateblue;
}
nav a:hover {
color: darkslateblue;
}
main {
margin: 30vh auto 0;
text-align: center;
}
h1,
h2 {
color: #bada;
}
h1 {
font-size: 96px;
margin: 0;
text-shadow: 0 6px 10px darkslateblue;
}
h2 {
font-size: 28px;
margin: 0;
text-shadow: 0 4px 4px darkslateblue;
}
header > span {
position: absolute;
top: 50px;
right: 50px;
}
@media (min-width: 641px) {
html, body {
margin: 0;
}
main {
width: fit-content;
}
h1 {
font-size: 128px;
}
h2 {
font-size: 32px;
}
nav > ul {
width: fit-content;
margin: 0 auto;
}
nav li.nav-items {
font-size: 20px;
padding: 1rem 2rem;
}
}
</style>
</head>
<body>
<header>
<nav>
<ul>
<li class="nav-items">
<a href="./docs/">API Reference</a>
</li>
<li class="nav-items">
<a href="./demo/">Demos</a>
</li>
<li class="nav-items">
<a href="https://github.com/wix-incubator/kampos">Source</a>
</li>
<li>
<a class="github-button" href="https://github.com/wix-incubator/kampos" data-size="large" aria-label="Star wix-incubator/kampos on GitHub">Star</a>
</li>
</ul>
</nav>
</header>
<main>
<h1>kampos</h1>
<h2>Tiny and fast effects compositor</h2>
</main>
</body>
</html>
<svg viewBox="0 0 313.33 710.07" xmlns="http://www.w3.org/2000/svg" width="156" height="355">
<defs>
<linearGradient gradientTransform="rotate(90)" id="a769ca78-d298-44bf-bc15-efb581f913a2">
<stop stop-color="#02C836" offset="0%"/>
<stop stop-color="#0055ee" offset="100%"/>
</linearGradient>
</defs>
<g>
<path fill="url(#a769ca78-d298-44bf-bc15-efb581f913a2)" d="M154.1 57.03a7.64 7.64 0 1 0-7.64-7.64 7.64 7.64 0 0 0 7.64 7.64zm3.27-10.91a3.28 3.28 0 1 1-3.27 3.27 3.27 3.27 0 0 1 3.27-3.27zm-97.06 56.71c17.76 38.44 37.87 12 159.23 80.71 16.66 9.43 27.63-11.55 13.09-18.54-44.32-21.38-81.32-66.71-39.27-114.52C137.52-33.63 40.44 6.94 33.04 33.03c33.47 0 13.27 39.55 27.27 69.8zm87.25-69.8a16.36 16.36 0 1 1-16.36 16.36 16.36 16.36 0 0 1 16.35-16.36zm2.18 299.93c-10.23 30.67-73.15 42-84-9.82-.13-.6 4.81 37.48 21.81 73.07 5.28 13.06 55.51 90.64 147.23 50.17 41.15-18.15 65-68.86 58.21-110.13-4.89-59.06-65.12-121.37-212-177.79-75-28.81-39.27-81.8-39.27-81.8-93.17 102.29-8.89 149.36 44.6 174 65.32 30 72.45 55.21 63.41 82.3zm8.69 143.73c-43.59-9.4-69.12-32.4-92.67-73.93 20.46 74.74 6.83 125.66-6.55 157C45 593.09 40.63 623.56 45.53 648c3.73 22.07 16.94 42.31 37 53.57 24.15 13.53 54.25 10.92 74.17-8.66 16.72-16.43 23.64-42.22 11.22-63.22-9.41-15.9-28.13-25.54-46.47-21.75-15.83 3.27-28.62 15.87-29.76 32.35-.79 11.36 5 23.15 14.91 28.76 13.59 7.69 32.05 2 36.87-13.31a3.92 3.92 0 0 0-7.36-2.66l-.06.15c-6.68 16.71-29.5 9.69-32.08-5.9-4.84-29.21 36.8-31.53 47.75-9.8 14 27.8-16.53 53.07-42.85 45.79-14.07-3.89-25.4-11.59-31-28.58-12.38-54.74 17.11-96 96.67-126.44 119.08-45.41 136.4-120.53 138.77-150.63-17.92 73.48-86.29 113.91-154.89 99.02z" fill-rule="evenodd"/>
</g>
</svg>
/**
* @function turbulence
* @param {string} noise 3D noise implementation to use
* @returns {turbulenceEffect}
*
* @example turbulence(noise)
*/
export default function (noise) {
/**
* @typedef {Object} turbulenceEffect
* @property {{x: number?, y: number?}} frequency
* @property {number} octaves
* @property {boolean} isFractal
*
* @description Generates a turbulence/fractal noise value stored into `turbulenceValue`.
* Depends on a `noise(vec3 P)` function to be declared. Currently it's possible to simply use it after {@link perlinNoiseEffect}.
*
* @example
* effect.frequency = {x: 0.0065};
* effect.octaves = 4;
* effect.isFractal = true;
*/
return {
fragment: {
uniform: {
u_turbulenceEnabled: 'bool',
u_turbulenceFrequency: 'vec2',
u_turbulenceOctaves: 'int',
u_isFractal: 'bool',
u_time: 'float'
},
constant: `
${noise}
const int MAX_OCTAVES = 9;
float turbulence (vec3 seed, vec2 frequency, int numOctaves, bool isFractal) {
float sum = 0.0;
vec3 position = vec3(0.0);
position.x = seed.x * frequency.x;
position.y = seed.y * frequency.y;
position.z = seed.z;
float ratio = 1.0;
for (int octave = 0; octave <= MAX_OCTAVES; octave++) {
if (octave > numOctaves) {
break;
}
if (isFractal) {
sum += noise(position) / ratio;
}
else {
sum += abs(noise(position)) / ratio;
}
position.x *= 2.0;
position.y *= 2.0;
ratio *= 2.0;
}
if (isFractal) {
sum = (sum + 1.0) / 2.0;
}
return clamp(sum, 0.0, 1.0);
}`,
main: `
vec3 turbulenceSeed = vec3(gl_FragCoord.xy, u_time * 0.0001);
float turbulenceValue = turbulence(turbulenceSeed, u_turbulenceFrequency, u_turbulenceOctaves, u_isFractal);`
},
get frequency () {
const [x, y] = this.uniforms[0].data;
return {x, y};
},
set frequency ({x, y}) {
if ( typeof x !== 'undefined' )
this.uniforms[0].data[0] = x;
if ( typeof y !== 'undefined' )
this.uniforms[0].data[1] = y;
},
get octaves () {
return this.uniforms[1].data[0];
},
set octaves (value) {
this.uniforms[1].data[0] = Math.max(0, parseInt(value));
},
get isFractal () {
return !!this.uniforms[2].data[0];
},
set isFractal (toggle) {
this.uniforms[2].data[0] = +toggle;
},
get time () {
return this.uniforms[3].data[0];
},
set time (value) {
this.uniforms[3].data[0] = Math.max(0, parseFloat(value));
},
uniforms: [
{
name: 'u_turbulenceFrequency',
type: 'f',
data: [0.0, 0.0]
},
{
name: 'u_turbulenceOctaves',
type: 'i',
data: [1]
},
{
name: 'u_isFractal',
type: 'i',
data: [0]
},
{
name: 'u_time',
type: 'f',
data: [0.0]
}
]
};
};
/*!
* GLSL textureless classic 3D noise "cnoise",
* with an RSL-style periodic variant "pnoise".
* Author: Stefan Gustavson (stefan.gustavson@liu.se)
* Version: 2011-10-11
*
* Many thanks to Ian McEwan of Ashima Arts for the
* ideas for permutation and gradient selection.
*
* Copyright (c) 2011 Stefan Gustavson. All rights reserved.
* Distributed under the MIT license. See LICENSE file.
* https://github.com/ashima/webgl-noise
*/
/**
* Implementation of a 3D classic Perlin noise. Exposes a `noise(vec3 P)` function for use inside fragment shaders.
*/
export default `
vec3 mod289 (vec3 x) {
return x - floor(x * (1.0 / 289.0)) * 289.0;
}
vec4 mod289 (vec4 x) {
return x - floor(x * (1.0 / 289.0)) * 289.0;
}
vec4 permute (vec4 x) {
return mod289(((x*34.0)+1.0)*x);
}
vec4 taylorInvSqrt (vec4 r) {
return 1.79284291400159 - 0.85373472095314 * r;
}
vec3 fade (vec3 t) {
return t*t*t*(t*(t*6.0-15.0)+10.0);
}
// Classic Perlin noise
float noise (vec3 P) {
vec3 Pi0 = floor(P); // Integer part for indexing
vec3 Pi1 = Pi0 + vec3(1.0); // Integer part + 1
Pi0 = mod289(Pi0);
Pi1 = mod289(Pi1);
vec3 Pf0 = fract(P); // Fractional part for interpolation
vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0
vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
vec4 iy = vec4(Pi0.yy, Pi1.yy);
vec4 iz0 = Pi0.zzzz;
vec4 iz1 = Pi1.zzzz;
vec4 ixy = permute(permute(ix) + iy);
vec4 ixy0 = permute(ixy + iz0);
vec4 ixy1 = permute(ixy + iz1);
vec4 gx0 = ixy0 * (1.0 / 7.0);
vec4 gy0 = fract(floor(gx0) * (1.0 / 7.0)) - 0.5;
gx0 = fract(gx0);
vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0);
vec4 sz0 = step(gz0, vec4(0.0));
gx0 -= sz0 * (step(0.0, gx0) - 0.5);
gy0 -= sz0 * (step(0.0, gy0) - 0.5);
vec4 gx1 = ixy1 * (1.0 / 7.0);
vec4 gy1 = fract(floor(gx1) * (1.0 / 7.0)) - 0.5;
gx1 = fract(gx1);
vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1);
vec4 sz1 = step(gz1, vec4(0.0));
gx1 -= sz1 * (step(0.0, gx1) - 0.5);
gy1 -= sz1 * (step(0.0, gy1) - 0.5);
vec3 g000 = vec3(gx0.x,gy0.x,gz0.x);
vec3 g100 = vec3(gx0.y,gy0.y,gz0.y);
vec3 g010 = vec3(gx0.z,gy0.z,gz0.z);
vec3 g110 = vec3(gx0.w,gy0.w,gz0.w);
vec3 g001 = vec3(gx1.x,gy1.x,gz1.x);
vec3 g101 = vec3(gx1.y,gy1.y,gz1.y);
vec3 g011 = vec3(gx1.z,gy1.z,gz1.z);
vec3 g111 = vec3(gx1.w,gy1.w,gz1.w);
vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)));
g000 *= norm0.x;
g010 *= norm0.y;
g100 *= norm0.z;
g110 *= norm0.w;
vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)));
g001 *= norm1.x;
g011 *= norm1.y;
g101 *= norm1.z;
g111 *= norm1.w;
float n000 = dot(g000, Pf0);
float n100 = dot(g100, vec3(Pf1.x, Pf0.yz));
float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z));
float n110 = dot(g110, vec3(Pf1.xy, Pf0.z));
float n001 = dot(g001, vec3(Pf0.xy, Pf1.z));
float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z));
float n011 = dot(g011, vec3(Pf0.x, Pf1.yz));
float n111 = dot(g111, Pf1);
vec3 fade_xyz = fade(Pf0);
vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z);
vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y);
float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x);
return 2.2 * n_xyz;
}`;
+36
-3

@@ -1,3 +0,36 @@

import './utils';
import './disp';
import './hue-fade';
function updatePreview (iframe, example, videos) {
iframe.setAttribute('srcdoc', getIFrameHTML({example, videos}))
}
function getIFrameHTML ({example, videos}) {
return `<!DOCTYPE html>
<html>
<head>
<style>
body, html {margin: 0; height: 100%; overflow: hidden;}
canvas {width: 100%; height: 100%;}
video {display: none;}
</style>
<script src="../index.js"></script>
<script src="./utils.js"></script>
</head>
<body>
${videos}
<canvas id="target"></canvas>
<script>
${example}
</script>
</body>
</html>`;
}
window.updatePreview = updatePreview;
const navOffHandler = () => document.body.classList.remove('nav-open');
document.querySelector('#nav-on')
.addEventListener('click', () => {
document.body.classList.add('nav-open');
setTimeout(() => document.body.addEventListener('click', navOffHandler, {once: true}), 0);
});
+11
-4

@@ -41,2 +41,3 @@ const {Kampos, transitions} = window.kampos;

// try playing with the x/y and +/- for different transition effects
this.transition.sourceScale = {x: this.dispScale};

@@ -85,2 +86,3 @@ this.transition.toScale = {x: -this.dispScale};

// dividing by 500 is just enough to slow down the effect
// you can change the sin() function with a different one for a different easing
let p = Math.abs(Math.sin(now / 500));

@@ -112,3 +114,3 @@ p = this.direction ? p : 1 - p;

const video2 = document.querySelector('#video2');
const target1 = document.querySelector('#target1');
const target = document.querySelector('#target');

@@ -118,4 +120,9 @@ const trans = new Transition({

vid2: video2,
target: target1,
target,
// switch between the different displacement-map images and refresh to see different effects
//disp: 'disp-cloud.png',
//disp: 'disp-liquid.jpg',
//disp: 'disp-tri.jpg',
disp: 'disp-snow.jpg',
// change this value and refresh to see how it affects the transition
dispScale: 1.0

@@ -127,3 +134,3 @@ });

*/
target1.addEventListener('mouseenter', () => trans.forward());
target1.addEventListener('mouseleave', () => trans.backward());
target.addEventListener('mouseenter', () => trans.forward());
target.addEventListener('mouseleave', () => trans.backward());

@@ -5,3 +5,3 @@ const {Kampos, effects, transitions} = window.kampos;

const media2 = document.querySelector('#video4');
const target = document.querySelector('#target2');
const target = document.querySelector('#target');

@@ -8,0 +8,0 @@ // create the effects/transitions we need

@@ -7,5 +7,6 @@ <!DOCTYPE html>

<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="pragma" content="no-cache" />
<title>Kampos Displacement Demo</title>
<title>kampos Demos</title>
<link href="https://fonts.googleapis.com/css?family=Nova+Round&display=swap" rel="stylesheet">
<link rel="stylesheet" href="./lib/codemirror/codemirror.css">
<link rel="stylesheet" href="lib/codemirror/dracula.css">
<style>

@@ -18,25 +19,28 @@ body {

font-family: "Nova round", cursive, fantasy;
color: #bada;
}
header {
width: fit-content;
margin: 40vh auto 0;
text-align: center;
text-align: right;
}
h1 {
font-size: 96px;
margin: 0;
text-shadow: 0 6px 10px darkslateblue;
nav {
position: fixed;
width: 256px;
min-height: 100vh;
z-index: 10;
top: 0;
background-color: #DDA0DDee;
transform: translateX(-100%);
transition: transform .5s ease;
}
h2 {
font-size: 28px;
margin: 0;
text-shadow: 0 4px 4px darkslateblue;
.nav-open nav {
transform: translateX(0);
}
video,
canvas {
main {
width: 100vw;
}
iframe {
display: block;

@@ -46,18 +50,64 @@ vertical-align: top;

canvas {
iframe {
width: 100vw;
height: auto;
height: calc(480 / 854 * 100vw);
border: none;
outline: none;
}
video {
display: none;
section {
position: relative;
margin: 0 auto 10vh;
}
header > span {
nav ul {
margin: 1rem 0;
padding: 0;
list-style: none;
}
nav li {
padding: 1rem;
}
p {
padding: 1rem;
}
button {
cursor: pointer;
background: linear-gradient(45deg, beige, plum);
}
.code-container {
position: relative;
}
.refresh-button {
position: absolute;
top: 50px;
right: 50px;
top: 1px;
right: 1px;
z-index: 10;
padding: 1em 2em;
font-size: 16px;
font-weight: bold;
}
@media (min-width: 854px) {
header button {
cursor: pointer;
}
#nav-off {
display: none;
}
.nav-open #nav-off {
display: inline;
}
.nav-open #nav-on {
display: none;
}
@media (min-width: 1110px) {
html, body {

@@ -67,2 +117,24 @@ margin: 0;

body {
display: grid;
grid-template: "nav main" 1fr / 256px calc(100vw - 256px);
}
header {
display: none;
}
nav {
grid-area: nav;
position: fixed;
min-height: 100vh;
background-color: transparent;
transform: none;
}
main {
grid-area: main;
width: auto;
}
h1 {

@@ -80,6 +152,5 @@ font-size: 128px;

width: 854px;
margin: 10vh auto;
}
canvas {
iframe {
flex: auto;

@@ -95,3 +166,3 @@ width: 854px;

#code1 + .CodeMirror {
height: 118rem;
height: 125rem;
}

@@ -102,100 +173,117 @@

}
#code3 + .CodeMirror {
height: 54rem;
}
}
</style>
<link href="https://fonts.googleapis.com/css?family=Nova+Round&display=swap" rel="stylesheet">
<script async defer src="https://buttons.github.io/buttons.js"></script>
</head>
<body>
<header>
<a class="github-button" href="https://github.com/wix-incubator/kampos" data-size="large" aria-label="Star wix-incubator/kampos on GitHub">Star</a>
<h1>kampos</h1>
<h2>Tiny and fast effects compositor</h2>
</header>
<!--<video id="video"-->
<!--src="https://video.wixstatic.com/video/11062b_6ceb80744f45401caf9eb666caeb9887/480p/mp4/file.mp4"-->
<!--autoplay-->
<!--loop-->
<!--muted-->
<!--preload="auto"-->
<!--crossorigin="anonymous"-->
<!--playsinline></video>-->
<template id="videos1">
<video id="video1"
src="./cloudy-night.mp4"
autoplay
loop
muted
preload="auto"
crossorigin="anonymous"
playsinline></video>
<!--<video id="video2"-->
<!--src="https://video.wixstatic.com/video/11062b_1bb2d040b6da423fa2461982bd68bb12/480p/mp4/file.mp4"-->
<!--autoplay-->
<!--loop-->
<!--muted-->
<!--preload="auto"-->
<!--crossorigin="anonymous"-->
<!--playsinline></video>-->
<video id="video2"
src="./starry-night.mp4"
autoplay
loop
muted
preload="auto"
crossorigin="anonymous"
playsinline></video>
</template>
<video id="video1"
src="https://video.wixstatic.com/video/11062b_2ccb88c1c6de4151b51879d6c90fca9d/480p/mp4/file.mp4"
autoplay
loop
muted
preload="auto"
crossorigin="anonymous"
playsinline></video>
<template id="videos2">
<video id="video3"
src="./wheat-field.mp4"
autoplay
loop
muted
preload="auto"
crossorigin="anonymous"
playsinline></video>
<video id="video2"
src="https://video.wixstatic.com/video/11062b_735a34726eb64df29a56b30b60fe2db8/480p/mp4/file.mp4"
autoplay
loop
muted
preload="auto"
crossorigin="anonymous"
playsinline></video>
<video id="video4"
src="./shell-beach.mp4"
autoplay
loop
muted
preload="auto"
crossorigin="anonymous"
playsinline></video>
</template>
<video id="video3"
src="https://video.wixstatic.com/video/11062b_3da4a26484194105bde5b3935f5afb7b/480p/mp4/file.mp4"
autoplay
loop
muted
preload="auto"
crossorigin="anonymous"
playsinline></video>
<template id="videos3">
<video id="video5"
src="./man-on-beach.mp4"
autoplay
loop
muted
preload="auto"
crossorigin="anonymous"
playsinline></video>
</template>
<nav>
<ul>
<li>
<a href="#displacement-transition">Displacement transition</a>
</li>
<li>
<a href="#fade-hue">Cross-fade with hue-rotation</a>
</li>
<li>
<a href="#turbulence">Fractal noise displacement</a>
</li>
</ul>
</nav>
<header>
<button id="nav-on">
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="arcs"><line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line></svg>
</button>
<button id="nav-off">
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="arcs"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
</button>
</header>
<main>
<section id="displacement-transition">
<p>
Transition between 2 videos with a displacement effect.<br/>
Hover the video to see it in action.<br/>
* On mobile tap inside/outside the video.
</p>
<iframe id="preview1" srcdoc="" sandbox="allow-scripts allow-same-origin"></iframe>
<div class="code-container">
<button class="refresh-button" id="refresh1">Refresh</button>
<textarea id="code1"></textarea>
</div>
</section>
<section id="fade-hue">
<p>
Transition between 2 videos with a cross-fade effect & apply a hue-rotate filter.<br/>
Move the mouse (tap on mobile) around over the video to see it in action.
</p>
<iframe id="preview2" srcdoc="" sandbox="allow-scripts allow-same-origin"></iframe>
<div class="code-container">
<button class="refresh-button" id="refresh2">Refresh</button>
<textarea id="code2"></textarea>
</div>
</section>
<section id="turbulence">
<p>
Paint turbulence noise, animate it, and use it as a displacement map for the video.
</p>
<iframe id="preview3" srcdoc="" sandbox="allow-scripts allow-same-origin"></iframe>
<div class="code-container">
<button class="refresh-button" id="refresh3">Refresh</button>
<textarea id="code3"></textarea>
</div>
</section>
</main>
<video id="video4"
src="https://video.wixstatic.com/video/11062b_62f64d80001a4490b6cc785d64359c6c/480p/mp4/file.mp4"
autoplay
loop
muted
preload="auto"
crossorigin="anonymous"
playsinline></video>
<!--<video id="video7"-->
<!--src="https://video.wixstatic.com/video/11062b_830709c744404d6ea7a10dcfd88e3a48/480p/mp4/file.mp4"-->
<!--autoplay-->
<!--loop-->
<!--muted-->
<!--preload="auto"-->
<!--crossorigin="anonymous"-->
<!--playsinline></video>-->
<!--<video id="video8"-->
<!--src="https://video.wixstatic.com/video/11062b_ba2c921477734f8b84ef0c71f64a2562/480p/mp4/file.mp4"-->
<!--autoplay-->
<!--loop-->
<!--muted-->
<!--preload="auto"-->
<!--crossorigin="anonymous"-->
<!--playsinline></video>-->
<!--<canvas id="target"></canvas>-->
<!--<canvas id="target2"></canvas>-->
<!--<canvas id="target3"></canvas>-->
<section>
<h2>Displacement transition:</h2>
<canvas id="target1"></canvas>
<textarea id="code1"></textarea>
</section>
<section>
<h2>Cross-fade transition with hue-rotation:</h2>
<canvas id="target2"></canvas>
<textarea id="code2"></textarea>
</section>
<script src="../index.js"></script>
<script src="./lib/codemirror/codemirror.js"></script>

@@ -205,2 +293,5 @@ <script src="./lib/codemirror/javascript.js"></script>

const text1 = document.querySelector('#code1');
const preview1 = document.querySelector('#preview1');
const videos1 = document.querySelector('#videos1');
const refresh1 = document.querySelector('#refresh1');

@@ -211,9 +302,19 @@ fetch('./disp.js')

text1.value = text;
CodeMirror.fromTextArea(text1, {
const doc = CodeMirror.fromTextArea(text1, {
value: text,
lineNumbers: true
lineNumbers: true,
theme: 'dracula'
});
const update = () => updatePreview(preview1, doc.getValue(), videos1.innerHTML);
refresh1.addEventListener('click', update);
update();
});
const text2 = document.querySelector('#code2');
const preview2 = document.querySelector('#preview2');
const videos2 = document.querySelector('#videos2');
const refresh2 = document.querySelector('#refresh2');

@@ -224,7 +325,36 @@ fetch('./hue-fade.js')

text2.value = text;
CodeMirror.fromTextArea(text2, {
const doc = CodeMirror.fromTextArea(text2, {
value: text,
lineNumbers: true
lineNumbers: true,
theme: 'dracula'
});
const update = () => updatePreview(preview2, doc.getValue(), videos2.innerHTML);
refresh2.addEventListener('click', update);
update();
});
const text3 = document.querySelector('#code3');
const preview3 = document.querySelector('#preview3');
const videos3 = document.querySelector('#videos3');
const refresh3 = document.querySelector('#refresh3');
fetch('./turbulence.js')
.then(resp => resp.text())
.then(text => {
text3.value = text;
const doc = CodeMirror.fromTextArea(text3, {
value: text,
lineNumbers: true,
theme: 'dracula'
});
const update = () => updatePreview(preview3, doc.getValue(), videos3.innerHTML);
refresh3.addEventListener('click', update);
update();
});
</script>

@@ -231,0 +361,0 @@ <script src="index.js"></script>

(function () {
'use strict';
/*
* Most simple image loader
* You'll probably have something like this already
*/
function loadImage$1 (src) {
return new Promise(resolve => {
const img = new Image();
img.onload = function () {
resolve(this);
};
img.src = src;
});
function updatePreview (iframe, example, videos) {
iframe.setAttribute('srcdoc', getIFrameHTML({example, videos}));
}
window.loadImage = loadImage$1;
/*
* Minimal, cross-browser logic for playing videos and making sure
* they are ready to work with
*/
function prepareVideos$1 (videos) {
return new Promise(resolve => {
let playing = 0;
let timeupdate = 0;
function canPlay (e) {
e.target.play();
}
const isPlaying = e => {
playing += 1;
e.target.removeEventListener('playing', isPlaying, true);
check();
};
const isTimeupdate = (e) => {
timeupdate += 1;
e.target.removeEventListener('timeupdate', isTimeupdate, true);
check();
};
const check = () => {
if (playing === videos.length && timeupdate === videos.length) {
videos.forEach(vid => {
vid.removeEventListener('canplay', canPlay, true);
});
resolve();
}
};
videos.forEach(vid => {
vid.addEventListener('playing', isPlaying, true);
vid.addEventListener('timeupdate', isTimeupdate, true);
vid.addEventListener('canplay', canPlay, true);
});
});
function getIFrameHTML ({example, videos}) {
return `<!DOCTYPE html>
<html>
<head>
<style>
body, html {margin: 0; height: 100%; overflow: hidden;}
canvas {width: 100%; height: 100%;}
video {display: none;}
</style>
<script src="../index.js"></script>
<script src="./utils.js"></script>
</head>
<body>
${videos}
<canvas id="target"></canvas>
<script>
${example}
</script>
</body>
</html>`;
}
window.prepareVideos = prepareVideos$1;
window.updatePreview = updatePreview;
const {Kampos, transitions} = window.kampos;
const transitionDisplacement = transitions.displacement;
const navOffHandler = () => document.body.classList.remove('nav-open');
/*
* Wrapper class for transition logic.
* This is a simple vanilla implementation
*/
class Transition {
constructor ({vid1, vid2, target, disp, dispScale}) {
/*
* prepare here everything we need
*/
this.vid1 = vid1;
this.vid2 = vid2;
this.target = target;
this.dispScale = dispScale;
this.transition = transitionDisplacement();
document.querySelector('#nav-on')
.addEventListener('click', () => {
document.body.classList.add('nav-open');
this.direction = 1;
this.startTime = 0;
// init kampos
this.kampos = new Kampos({target, effects: [this.transition]});
// load the displacement map image
const dispReady = loadImage(disp);
// make sure videos are loaded and playing
prepareVideos([this.vid1, this.vid2])
.then(() => {
const width = this.vid1.videoWidth;
const height = this.vid1.videoHeight;
dispReady.then(img => {
/*
* set transition values
*/
this.transition.map = img;
this.transition.to = this.vid2;
this.transition.sourceScale = {x: this.dispScale};
this.transition.toScale = {x: -this.dispScale};
// set media source
this.kampos.setSource({media: this.vid1, width, height});
// start kampos
this.kampos.play();
});
});
}
/*
* start animation playback forward
*/
forward () {
this.direction = 1;
this.startTime = Date.now();
this.loop();
}
/*
* start animation playback backwards
*/
backward () {
this.direction = 0;
this.startTime = Date.now();
this.loop();
}
/*
* This will probably be a callback you'll provide to your animation library
*/
tick (p) {
this.transition.progress = p;
}
/*
* This will usually be implemented by an animation library you may already have in your project
*/
loop () {
const now = Date.now() - this.startTime;
// dividing by 500 is just enough to slow down the effect
let p = Math.abs(Math.sin(now / 500));
p = this.direction ? p : 1 - p;
this.tick(p);
let nextTick = () => this.loop();
// we choose a cutoff value where the progress value
// is almost 0/1, depending on direction
// and then stop the animation by just rendering
// 1 extra tick with the final value (0 or 1 respectively).
if (this.direction) {
if (p * 100 >= 99) {
nextTick = () => this.tick(1);
}
}
else if (p * 100 <= 1) {
nextTick = () => this.tick(0);
}
window.requestAnimationFrame(nextTick);
}
}
const video1 = document.querySelector('#video1');
const video2 = document.querySelector('#video2');
const target1 = document.querySelector('#target1');
const trans = new Transition({
vid1: video1,
vid2: video2,
target: target1,
disp: 'disp-snow.jpg',
dispScale: 1.0
});
/*
* register event handlers for interaction
*/
target1.addEventListener('mouseenter', () => trans.forward());
target1.addEventListener('mouseleave', () => trans.backward());
const {Kampos: Kampos$1, effects, transitions: transitions$1} = window.kampos;
const media1 = document.querySelector('#video3');
const media2 = document.querySelector('#video4');
const target = document.querySelector('#target2');
// create the effects/transitions we need
const hueSat = effects.hueSaturation();
const fade = transitions$1.fade();
// init kampos
const instance = new Kampos$1({target, effects:[fade, hueSat]});
// make sure videos are loaded and playing
prepareVideos([media1, media2])
.then(() => {
const width = media1.videoWidth;
const height = media1.videoHeight;
// set media source
instance.setSource({media: media1, width, height});
// set media to transition into
fade.to = media2;
// start kampos
instance.play();
setTimeout(() => document.body.addEventListener('click', navOffHandler, {once: true}), 0);
});
let x, y, rect;
let drawing = false;
// this is invoked once in every animation frame, while there's a mouse move over the canvas
function tick () {
fade.progress = Math.max(0, Math.min(1, (y - rect.y) / rect.height));
hueSat.hue = Math.max(0, Math.min(1, (x - rect.x) / rect.width)) * 360 - 180;
drawing = false;
}
// handler for detecting mouse move
const moveHandler = e => {
const {clientX, clientY} = e;
// cache mouse location
x = clientX;
y = clientY;
// only once! a frame
if (!drawing) {
drawing = true;
// read here
rect = target.getBoundingClientRect();
// write on next frame
requestAnimationFrame(tick);
}
};
/*
* register event handlers for interaction
*/
target.addEventListener('mouseenter', () => {
target.addEventListener('mousemove', moveHandler);
});
target.addEventListener('mouseleave', () => {
target.removeEventListener('mousemove', moveHandler);
});
}());

@@ -18,2 +18,3 @@ toc:

- displacement
- turbulence
- brightnessContrastEffect

@@ -24,2 +25,3 @@ - hueSaturationEffect

- displacementEffect
- turbulenceEffect
- name: transitions

@@ -26,0 +28,0 @@ children:

{
"name": "kampos",
"version": "0.2.2",
"version": "0.3.0",
"description": "Tiny and fast effects compositor on WebGL",

@@ -5,0 +5,0 @@ "registry": "https://registry.npmjs.org/",

+16
-12

@@ -1,2 +0,6 @@

# kampos
<p align="center">
<img width="100" src="./kampos.svg?sanitize=true">
</p>
# kampos [![Build Status](https://travis-ci.com/wix-incubator/kampos.svg?branch=master)](https://travis-ci.com/wix-incubator/kampos)
### Tiny and fast effects compositor on WebGL

@@ -6,9 +10,9 @@

Just like [SVG filter effects](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Filter_effects),
only using WebGL, and hence works everywhere!
only using WebGL, which means it works everywhere!
## Demo
Watch a [live demo](https://wix-incubator.github.io/kampos/demo/).
Check out the [live demo](https://wix-incubator.github.io/kampos/demo/).
## Documentation
For API reference and examples read [the docs](https://wix-incubator.github.io/kampos/docs/).
For API reference and examples, read [the docs](https://wix-incubator.github.io/kampos/docs/).

@@ -24,3 +28,3 @@ ## Features

Here's a simple example for using kampos:
```
```javascript
import {Kampos, effects} from 'kampos';

@@ -44,3 +48,3 @@

### npm example:
```
```bash
npm install kampos

@@ -50,9 +54,9 @@ ```

Import the default build:
```
```javascript
import {Kampos, Ticker, effects, transitions} from 'kampos';
```
Or just what you need:
```
import {Kampos} from './node_modules/kampos/src/kampos';
Or take just what you need:
```javascript
import Kampos from './node_modules/kampos/src/kampos';
import duotone from './node_modules/kampos/src/effects/duotone';

@@ -63,3 +67,3 @@ import displacement from './node_modules/kampos/src/effects/displacement';

## Building locally
```
```bash
npm install

@@ -70,3 +74,3 @@ npm run build

## Running tests
```
```bash
npm run test

@@ -73,0 +77,0 @@ ```

@@ -10,3 +10,3 @@ export default {

const vertexTemplate = ({
const vertexSimpleTemplate = ({
uniform = '',

@@ -21,2 +21,22 @@ attribute = '',

${attribute}
attribute vec2 a_position;
${varying}
const vec3 lumcoeff = vec3(0.2125, 0.7154, 0.0721);
${constant}
void main() {
${main}
gl_Position = vec4(a_position.xy, 0.0, 1.0);
}`;
const vertexMediaTemplate = ({
uniform = '',
attribute = '',
varying = '',
constant = '',
main = ''
}) => `
precision mediump float;
${uniform}
${attribute}
attribute vec2 a_texCoord;

@@ -35,3 +55,3 @@ attribute vec2 a_position;

const fragmentTemplate = ({
const fragmentSimpleTemplate = ({
uniform = '',

@@ -45,2 +65,23 @@ varying = '',

${varying}
${uniform}
const vec3 lumcoeff = vec3(0.2125, 0.7154, 0.0721);
${constant}
void main() {
${source}
vec3 color = vec3(0.0);
float alpha = 1.0;
${main}
gl_FragColor = vec4(color, 1.0) * alpha;
}`;
const fragmentMediaTemplate = ({
uniform = '',
varying = '',
constant = '',
main = '',
source = ''
}) => `
precision mediump float;
${varying}
varying vec2 v_texCoord;

@@ -66,10 +107,12 @@ ${uniform}

* @private
* @param {WebGLRenderingContext} gl
* @param effects
* @param dimensions
* @param {Object} config
* @param {WebGLRenderingContext} config.gl
* @param {Object[]} config.effects
* @param {{width: number, heignt: number}} [config.dimensions]
* @param {boolean} [config.noSource]
* @return {{gl: WebGLRenderingContext, data: kamposSceneData, [dimensions]: {width: number, height: number}}}
*/
function init (gl, effects, dimensions) {
function init ({gl, effects, dimensions, noSource}) {
const programData = _initProgram(gl, effects);
const programData = _initProgram(gl, effects, noSource);

@@ -163,7 +206,9 @@ return {gl, data: programData, dimensions: dimensions || {}};

// bind the source texture
gl.bindTexture(gl.TEXTURE_2D, source.texture);
if ( media && source && source.texture ) {
// bind the source texture
gl.bindTexture(gl.TEXTURE_2D, source.texture);
// read source data into texture
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, media);
// read source data into texture
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, media);
}

@@ -215,3 +260,4 @@ // Tell it to use our program (pair of shaders)

// delete texture
gl.deleteTexture(source.texture);
if ( source && source.texture )
gl.deleteTexture(source.texture);

@@ -226,4 +272,4 @@ // delete program

function _initProgram (gl, effects) {
const source = {
function _initProgram (gl, effects, noSource=false) {
const source = noSource || {
texture: createTexture(gl).texture,

@@ -233,9 +279,11 @@ buffer: null

// flip Y axis for source texture
gl.bindTexture(gl.TEXTURE_2D, source.texture);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
if ( source ) {
// flip Y axis for source texture
gl.bindTexture(gl.TEXTURE_2D, source.texture);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
}
const data = _mergeEffectsData(effects);
const vertexSrc = _stringifyShaderSrc(data.vertex, vertexTemplate);
const fragmentSrc = _stringifyShaderSrc(data.fragment, fragmentTemplate);
const data = _mergeEffectsData(effects, noSource);
const vertexSrc = _stringifyShaderSrc(data.vertex, noSource ? vertexSimpleTemplate : vertexMediaTemplate);
const fragmentSrc = _stringifyShaderSrc(data.fragment, noSource ? fragmentSimpleTemplate : fragmentMediaTemplate);

@@ -266,6 +314,6 @@ // compile the GLSL program

function _mergeEffectsData (effects) {
function _mergeEffectsData (effects, noSource=false) {
return effects.reduce((result, config) => {
const {attributes = [], uniforms = [], textures = [], varying = {}} = config;
const merge = shader => Object.keys(config[shader]).forEach(key => {
const merge = shader => Object.keys(config[shader] || {}).forEach(key => {
if ( key === 'constant' || key === 'main' || key === 'source' ) {

@@ -302,3 +350,47 @@ result[shader][key] += config[shader][key] + '\n';

return result;
}, {
}, getEffectDefaults(noSource));
}
function getEffectDefaults (noSource) {
/*
* Default uniforms
*/
const uniforms = noSource ? [] : [
{
name: 'u_source',
type: 'i',
data: [0]
}
];
/*
* Default attributes
*/
const attributes = [
{
name: 'a_position',
data: new Float32Array([
-1.0, -1.0,
-1.0, 1.0,
1.0, -1.0,
1.0, 1.0]),
size: 2,
type: 'FLOAT'
}
];
if ( ! noSource ) {
attributes.push({
name: 'a_texCoord',
data: new Float32Array([
0.0, 0.0,
0.0, 1.0,
1.0, 0.0,
1.0, 1.0]),
size: 2,
type: 'FLOAT'
});
}
return {
vertex: {

@@ -318,42 +410,9 @@ uniform: {},

},
attributes,
uniforms,
/*
* Default attributes
*/
attributes: [
{
name: 'a_position',
data: new Float32Array([
-1.0, -1.0,
-1.0, 1.0,
1.0, -1.0,
1.0, 1.0]),
size: 2,
type: 'FLOAT'
},
{
name: 'a_texCoord',
data: new Float32Array([
0.0, 0.0,
0.0, 1.0,
1.0, 0.0,
1.0, 1.0]),
size: 2,
type: 'FLOAT'
}
],
/*
* Default uniforms
*/
uniforms: [
{
name: 'u_source',
type: 'i',
data: [0]
}
],
/*
* Default textures
*/
textures: []
});
};
}

@@ -360,0 +419,0 @@

@@ -11,4 +11,7 @@ /**

* @property {boolean} disabled
* @property {boolean} isLuminance
*
* @example
* @description Multiplies `alpha` value with values read from `mask` media source.
*
* @example
* const img = new Image();

@@ -30,2 +33,3 @@ * img.src = 'picture.png';

u_alphaMaskEnabled: 'bool',
u_alphaMaskIsLuminance: 'bool',
u_mask: 'sampler2D'

@@ -35,3 +39,10 @@ },

if (u_alphaMaskEnabled) {
alpha *= texture2D(u_mask, v_alphaMaskTexCoord).a;
vec4 alphaMaskPixel = texture2D(u_mask, v_alphaMaskTexCoord);
if (u_alphaMaskIsLuminance) {
alpha *= dot(lumcoeff, alphaMaskPixel.rgb) * alphaMaskPixel.a;
}
else {
alpha *= alphaMaskPixel.a;
}
}`

@@ -51,2 +62,9 @@ },

},
get isLuminance () {
return !!this.uniforms[2].data[0];
},
set isLuminance (toggle) {
this.uniforms[2].data[0] = +toggle;
this.textures[0].format = toggle ? 'RGBA' : 'ALPHA';
},
varying: {

@@ -65,2 +83,7 @@ v_alphaMaskTexCoord: 'vec2'

data: [1]
},
{
name: 'u_alphaMaskIsLuminance',
type: 'i',
data: [0]
}

@@ -67,0 +90,0 @@ ],

@@ -20,3 +20,2 @@ /**

return {
vertex: {},
fragment: {

@@ -23,0 +22,0 @@ uniform: {

@@ -10,3 +10,3 @@ /**

* @property {ArrayBufferView|ImageData|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement|ImageBitmap} map
* @property {{x: number, y: number}} scale
* @property {{x: number?, y: number?}} scale
* @property {boolean} disabled

@@ -13,0 +13,0 @@ *

@@ -9,4 +9,4 @@ /**

* @typedef {Object} duotoneEffect
* @property {number[]} light Array of 4 numbers normalized (0.0 - 1.0)
* @property {number[]} dark Array of 4 numbers normalized (0.0 - 1.0)
* @property {number[]} light Array of 4 numbers, normalized (0.0 - 1.0)
* @property {number[]} dark Array of 4 numbers, normalized (0.0 - 1.0)
* @property {boolean} disabled

@@ -19,3 +19,2 @@ *

return {
vertex: {},
fragment: {

@@ -22,0 +21,0 @@ uniform: {

@@ -6,2 +6,4 @@ import alphaMask from './effects/alpha-mask';

import displacement from './effects/displacement';
import perlinNoise from './noise/perlin-noise-3d';
import turbulence from './effects/turbulence';
import fade from './transitions/fade';

@@ -18,3 +20,4 @@ import displacementTransition from './transitions/displacement';

duotone,
displacement
displacement,
turbulence
},

@@ -25,4 +28,7 @@ transitions: {

},
noise: {
perlinNoise
},
Kampos,
Ticker
};
import core from './core';
/**
* Initialize a webgl target with effects.
* Initialize a WebGL target with effects.
*

@@ -9,7 +9,7 @@ * @class Kampos

* @example
* import {Ticker, Kampos, effects} from 'kampos';
* const ticker = new Ticker();
* import { Kampos, effects} from 'kampos';
*
* const target = document.querySelector('#canvas');
* const hueSat = effects.hueSaturation();
* const kampos = new Kampos({ticker, target, effects: [hueSat]});
* const kampos = new Kampos({target, effects: [hueSat]});
*/

@@ -87,6 +87,6 @@ export default class Kampos {

/**
* Initializes an Kampos instance.
* Initializes a Kampos instance.
* This is called inside the constructor,
* but can be called again after effects have changed
* or after {@link Kampos#desotry()}.
* or after {@link Kampos#destroy}.
*

@@ -98,3 +98,3 @@ * @param {kamposConfig} [config] defaults to `this.config`

config = config || this.config;
let {target, effects, ticker} = config;
let {target, effects, ticker, noSource} = config;

@@ -124,3 +124,3 @@ if ( Kampos.preventContextCreation )

const {data} = core.init(gl, effects, this.dimensions);
const {data} = core.init({gl, effects, dimensions: this.dimensions, noSource});

@@ -189,2 +189,7 @@ this.gl = gl;

const cb = this.config.beforeDraw;
if ( cb && cb() === false )
return;
core.draw(this.gl, this.media, this.data, this.dimensions);

@@ -196,5 +201,9 @@ }

*
* If using a {@see Ticker} this instance will be added to that {@see Ticker}.
* If a {@link Ticker} is used, this instance will be added to that {@link Ticker}.
*
* @param {function} beforeDraw function to run before each draw call
*/
play () {
play (beforeDraw) {
this.config.beforeDraw = beforeDraw;
if ( this.ticker ) {

@@ -224,3 +233,3 @@ if ( this.animationFrameId ) {

*
* If using a {@see Ticker} this instance will be removed from that {@see Ticker}.
* If a {@link Ticker} is used, this instance will be removed from that {@link Ticker}.
*/

@@ -240,5 +249,5 @@ stop () {

/**
* Stops animation loop and frees all resources.
* Stops the animation loop and frees all resources.
*
* @param {boolean} keepState for internal use.
* @param {boolean} keepState for internal use.
*/

@@ -329,2 +338,4 @@ destroy (keepState) {

* @property {Ticker} [ticker]
* @property {boolean} [noSource]
* @property {function} [beforeDraw] function to run before each draw call. If it returns `false` {@link kampos#draw} will not be called.
* @property {function} [onContextLost]

@@ -357,4 +368,4 @@ * @property {function} [onContextRestored]

* @property {string} [constant]
* @property {Object} [uniform] mapping name of variable to type
* @property {Object} [attribute] mapping name of variable to type
* @property {Object} [uniform] mapping variable name to type
* @property {Object} [attribute] mapping variable name to type
*/

@@ -361,0 +372,0 @@

/**
* Initialize a ticker instance for batching animation of multiple Kampos instances.
* Initialize a ticker instance for batching animation of multiple {@link Kampos} instances.
*

@@ -34,3 +34,3 @@ * @class Ticker

/**
* Invoke draw() on all instances in the pool.
* Invoke `.draw()` on all instances in the pool.
*/

@@ -37,0 +37,0 @@ draw () {

@@ -12,4 +12,4 @@ /**

* @property {number} progress number between 0.0 and 1.0
* @property {{x: number, y: number}} sourceScale
* @property {{x: number, y: number}} toScale
* @property {{x: number?, y: number?}} sourceScale
* @property {{x: number?, y: number?}} toScale
* @property {boolean} disabled

@@ -16,0 +16,0 @@ *

@@ -25,3 +25,3 @@ const core = require('./src/core');

const canvas = document.createElement('canvas');
const {gl, data} = core.init(core.getWebGLContext(canvas), [brightnessContrast]);
const {gl, data} = core.init({gl: core.getWebGLContext(canvas), effects: [brightnessContrast]});

@@ -36,3 +36,3 @@ assert(gl);

const canvas = document.createElement('canvas');
const {gl, data} = core.init(core.getWebGLContext(canvas), [brightnessContrast]);
const {gl, data} = core.init({gl: core.getWebGLContext(canvas), effects: [brightnessContrast]});

@@ -70,3 +70,3 @@ assert(gl);

const initData = core.init(core.getWebGLContext(canvas), [brightnessContrast]);
const initData = core.init({gl: core.getWebGLContext(canvas), effects: [brightnessContrast]});

@@ -92,3 +92,3 @@ gl = initData.gl;

const initData = core.init(core.getWebGLContext(canvas), [brightnessContrast]);
const initData = core.init({gl: core.getWebGLContext(canvas), effects: [brightnessContrast]});

@@ -134,3 +134,3 @@ gl = initData.gl;

core.destroy(gl, scene);
const initData2fx = core.init(core.getWebGLContext(canvas), [brightnessContrast]);
const initData2fx = core.init({gl: core.getWebGLContext(canvas), effects: [brightnessContrast]});

@@ -161,3 +161,3 @@ gl = initData2fx.gl;

const initData = core.init(core.getWebGLContext(canvas), [brightnessContrast]);
const initData = core.init({gl: core.getWebGLContext(canvas), effects: [brightnessContrast]});

@@ -164,0 +164,0 @@ gl = initData.gl;

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display