Skip to content

Hero section #23

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 17 commits into
base: refresh
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Deploy

env:
NODE_VERSION: 17
ZOLA_VERSION: 0.16.1

on:
push:
branches: ["master"]
pull_request:
branches: ["master"]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v3

- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}

- name: Install Zola
run: |
set -x
wget -O - \
"https://github.com/getzola/zola/releases/download/v${ZOLA_VERSION}/zola-v${ZOLA_VERSION}-x86_64-unknown-linux-gnu.tar.gz" \
| sudo tar xzf - -C /usr/local/bin

- name: Install dependencies
run: npm install

- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
2 changes: 2 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@
[submodule "etro"]
path = etro
url = https://github.com/etro-js/etro.git
[submodule "etro/"]
url = https://github.com/etro-js/etro.git
6 changes: 1 addition & 5 deletions content/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,9 @@ npm install etro

# Usage

Include it with
```js
<script src="node_modules/etro/dist/etro-iife.js"></script>
```
import etro from 'etro'

Let's look at an example:
```js
var movie = new etro.Movie({ canvas: outputCanvas })
var layer = new etro.layer.Video({ startTime: 0, source: videoElement }) // the layer starts at 0s
movie.addLayer(layer)
Expand Down
13 changes: 9 additions & 4 deletions content/docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ weight = 0

<div class="heading-text">Documentation</div>

<!-- - [Getting Started](getting-started) -->
- [Tutorial](tutorial)
- [Migrating to v0.8.0](migrating-v0-8-0)
- [API Reference](api)
Welcome to the Etro documentation!

- To learn the fundamentals of Etro, check out the [reference](reference)
section
- To use Etro in a React app, check out the [Webcam
Filter](guides/webcam-filter) guide
- The full API documentation can be found [here](api)
- To learn how to migrate from Etro v0.7 to v0.8, check out the [migration
guide](migrating-v0-8-0)
276 changes: 276 additions & 0 deletions content/docs/guides/webcam-filter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,276 @@
+++
title = "Webcam Filter"
template = "page.html"
+++

<div class="heading-text">Webcam Filter</div>

In this guide, we'll create a simple webcam filter using React and Etro.

## Setting up the React app

First, we'll set up a new React app using
[create-react-app](https://create-react-app.dev):

```bash
npx create-react-app webcam-filter
cd webcam-filter
```

## Installing Etro

Now, we'll install Etro:

```bash
npm install etro
```

## Creating the movie

Now, we'll create a new movie, add a webcam layer to it, and play it.

Create a new file `src/Movie.js`:

```js
import React, { useEffect, useRef } from "react";
import etro from "etro";

export default function Movie() {
const canvasRef = useRef();
const movieRef = useRef();

useEffect(() => {
// Use the canvas ref to get the canvas element
const canvas = canvasRef.current;

// Create a new movie instance
const movie = new etro.Movie({ canvas });

// Get the user's webcam stream
navigator.mediaDevices
.getUserMedia({ video: true })

// Create a video element from the stream
.then((stream) => {
const video = document.createElement("video");
video.srcObject = stream;
return new Promise((resolve) => {
video.onloadedmetadata = () => {
resolve(video);
};
});
})

// Add a video layer to the movie and play it
.then((video) => {
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
const layer = new etro.layer.Video({
startTime: 0,
source: video,
});
movie.addLayer(layer);
movie.play();
movieRef.current = movie;
});
}, []);

return <canvas ref={canvasRef} />;
}
```

Use the `Movie` component in `src/App.js`:

```js
import React from 'react'
import Movie from './Movie'

function App() {
return (
<div className="App">
<Movie />
</div>
)
}
```

## Adding an effect

Now, we'll add an effect to the webcam layer.

Create a new file `src/effect.js`:

```js
import etro from "etro";

export default class SaturationEffect extends etro.effect.Shader {
constructor(options = {}) {
super({
fragmentSource: `
precision highp float;

uniform sampler2D u_Source;
uniform float u_Saturation;

varying vec2 v_TextureCoord;

void main() {
vec4 color = texture2D(u_Source, v_TextureCoord);
float luminance = dot(color.rgb, vec3(0.2126, 0.7152, 0.0722));
gl_FragColor = vec4(mix(vec3(luminance), color.rgb, u_Saturation), color.a);
}
`,
uniforms: {
saturation: "1f",
},
});

this.saturation = options.saturation || 1;
}
}
```

Next we need to add the effect to the layer. We'll do this in `src/Movie.js`.

Import the effect:

```diff
import React, { useEffect, useRef } from "react";
import etro from "etro";
+import SaturationEffect from "./effect";
```

Add a `saturation` property to the `Movie` component:

```diff
-export default function Movie() {
+export default function Movie({ saturation = 1 }) {
```

Create a ref to store the effect instance:

```diff
export default function Movie() {
const canvasRef = useRef();
const movieRef = useRef();
+ const effectRef = useRef();
```

Add the effect to the layer:

```diff
const layer = new etro.layer.Video({
startTime: 0,
source: video,
});
+ const effect = new SaturationEffect();
+ layer.addEffect(effect);
+
movie.addLayer(layer);
movie.play();
movieRef.current = movie;
+ effectRef.current = effect;
});
```

Now, update the effect when the `saturation` prop changes:

```diff
movie.play();

effectRef.current = effect;
movieRef.current = movie;
});
}, []);
+
+ useEffect(() => {
+ if (effectRef.current) {
+ effectRef.current.saturation = saturation;
+ }
+ }, [saturation]);
```

Finally, we can pass a temporary `saturation` value to the `Movie` component in
`src/App.js`:

```diff
import React from 'react'
import Movie from './Movie'

function App() {
return (
<div className="App">
- <Movie />
+ <Movie saturation={0.5} />
</div>
)
}
```

## Changing the saturation

Now, we'll add a slider to change the saturation.

Create a new file `src/Slider.js`:

```js
import React from "react";

export default function Slider({ value, onChange }) {
return (
<input
type="range"
min="0"
max="1"
step="0.01"
value={value}
onChange={(e) => onChange(e.target.value)}
/>
);
}
```

Now, import the slider in `src/App.js`:

```diff
import React from 'react'
import Movie from './Movie'
+import Slider from './Slider'

function App() {
return (
<div className="App">
<Movie />
+ <Slider />
</div>
)
}
```

Next, we'll add a state variable to the app to store the saturation value. This
value will be modified by the slider and passed to the effect:

```diff
import React from 'react'
import Movie from './Movie'
import Slider from './Slider'

function App() {
+ const [saturation, setSaturation] = React.useState(1)
+
return (
<div className="App">
- <Movie saturation={0.5} />
- <Slider />
+ <Movie saturation={saturation} />
+ <Slider value={saturation} onChange={setSaturation} />
</div>
)
}
```

## Conclusion

That's it! You've created a webcam app with a saturation effect. If you have
any questions, feel free to ask them in the [etro Discord
server](https://discord.gg/myrBsQ8Cht).
13 changes: 13 additions & 0 deletions content/docs/reference.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
+++
title = "Reference"
template = "page.html"
+++

<div class="heading-text">Reference</div>

\+ [Framework Overview](overview)<br/>
\+ [Movies](movies) <br/>
\+ [Layers](layers) <br/>
\+ [Effects](effects) <br/>
\+ [Dynamic Properties](dynamic-properties) <br/>
\+ [Property Filters](property-filters) <br/>
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ movie.height = 200 // also sets the canvas's height to 200
```

Now we have a 200x200 movie, but there are no layers so nothing will be
rendered. In the [next section](layers), we'll add a video clip to the movie.
rendered. In the [next section](../layers), we'll add a video clip to the
movie.
Loading