Skip to content

Commit

Permalink
Kaleidoscope improvements (#53)
Browse files Browse the repository at this point in the history
* Improvements to Kaleidoscope effect;
Added rotation;
Changed offset to object;
Changed repeat to mirrored repeat

* 0.13.0

* Updated docs

* Added package-lock.json

* Use python 3.9.6

* Use python 3.10

* Removed gl dep and python version fix

* 0.13.1

* Fixed version

* Fixed build and tests

* Try python 3.9

* Try overriding node-gyp to 10.3.0

* Revert fixing python version to 3.9

* Try lower node.js maybe

* Try node-gyp 11

* Update package-lock

* Just give up for now on unit tests

* Just drop node-canvas

* Try putting back deps for noce-canvas

* Workaround to fix "No usable sandbox!" error

* Try disabling pptr sandbox
  • Loading branch information
ydaniv authored Dec 9, 2024
1 parent f64706b commit 14d7e18
Show file tree
Hide file tree
Showing 16 changed files with 13,253 additions and 82 deletions.
6 changes: 0 additions & 6 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,9 @@ jobs:
name: List the state of node modules
continue-on-error: true
run: npm list
- name: Install node-canvas dependencies
run: |
sudo apt update
sudo apt install -y libcairo2-dev libjpeg-dev libpango1.0-dev libgif-dev librsvg2-dev libxt-dev libxi-dev libgl-dev libxext-dev
- name: Install dependencies
run: npm install
- name: Build
run: npm run build
- name: Unit tests
run: xvfb-run npm run test:unit
- name: E2e tests
run: xvfb-run npm run test:e2e
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
node_modules/
package-lock.json

test/src/*.js

Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
### 0.13.1 (2024-12-09)

_New:_

- Added `rotation` property to `kaleidoscope` effect.

_Breaking:_

- Kaleidoscope effect now does mirrored-repeat instead of simple repeat.
- Changed `Kaleidoscope.offset` from a `number` to an object of `{ x: number, y: number }`.

### 0.12.0 (2024-12-04)

_New:_
Expand Down
8 changes: 0 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,6 @@ npm install
npm run build
```

If npm install fails on node-gyp on MacOS run the following:

```
brew install pkg-config cairo pango libpng jpeg giflib librsvg pixman
```

[source and other OS](https://github.com/Automattic/node-canvas#compiling)

## Running tests

```bash
Expand Down
4 changes: 3 additions & 1 deletion demo/kaleidoscope.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ prepareVideos([media]).then(() => {

target.addEventListener('pointermove', (e) => {
const { offsetX, offsetY } = e;
kaleidoscope.offset = offsetX / width - 0.5;
const x = offsetX / width - 0.5;
const y = offsetY / height - 0.5;
kaleidoscope.offset = { x, y };
});
});
46 changes: 33 additions & 13 deletions dist/index.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -1236,39 +1236,46 @@ function channelSplit({
/**
* @function kaleidoscope
* @param {Object} [params]
* @param {number} [params.segments=6] .
* @param {number} [params.offset=0] .
* @param {number} [params.segments=6] number of times the view is divided.
* @param {number} [params.offset={x: 0.0, y: 0.0}] offset to move the source media from the center.
* @param {number} [params.rotation=0] extra angle to rotate the view.
* @returns {kaleidoscopeEffect}
*
* @example kaleidoscope({segments: 12})
*/
function kaleidoscope ({ segments = 6, offset = 0 } = {}) {
function kaleidoscope ({ segments = 6, offset, rotation = 0 } = {}) {
const { x: offsetX, y: offsetY } = offset || { x: 0.0, y: 0.0 };
/**
* @typedef {Object} kaleidoscopeEffect
* @property {number} segments
* @property {number} offset
* @property {{x: number?, y: number?}} offset
* @property {number} rotation
* @property {boolean} disabled
*
* @example
* effect.segments = 8;
* effect.offset = 0.5;
* effect.offset = { x: 0.5, y: 0.5 };
* effect.rotation = 45;
*/
return {
fragment: {
uniform: {
u_kaleidoscopeEnabled: 'bool',
u_segments: 'float',
u_offset: 'float',
u_offset: 'vec2',
u_rotation: 'float',
},
source: `
if (u_kaleidoscopeEnabled) {
if (u_kaleidoscopeEnabled && u_segments > 0.0) {
vec2 centered = v_texCoord - 0.5;
float r = length(centered);
float theta = atan(centered.y, centered.x);
theta = mod(theta, 2.0 * PI / u_segments);
theta = mod(theta, 2.0 * PI / u_segments) + radians(u_rotation);
theta = abs(theta - PI / u_segments) - PI / u_segments;
vec2 newCoords = r * vec2(cos(theta), sin(theta)) + 0.5;
sourceCoord = mod(newCoords - u_offset, 1.0);
sourceCoord = newCoords - u_offset;
// mirrored repeat
sourceCoord = mod(-sourceCoord, 1.0) * (mod(sourceCoord - 1.0, 2.0) - mod(sourceCoord, 1.0)) + mod(sourceCoord, 1.0) * (mod(sourceCoord, 2.0) - mod(sourceCoord, 1.0));
}`,
},
get segments() {
Expand All @@ -1278,10 +1285,18 @@ function kaleidoscope ({ segments = 6, offset = 0 } = {}) {
this.uniforms[1].data[0] = +n;
},
get offset() {
return this.uniforms[2].data[0];
const [x, y] = this.uniforms[2].data;
return { x, y };
},
set offset(o) {
this.uniforms[2].data[0] = +o;
set offset({ x, y }) {
if (typeof x !== 'undefined') this.uniforms[2].data[0] = x;
if (typeof y !== 'undefined') this.uniforms[2].data[1] = y;
},
get rotation() {
return this.uniforms[3].data[0];
},
set rotation(r) {
this.uniforms[3].data[0] = r;
},
get disabled() {
return !this.uniforms[0].data[0];
Expand All @@ -1303,7 +1318,12 @@ function kaleidoscope ({ segments = 6, offset = 0 } = {}) {
{
name: 'u_offset',
type: 'f',
data: [offset],
data: [offsetX, offsetY],
},
{
name: 'u_rotation',
type: 'f',
data: [rotation],
},
],
};
Expand Down
30 changes: 24 additions & 6 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset='utf-8'>
<title>kampos 0.11.7 | Documentation</title>
<title>kampos 0.13.0 | Documentation</title>
<meta name='description' content='Tiny and fast effects compositor on WebGL'>
<meta name='viewport' content='width=device-width,initial-scale=1'>
<link href='assets/bass.css' rel='stylesheet'>
Expand All @@ -15,7 +15,7 @@
<div id='split-left' class='overflow-auto fs0 height-viewport-100'>
<div class='py1 px2'>
<h3 class='mb0 no-anchor'>kampos</h3>
<div class='mb1'><code>0.11.7</code></div>
<div class='mb1'><code>0.13.0</code></div>
<input
placeholder='Filter'
id='filter-input'
Expand Down Expand Up @@ -3707,7 +3707,7 @@ <h3 class='fl m0' id='effects'>

(default <code>6</code>)
</td>
<td class='break-word'><span>.
<td class='break-word'><span>number of times the view is divided.
</span></td>
</tr>

Expand All @@ -3716,9 +3716,20 @@ <h3 class='fl m0' id='effects'>
<tr>
<td class='break-word'><span class='code bold'>params.offset</span> <code class='quiet'><a href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number">number</a></code>

(default <code>{x:0.0,y:0.0}</code>)
</td>
<td class='break-word'><span>offset to move the source media from the center.
</span></td>
</tr>



<tr>
<td class='break-word'><span class='code bold'>params.rotation</span> <code class='quiet'><a href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number">number</a></code>

(default <code>0</code>)
</td>
<td class='break-word'><span>.
<td class='break-word'><span>extra angle to rotate the view.
</span></td>
</tr>

Expand Down Expand Up @@ -4854,7 +4865,13 @@ <h3 class='fl m0' id='kaleidoscopeeffect'>
</div>

<div class='space-bottom0'>
<span class='code bold'>offset</span> <code class='quiet'>(<a href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number">number</a>)</code>
<span class='code bold'>offset</span> <code class='quiet'>({x: <a href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number">number</a>?, y: <a href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number">number</a>?})</code>


</div>

<div class='space-bottom0'>
<span class='code bold'>rotation</span> <code class='quiet'>(<a href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number">number</a>)</code>


</div>
Expand All @@ -4879,7 +4896,8 @@ <h3 class='fl m0' id='kaleidoscopeeffect'>


<pre class='p1 overflow-auto round fill-light'>effect.<span class="hljs-property">segments</span> = <span class="hljs-number">8</span>;
effect.<span class="hljs-property">offset</span> = <span class="hljs-number">0.5</span>;</pre>
effect.<span class="hljs-property">offset</span> = { <span class="hljs-attr">x</span>: <span class="hljs-number">0.5</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">0.5</span> };
effect.<span class="hljs-property">rotation</span> = <span class="hljs-number">45</span>;</pre>



Expand Down
46 changes: 33 additions & 13 deletions index.umd.js
Original file line number Diff line number Diff line change
Expand Up @@ -1240,39 +1240,46 @@ const mat3 satmat = mat3(
/**
* @function kaleidoscope
* @param {Object} [params]
* @param {number} [params.segments=6] .
* @param {number} [params.offset=0] .
* @param {number} [params.segments=6] number of times the view is divided.
* @param {number} [params.offset={x: 0.0, y: 0.0}] offset to move the source media from the center.
* @param {number} [params.rotation=0] extra angle to rotate the view.
* @returns {kaleidoscopeEffect}
*
* @example kaleidoscope({segments: 12})
*/
function kaleidoscope ({ segments = 6, offset = 0 } = {}) {
function kaleidoscope ({ segments = 6, offset, rotation = 0 } = {}) {
const { x: offsetX, y: offsetY } = offset || { x: 0.0, y: 0.0 };
/**
* @typedef {Object} kaleidoscopeEffect
* @property {number} segments
* @property {number} offset
* @property {{x: number?, y: number?}} offset
* @property {number} rotation
* @property {boolean} disabled
*
* @example
* effect.segments = 8;
* effect.offset = 0.5;
* effect.offset = { x: 0.5, y: 0.5 };
* effect.rotation = 45;
*/
return {
fragment: {
uniform: {
u_kaleidoscopeEnabled: 'bool',
u_segments: 'float',
u_offset: 'float',
u_offset: 'vec2',
u_rotation: 'float',
},
source: `
if (u_kaleidoscopeEnabled) {
if (u_kaleidoscopeEnabled && u_segments > 0.0) {
vec2 centered = v_texCoord - 0.5;
float r = length(centered);
float theta = atan(centered.y, centered.x);
theta = mod(theta, 2.0 * PI / u_segments);
theta = mod(theta, 2.0 * PI / u_segments) + radians(u_rotation);
theta = abs(theta - PI / u_segments) - PI / u_segments;
vec2 newCoords = r * vec2(cos(theta), sin(theta)) + 0.5;
sourceCoord = mod(newCoords - u_offset, 1.0);
sourceCoord = newCoords - u_offset;
// mirrored repeat
sourceCoord = mod(-sourceCoord, 1.0) * (mod(sourceCoord - 1.0, 2.0) - mod(sourceCoord, 1.0)) + mod(sourceCoord, 1.0) * (mod(sourceCoord, 2.0) - mod(sourceCoord, 1.0));
}`,
},
get segments() {
Expand All @@ -1282,10 +1289,18 @@ const mat3 satmat = mat3(
this.uniforms[1].data[0] = +n;
},
get offset() {
return this.uniforms[2].data[0];
const [x, y] = this.uniforms[2].data;
return { x, y };
},
set offset(o) {
this.uniforms[2].data[0] = +o;
set offset({ x, y }) {
if (typeof x !== 'undefined') this.uniforms[2].data[0] = x;
if (typeof y !== 'undefined') this.uniforms[2].data[1] = y;
},
get rotation() {
return this.uniforms[3].data[0];
},
set rotation(r) {
this.uniforms[3].data[0] = r;
},
get disabled() {
return !this.uniforms[0].data[0];
Expand All @@ -1307,7 +1322,12 @@ const mat3 satmat = mat3(
{
name: 'u_offset',
type: 'f',
data: [offset],
data: [offsetX, offsetY],
},
{
name: 'u_rotation',
type: 'f',
data: [rotation],
},
],
};
Expand Down
Loading

0 comments on commit 14d7e18

Please sign in to comment.