├── .gitignore
├── .travis.yml
├── Aquarelle.js
├── AquarellePass.js
├── LICENSE
├── README.md
├── Screenshots
└── web__transition__effect_ramotion.gif
├── bower.json
├── deploy-to-gh-pages.sh
├── examples
├── bower.json
├── example_scroll.html
├── img
│ ├── bg.png
│ ├── icon01.png
│ ├── icon02.png
│ ├── icon03.png
│ ├── jobs.jpg
│ ├── logo.png
│ ├── mask.png
│ ├── mouse.svg
│ ├── splash.png
│ ├── title.png
│ └── top_menu.png
└── index.html
└── header.png
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .DS_Store
3 | examples/bower_components/
4 | examples/.git
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | before_script:
3 | - npm install -g bower
4 | script:
5 | - bash ./deploy-to-gh-pages.sh
6 | env:
7 | global:
8 | - GITHUB_REPO: "Ramotion/aquarelle"
9 | - secure: "jbYrk4ft6krPuSanHopdtgUAUknFVS1m0+fokfS9FJWhsuOqmfP59EKF4mQpPk2ywLIu25NxPF6PuK26sk+8JVmiI4a+ycQIgjjbo/SStzJBy6mCTuXDjU1jJN8W3z20yf3+ltFtJuPmrE6nTZ+FAhmRk/Fp/A2TjjQsmz+ZlnCjTWjuiLEEkXY9nkqrceftUBt4BvHRcqn3vWp8ipDAiP52MJ9lArk4nHe6URcAvURk4QEuQ6bu8hRyysI8/ukSnVFHD4vYvn1T2ed5U3KgJqiayVJD32epSyYFixx+aLpwmJyMTrRpOkjCoxNwn6yDN4sKHuox5pUyWP2wzdSCvJCTrwHc2N+End5/n9YTOTM2UX75mtaMRTsg+lrngg3rQvCjdxGMXD4uM6u1r1KLvocYjOSM4P1sttV7g3Tu/Gmp5BCYC++snoG3SDlbfu2shtf8gARO7MnM5lpo8+NnkBT2NtUh9/g5RAbUkXbNLqs4pFhdg7wN/ieRLPqRIWK5d/zJZfGsUpLtqLrqfXZOU4nrxF6quGfTKJ1zdFj6GQIKvbfr7YQSVa79121Khmfb2xDX8/SLb/D5qVbF4pxXX3lpzVT9qXFVqLlBLCoBpH7XPvM1ys6v06VvZN8ML2TyMVSe43oTvQoFip6t2ss+RTN+4+Y2oHgaTk2gw9uo9gU="
--------------------------------------------------------------------------------
/Aquarelle.js:
--------------------------------------------------------------------------------
1 | var THREE = window.THREE || {};
2 |
3 | (function() {
4 | var stack = [];
5 | var lastTime = Date.now();
6 |
7 | // Thanks https://github.com/d3 for the plugin
8 | function contour(grid) {
9 | var s = [];
10 | var c = [];
11 | var x = s ? s[0] : 0;
12 | var y = s ? s[1] : 0;
13 | var dx = 0;
14 | var dy = 0;
15 | var pdx = NaN;
16 | var pdy = NaN;
17 | var i = 0;
18 |
19 | while(true) {
20 | if(grid(x, y)) {
21 | s = [x, y];
22 | break;
23 | }
24 | if(x) {
25 | x = x - 1;
26 | y = y + 1;
27 | } else {
28 | x = y + 1;
29 | y = 0;
30 | }
31 | }
32 |
33 | do {
34 | i = 0;
35 |
36 | if(grid(x - 1, y - 1)) {
37 | i += 1;
38 | }
39 | if(grid(x, y - 1)) {
40 | i += 2;
41 | }
42 | if(grid(x - 1, y)) {
43 | i += 4;
44 | }
45 | if(grid(x, y)) {
46 | i += 8;
47 | }
48 |
49 | if(i === 6) {
50 | dx = pdy === -1 ? -1 : 1;
51 | dy = 0;
52 | } else
53 | if(i === 9) {
54 | dx = 0;
55 | dy = pdx === 1 ? -1 : 1;
56 | } else {
57 | dx = [1, 0, 1, 1, -1, 0, -1, 1, 0, 0, 0, 0, -1, 0, -1, NaN][i];
58 | dy = [0, -1, 0, 0, 0, -1, 0, 0, 1, -1, 1, 1, 0, -1, 0, NaN][i];
59 | }
60 |
61 | if(dx != pdx && dy != pdy) {
62 | c.push([x, y]);
63 | pdx = dx;
64 | pdy = dy;
65 | }
66 |
67 | x += dx;
68 | y += dy;
69 | } while(s[0] != x || s[1] != y);
70 |
71 | return c;
72 | }
73 |
74 | function Aquarelle(texture, mask, options) {
75 | var self = this;
76 |
77 | self.setOptions(Aquarelle.defaultOptions);
78 | self.setOptions(options);
79 |
80 | self.mask = {};
81 |
82 | self.mask.canvas = document.createElement('canvas');
83 | self.mask.ctx = self.mask.canvas.getContext('2d');
84 |
85 | if(typeof mask === 'string') {
86 | self.mask.img = new Image;
87 | self.mask.img.onload = function() {
88 | self.drawMaskImage();
89 | };
90 | self.mask.crossOrigin = 'Anonymous';
91 | self.mask.img.src = mask;
92 | } else
93 | if(mask.nodeName && mask.src) {
94 | self.mask.img = mask;
95 | self.drawMaskImage();
96 | }
97 |
98 | THREE.ImageUtils.crossOrigin = '';
99 | new THREE.TextureLoader().load(texture && (typeof texture === 'string' ? texture : texture.nodeName && texture.src) || '', function(texture) {
100 | self.texture = texture;
101 | texture.minFilter = THREE.LinearFilter;
102 |
103 | var composer = self.getComposer();
104 |
105 | composer.addPass(new THREE.ClearPass);
106 |
107 | var mask = new THREE.Texture(self.mask.canvas);
108 | mask.needsUpdate = true;
109 | mask.minFilter = THREE.LinearFilter;
110 |
111 | var turbulentPass = self.turbulentPass = new THREE.AquarellePass(texture, mask);
112 | composer.addPass(turbulentPass);
113 |
114 | var outputPass = new THREE.ShaderPass(THREE.CopyShader);
115 | outputPass.renderToScreen = true;
116 | composer.addPass(outputPass);
117 |
118 | self.dispatchEvent(self.getEventObject('created'));
119 |
120 | if(self.options.autoplay) {
121 | self.start();
122 | }
123 |
124 | self.reset();
125 |
126 | self.isInitialized = true;
127 | });
128 |
129 | stack.push(self);
130 | }
131 |
132 | Object.assign(Aquarelle.prototype, THREE.EventDispatcher.prototype);
133 |
134 | Aquarelle.prototype.getRenderer = function() {
135 | if(!this.renderer) {
136 | var renderer = this.renderer = new THREE.WebGLRenderer({
137 | alpha: true
138 | });
139 | renderer.setClearColor(0x000000, 0);
140 | renderer.setSize(this.texture.image.width, this.texture.image.height);
141 | renderer.autoClear = false;
142 | }
143 |
144 | return this.renderer;
145 | };
146 | Aquarelle.prototype.getCanvas = function() {
147 | return this.getRenderer().domElement;
148 | };
149 | Aquarelle.prototype.getComposer = function() {
150 | if(!this.composer) {
151 | this.composer = new THREE.EffectComposer(this.getRenderer(), new THREE.WebGLRenderTarget(this.texture.image.width, this.texture.image.height));
152 | }
153 |
154 | return this.composer;
155 | };
156 |
157 | Aquarelle.prototype.drawMaskImage = function() {
158 | var mask = this.mask || {};
159 |
160 | if(mask.img) {
161 | mask.canvas.width = mask.img.width;
162 | mask.canvas.height = mask.img.height;
163 |
164 | mask.ctx.drawImage(mask.img, 0, 0);
165 |
166 | var data = mask.ctx.getImageData(0, 0, mask.img.width, mask.img.height).data;
167 | mask.points = contour(function(x, y) {
168 | return data[(y * mask.img.width + x) * 4 + 3] > 0;
169 | });
170 | }
171 | };
172 | Aquarelle.prototype.renderMask = function() {
173 | var mask = this.mask || {};
174 |
175 | if(!mask.points) {
176 | return;
177 | }
178 |
179 | mask.ctx.clearRect(0, 0, mask.canvas.width, mask.canvas.height);
180 |
181 | mask.ctx.lineJoin = 'round';
182 | mask.ctx.lineWidth = Math.abs(mask.offset) * 2;
183 |
184 | if(mask.offset) {
185 | mask.ctx.globalCompositeOperation = 'source-' + (mask.offset < 0 ? 'out' : 'over');
186 |
187 | this.pathPoints();
188 | mask.ctx.stroke();
189 | }
190 |
191 | this.pathPoints();
192 | mask.ctx.fill();
193 | };
194 | Aquarelle.prototype.pathPoints = function() {
195 | var mask = this.mask || {};
196 |
197 | mask.ctx.beginPath();
198 | mask.points.forEach(function(point, index) {
199 | mask.ctx[index ? 'lineTo' : 'moveTo'](point[0], point[1]);
200 | });
201 | mask.ctx.closePath();
202 | };
203 |
204 | Aquarelle.prototype.direction = 1;
205 | Aquarelle.prototype.progress = 1;
206 | Aquarelle.prototype.isPaused = true;
207 |
208 | Aquarelle.prototype.render = function(delta) {
209 | if(!this.turbulentPass || !this.composer) {
210 | return;
211 | }
212 |
213 | var lastProgress = this.progress;
214 | var progress = this.clampedProgress(lastProgress + this.direction * delta / (this.options.duration / 1000));
215 |
216 | if(!this.isPaused && lastProgress !== progress) {
217 | this.progress = progress;
218 | this.reset();
219 | }
220 |
221 | this.renderMask();
222 | this.getRenderer().clear();
223 | this.getComposer().render(delta);
224 | };
225 |
226 | Aquarelle.prototype.transitionForProgressInRange = function(progress, startValue, endValue) {
227 | return startValue + (endValue - startValue) * progress;
228 | };
229 | Aquarelle.prototype.progressForValueInRange = function(value, startValue, endValue) {
230 | return (value - startValue) / (endValue - startValue);
231 | };
232 | Aquarelle.prototype.clampedProgress = function(progress) {
233 | return Math.max(0, Math.min(progress, 1));
234 | };
235 |
236 | Aquarelle.prototype.transitionInRange = function(startValue, endValue, startTime, endTime) {
237 | return this.transitionForProgressInRange(this.clampedProgress(this.progressForValueInRange(this.progress, (startTime || 0) / this.options.duration, (endTime || this.options.duration) / this.options.duration)), startValue, endValue);
238 | };
239 |
240 | Aquarelle.prototype.isComplete = function() {
241 | return this.direction > 0 ? this.progress === 1 : this.direction < 0 && !this.progress;
242 | };
243 |
244 | Aquarelle.prototype.pause = function() {
245 | if(this.isPaused) {
246 | return;
247 | }
248 |
249 | this.isPaused = true;
250 |
251 | if(this.isInitialized) {
252 | this.dispatchEvent(this.getEventObject('paused'));
253 | }
254 | };
255 | Aquarelle.prototype.play = function() {
256 | if(!this.isPaused) {
257 | return;
258 | }
259 |
260 | this.isPaused = false;
261 |
262 | this.dispatchEvent(this.getEventObject('played'));
263 | };
264 | Aquarelle.prototype.stop = function() {
265 | if(this.progress === +(this.direction >= 0) && this.isPaused) {
266 | return;
267 | }
268 |
269 | this.progress = +(this.direction >= 0);
270 |
271 | this.pause();
272 |
273 | if(this.isInitialized) {
274 | this.dispatchEvent(this.getEventObject('stopped'));
275 | }
276 | };
277 | Aquarelle.prototype.start = function() {
278 | if(this.progress === +(this.direction < 0) && !this.isPaused) {
279 | return;
280 | }
281 |
282 | this.progress = +(this.direction < 0);
283 |
284 | this.dispatchEvent(this.getEventObject('started'));
285 |
286 | this.play();
287 | };
288 |
289 | Aquarelle.prototype.reverse = function() {
290 | this.direction = this.direction < 0 ? 1 : -1;
291 | };
292 | Aquarelle.prototype.reset = function() {
293 | if(!this.turbulentPass) {
294 | return;
295 | }
296 |
297 | this.turbulentPass.uniforms.Amplitude.value = this.transitionInRange(this.options.fromAmplitude, this.options.toAmplitude);
298 | this.turbulentPass.uniforms.Frequency.value = this.transitionInRange(this.options.fromFrequency, this.options.toFrequency);
299 | this.mask.offset = this.transitionInRange(this.options.fromOffset, this.options.toOffset);
300 |
301 | this.turbulentPass.uniforms.Mask.value.needsUpdate = true;
302 |
303 | this.dispatchEvent(this.getEventObject('changed'));
304 |
305 | if(this.isComplete()) {
306 | this.dispatchEvent(this.getEventObject('completed'));
307 |
308 | var isPaused = this.isPaused;
309 | this.stop();
310 | }
311 | if(this.isComplete() && this.options.loop && !isPaused) {
312 | this.start();
313 | }
314 | };
315 |
316 | Aquarelle.prototype.getEventObject = function(type) {
317 | return {
318 | type: type,
319 | timeStamp: Date.now(),
320 | direction: this.direction,
321 | progress: this.progress,
322 | isComplete: this.isComplete()
323 | };
324 | };
325 |
326 | Aquarelle.prototype.setOptions = function(options) {
327 | if(typeof options === 'object' && options !== null) {
328 | this.options = Object.assign(this.options || {}, options);
329 | }
330 | };
331 |
332 | Aquarelle.defaultOptions = {
333 | fromAmplitude: 50,
334 | toAmplitude: 0,
335 |
336 | fromFrequency: 8,
337 | toFrequency: 7,
338 |
339 | fromOffset: -30,
340 | toOffset: 28,
341 |
342 | autoplay: false,
343 | loop: false,
344 | duration: 8000
345 | };
346 |
347 | function frame() {
348 | var time = Date.now();
349 | var deltaTime = time - lastTime;
350 |
351 | lastTime = time;
352 |
353 | stack.forEach(function(item) {
354 | item.render(deltaTime / 1000);
355 | });
356 |
357 | requestAnimationFrame(frame);
358 | }
359 | frame();
360 |
361 | window.Aquarelle = Aquarelle;
362 | }());
--------------------------------------------------------------------------------
/AquarellePass.js:
--------------------------------------------------------------------------------
1 | var THREE = window.THREE || {};
2 |
3 | THREE.AquarellePass = function(texture, mask) {
4 | THREE.Pass.call(this);
5 |
6 | this.uniforms = {
7 | Texture: {
8 | type: 't',
9 | value: texture
10 | },
11 | Mask: {
12 | type: 't',
13 | value: mask
14 | },
15 | Amplitude: {
16 | type: 'f',
17 | value: 50
18 | },
19 | Frequency: {
20 | type: 'f',
21 | value: 10
22 | }
23 | };
24 |
25 | this.material = new THREE.ShaderMaterial({
26 | uniforms: this.uniforms,
27 | vertexShader: [
28 | 'varying vec2 vUv;',
29 |
30 | 'void main() {',
31 | 'vUv = uv;',
32 | 'gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1);',
33 | '}'
34 | ].join('\n'),
35 | fragmentShader: [
36 | '// Uniform variables.',
37 | 'uniform sampler2D Texture;',
38 | 'uniform sampler2D Mask;',
39 |
40 | 'uniform float Amplitude;',
41 | 'uniform float Frequency;',
42 |
43 |
44 | '// Varying variables.',
45 | 'varying vec2 vUv;',
46 |
47 |
48 | '// Description : Array and textureless GLSL 3D simplex noise function.',
49 | '// Author : Ian McEwan, Ashima Arts.',
50 | '// Maintainer : ijm',
51 | '// Lastmod : 20110822 (ijm)',
52 | '// License : Copyright (C) 2011 Ashima Arts. All rights reserved.',
53 | '// Distributed under the MIT License. See LICENSE file.',
54 | '// https://github.com/ashima/webgl-noise',
55 | 'vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }',
56 | 'vec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }',
57 | 'vec4 permute(vec4 x) { return mod289(((x*34.0)+1.0)*x); }',
58 | 'vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; }',
59 | 'float snoise(vec3 v)',
60 | '{',
61 | 'const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;',
62 | 'const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);',
63 |
64 | '// First corner',
65 | 'vec3 i = floor(v + dot(v, C.yyy) );',
66 | 'vec3 x0 = v - i + dot(i, C.xxx) ;',
67 |
68 | '// Other corners',
69 | 'vec3 g = step(x0.yzx, x0.xyz);',
70 | 'vec3 l = 1.0 - g;',
71 | 'vec3 i1 = min( g.xyz, l.zxy );',
72 | 'vec3 i2 = max( g.xyz, l.zxy );',
73 |
74 | '// x0 = x0 - 0.0 + 0.0 * C.xxx;',
75 | '// x1 = x0 - i1 + 1.0 * C.xxx;',
76 | '// x2 = x0 - i2 + 2.0 * C.xxx;',
77 | '// x3 = x0 - 1.0 + 3.0 * C.xxx;',
78 | 'vec3 x1 = x0 - i1 + C.xxx;',
79 | 'vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y',
80 | 'vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y',
81 |
82 | '// Permutations',
83 | 'i = mod289(i);',
84 | 'vec4 p = permute( permute( permute(',
85 | 'i.z + vec4(0.0, i1.z, i2.z, 1.0 ))',
86 | '+ i.y + vec4(0.0, i1.y, i2.y, 1.0 ))',
87 | '+ i.x + vec4(0.0, i1.x, i2.x, 1.0 ));',
88 |
89 | '// Gradients: 7x7 points over a square, mapped onto an octahedron.',
90 | '// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)',
91 | 'float n_ = 0.142857142857; // 1.0/7.0',
92 | 'vec3 ns = n_ * D.wyz - D.xzx;',
93 |
94 | 'vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)',
95 |
96 | 'vec4 x_ = floor(j * ns.z);',
97 | 'vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)',
98 |
99 | 'vec4 x = x_ *ns.x + ns.yyyy;',
100 | 'vec4 y = y_ *ns.x + ns.yyyy;',
101 | 'vec4 h = 1.0 - abs(x) - abs(y);',
102 |
103 | 'vec4 b0 = vec4( x.xy, y.xy );',
104 | 'vec4 b1 = vec4( x.zw, y.zw );',
105 |
106 | '//vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;',
107 | '//vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;',
108 | 'vec4 s0 = floor(b0)*2.0 + 1.0;',
109 | 'vec4 s1 = floor(b1)*2.0 + 1.0;',
110 | 'vec4 sh = -step(h, vec4(0.0));',
111 |
112 | 'vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;',
113 | 'vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;',
114 |
115 | 'vec3 p0 = vec3(a0.xy,h.x);',
116 | 'vec3 p1 = vec3(a0.zw,h.y);',
117 | 'vec3 p2 = vec3(a1.xy,h.z);',
118 | 'vec3 p3 = vec3(a1.zw,h.w);',
119 |
120 | '//Normalise gradients',
121 | 'vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));',
122 | 'p0 *= norm.x;',
123 | 'p1 *= norm.y;',
124 | 'p2 *= norm.z;',
125 | 'p3 *= norm.w;',
126 |
127 | '// Mix final noise value',
128 | 'vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);',
129 | 'm = m * m;',
130 | 'return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3) ) );',
131 | '}',
132 |
133 |
134 | 'void main() {',
135 | 'vec2 offset;',
136 |
137 | 'float noise = snoise(vec3(vUv * Frequency, 0)) * 3.14;',
138 | 'offset = vec2(cos(noise), sin(noise)) * Amplitude * .001;',
139 |
140 | 'vec4 texture = texture2D(Texture, vUv + offset);',
141 |
142 |
143 | 'vec2 shift = vUv;',
144 |
145 | 'float largeNoise = snoise(vec3(vUv * 20.0, 0));',
146 | 'shift += vec2(cos(largeNoise), sin(largeNoise)) * .07;',
147 |
148 | 'float smallNoise = snoise(vec3(vUv * 70.0, 0));',
149 | 'shift += vec2(cos(smallNoise), sin(smallNoise)) * .02;',
150 |
151 | 'vec4 mask = texture2D(Mask, shift);',
152 |
153 |
154 | 'gl_FragColor = vec4(texture.r, texture.g, texture.b, mask.a);',
155 | '}'
156 | ].join('\n'),
157 | transparent: true
158 | });
159 |
160 | this.needsSwap = false;
161 |
162 | this.camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);
163 | this.scene = new THREE.Scene;
164 |
165 | this.quad = new THREE.Mesh(new THREE.PlaneBufferGeometry(2, 2));
166 | this.scene.add(this.quad);
167 | };
168 |
169 | THREE.AquarellePass.prototype = Object.assign(Object.create(THREE.Pass.prototype), {
170 | constructor: THREE.AquarellePass,
171 |
172 | render: function(renderer, writeBuffer, readBuffer) {
173 | this.quad.material = this.material;
174 |
175 | renderer.render(this.scene, this.camera, readBuffer, this.clear);
176 | }
177 | });
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Ramotion
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://www.ramotion.com/agency/app-development?utm_source=gthb&utm_medium=special&utm_campaign=aquarelle)
2 | [](https://ramotion.github.io/aquarelle/)
3 |
4 | # Aquarelle
5 | [](https://www.codacy.com/app/juri-v/aquarelle?utm_source=github.com&utm_medium=referral&utm_content=Ramotion/aquarelle&utm_campaign=Badge_Grade)
6 | []()
7 | [](http://twitter.com/Ramotion)
8 | [](https://travis-ci.org/Ramotion/aquarelle)
9 | [](https://paypal.me/Ramotion)
10 |
11 |
12 | ## About
13 | This project is maintained by Ramotion, Inc.
14 | We specialize in the designing and coding of custom UI for Mobile Apps and Websites.
15 |
16 | **Looking for developers for your project?**
17 | This project is maintained by Ramotion, Inc. We specialize in the designing and coding of custom UI for Mobile Apps and Websites.
18 |
19 |
20 |
21 |
22 | ## Browser support
23 |
24 | * Chrome
25 | * Safari
26 | * Opera
27 | * Firefox
28 | * IE 11
29 |
30 | ## Installation
31 |
32 | `bower install aquarelle`
33 |
34 | Then insert in your html:
35 |
36 | ```html
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | ```
48 |
49 |
50 | ## API
51 |
52 | ### Constructor
53 |
54 | `new Aquarelle(textureImage, maskImage[, options]);`
55 |
56 | | Names | Required | Type | Description
57 | | --- | --- | --- | ---
58 | | textureImage | `true` | `string`, `Image` or `
` | background image
59 | | maskImage | `true` | `string`, `Image` or `
` | background image mask
60 | | options | `false` | `object` | initial options
61 |
62 | ### Options
63 |
64 | | Names | Defaults | Description
65 | | --- | --- | ---
66 | | fromAmplitude | `50` | initial noise amplitude value
67 | | toAmplitude | `0` | final noise amplitude value
68 | | fromFrequency | `8` | initial noise frequiency
69 | | toFrequency | `7` | final noise frequiency
70 | | fromOffset | `-30` | initial mask size
71 | | autoplay | `false` | `true` - start animation before first frame is being rendered
72 | | loop | `false` | `true` - repeat animation in loop
73 | | duration | `8000` | animation duration
74 |
75 | ### Events
76 |
77 | | Names | Description
78 | | --- | ---
79 | | created | triggered before first frame is rendered
80 | | changed | triggered before rendering of a frame
81 | | completed | triggered before latest frame is rendered
82 | | started | triggered before animation is started
83 | | played | triggered after animation is started
84 | | paused | triggered before pause of animation
85 | | stopped | triggered before reset of animation
86 |
87 | ### Methods
88 |
89 | | Names | Description
90 | | --- | ---
91 | | `pause()` | pause animation
92 | | `play()` | start animation
93 | | `stop()` | stop and reset animation
94 | | `start()` | start animation over
95 | | `reverse()` | reverse animation
96 | | `reset()` | re-render frame
97 | | `setOptions([object])` | set animation options
98 | | `transitionInRange(startValue, endValue[, startTimeMS[, endTimeMS]])` | return value between `startValue`..`endValue` in range `startTimeMS`..`endTimeMS`
99 | | `addEventListener(type, listener)` | add listener (`listener`) of event (`type`)
100 | | `removeEventListener(type, listener)` | remove (`listener`) of event (`type`)
101 |
102 |
103 | ## Usage
104 |
105 | ≈
106 |
107 | ```javascript
108 | var aquarelle = new Aquarelle(textureImage, maskImage[, options]);
109 | ```
110 |
111 | ##### Listeners
112 |
113 | ```javascript
114 | function listener(event) {}
115 |
116 | aquarelle.addEventListener('created', listener);
117 |
118 | aquarelle.removeEventListener('created', listener);
119 | ```
120 | ##### Demos
121 |
122 | [Static demo](http://ramotion.github.io/aquarelle)
123 |
124 | [Dynamic demo](https://ramotion.github.io/aquarelle/example_scroll.html)
125 |
126 | ## Licence
127 |
128 | Aquarelle is released under the MIT license.
129 | See [LICENSE](./LICENSE) for details.
130 |
131 | # Get the Showroom App for iOS to give it a try
132 | Try our UI components in our iOS app. Contact us if interested.
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 | Follow us for the latest updates
141 |
142 |
143 |
144 |
145 |
--------------------------------------------------------------------------------
/Screenshots/web__transition__effect_ramotion.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/aquarelle/aef4c7cd9fc4ab482559f49447822a1df169216d/Screenshots/web__transition__effect_ramotion.gif
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "aquarelle",
3 | "main": "aquarelle.js",
4 | "homepage": "https://ramotion.com",
5 | "authors": [
6 | "juri.v@ramotion.com"
7 | ],
8 | "description": "watercolor animation",
9 | "moduleType": [
10 | "amd"
11 | ],
12 | "keywords": [
13 | "aquarelle",
14 | "watercolor",
15 | "animation",
16 | "transition"
17 | ],
18 | "license": "MIT",
19 | "ignore": [
20 | "**/.*",
21 | "node_modules",
22 | "bower_components",
23 | "test",
24 | "tests"
25 | ],
26 | "dependencies": {
27 | "three.js": "threejs#*"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/deploy-to-gh-pages.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -o errexit
3 |
4 | # config
5 | git config --global user.email "nobody@nobody.org"
6 | git config --global user.name "Travis CI"
7 |
8 | # deploy
9 | cd examples
10 | bower install
11 | rm -rf .git
12 | git init
13 | git add .
14 | git commit -m "Deploy to Github Pages"
15 | git push --force --quiet "https://${GITHUB_TOKEN}@github.com/${GITHUB_REPO}.git" master:gh-pages
--------------------------------------------------------------------------------
/examples/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "examples",
3 | "homepage": "https://github.com/Ramotion/aquarelle",
4 | "authors": [
5 | "yury "
6 | ],
7 | "license": "MIT",
8 | "dependencies": {
9 | "aquarelle": "*"
10 | },
11 | "ignore": [
12 | "**/.*",
13 | "bower_components"
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/examples/example_scroll.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
60 |
61 |
62 |
68 |
Scroll down
69 |
70 |
71 |
108 |
109 |
110 |
--------------------------------------------------------------------------------
/examples/img/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/aquarelle/aef4c7cd9fc4ab482559f49447822a1df169216d/examples/img/bg.png
--------------------------------------------------------------------------------
/examples/img/icon01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/aquarelle/aef4c7cd9fc4ab482559f49447822a1df169216d/examples/img/icon01.png
--------------------------------------------------------------------------------
/examples/img/icon02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/aquarelle/aef4c7cd9fc4ab482559f49447822a1df169216d/examples/img/icon02.png
--------------------------------------------------------------------------------
/examples/img/icon03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/aquarelle/aef4c7cd9fc4ab482559f49447822a1df169216d/examples/img/icon03.png
--------------------------------------------------------------------------------
/examples/img/jobs.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/aquarelle/aef4c7cd9fc4ab482559f49447822a1df169216d/examples/img/jobs.jpg
--------------------------------------------------------------------------------
/examples/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/aquarelle/aef4c7cd9fc4ab482559f49447822a1df169216d/examples/img/logo.png
--------------------------------------------------------------------------------
/examples/img/mask.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/aquarelle/aef4c7cd9fc4ab482559f49447822a1df169216d/examples/img/mask.png
--------------------------------------------------------------------------------
/examples/img/mouse.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
--------------------------------------------------------------------------------
/examples/img/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/aquarelle/aef4c7cd9fc4ab482559f49447822a1df169216d/examples/img/splash.png
--------------------------------------------------------------------------------
/examples/img/title.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/aquarelle/aef4c7cd9fc4ab482559f49447822a1df169216d/examples/img/title.png
--------------------------------------------------------------------------------
/examples/img/top_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/aquarelle/aef4c7cd9fc4ab482559f49447822a1df169216d/examples/img/top_menu.png
--------------------------------------------------------------------------------
/examples/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
113 |
114 |
115 |

116 |
120 |
121 |
126 |
127 |
128 |
168 |
169 |
170 |
--------------------------------------------------------------------------------
/header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/aquarelle/aef4c7cd9fc4ab482559f49447822a1df169216d/header.png
--------------------------------------------------------------------------------