├── .editorconfig
├── .gitattributes
├── .github
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
└── FUNDING.yml
├── .gitignore
├── .npmignore
├── DOCUMENTATION.md
├── LICENSE.md
├── README.md
├── eslint.config.js
├── logo.png
├── package-lock.json
├── package.json
├── src
├── defaults.js
├── instacam.js
└── support.js
└── webpack.config.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | # top-most editorconfig file
2 | root = true
3 |
4 | # editor configuration
5 | [*]
6 | charset = utf-8
7 | end_of_line = lf
8 | indent_style = space
9 | indent_size = 2
10 | trim_trailing_whitespace = true
11 | insert_final_newline = true
12 |
13 | # preserve markdown line break
14 | [*.md]
15 | trim_trailing_whitespace = false
16 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files by default
2 | * text=auto
3 |
4 | # End of line as the UNIX convention (LF: Line Feed)
5 | * eol=lf
6 |
--------------------------------------------------------------------------------
/.github/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at hello@studiomotio.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | First of all, thank for taking time to contribute!
4 |
5 | The following is a set of guidelines for contributing to the project. These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request.
6 |
7 |
8 | #### Table Of Contents
9 |
10 | 1. [Code of conduct](#code-of-conduct)
11 | 2. [Reporting bugs](#reporting-bugs)
12 | 3. [Suggesting enhancements](#suggesting-enhancements)
13 |
14 |
15 | ## Code of conduct
16 |
17 | This project and everyone participating in it is governed by the [package code of conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to [xavier.foucrier@gmail.com](mailto:xavier.foucrier@gmail.com).
18 |
19 |
20 | ## Reporting bugs
21 |
22 | This section guides you through submitting a bug report for the package. Following these guidelines helps maintainers and the community understand your report, reproduce the behavior, and find related reports.
23 |
24 | Before creating bug reports, please **check the issues list** as you might find out that you don't need to create one. When you are creating a bug report, please include as many details as possible.
25 |
26 | ### Before submitting a bug report
27 |
28 | * **Perform a cursory search** to see if the problem has already been reported. If it has **and the issue is still open**, add a comment to the existing issue instead of opening a new one.
29 |
30 | ### How do I submit a (good) bug report?
31 |
32 | Bugs are tracked as [GitHub issues](https://guides.github.com/features/issues). After you've determined which repository your bug is related to, create an issue on that repository and provide the following information by filling in the template.
33 |
34 | * Use a **clear and descriptive title** for the issue to identify the problem
35 | * Describe the **exact steps** which reproduce the problem in as many details as possible
36 | * Explain which behavior **you expected to see** instead and why
37 | * Explain the problem and **include additional details** to help maintainers reproduce the problem
38 | * Include details about your **configuration and environment**
39 | * Include screenshots and animated GIFs if needed
40 | * Specify which version of the package you're using
41 |
42 |
43 | ## Suggesting enhancements
44 |
45 | This section guides you through submitting an enhancement suggestion for the package, including completely new features and minor improvements to existing functionality. Following these guidelines helps maintainers and the community understand your suggestion and find related suggestions.
46 |
47 | * Use a **clear and descriptive title** for the issue to identify the suggestion
48 | * Provide a **step-by-step description of the suggested enhancement** in as many details as possible
49 | * Describe the current behavior and explain **which behavior you expected to see** instead and why
50 | * Explain **why this enhancement would be useful** to most users
51 | * List some other applications **where this enhancement exists**
52 |
53 | Don't hesitate to use pull requests to propose code changes.
54 |
55 | Thanks for reading and happy contributing! :tada: :+1:
56 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: xavierfoucrier
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .dev
3 | /node_modules
4 | /dist
5 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .dev
3 | .editorconfig
4 | .eslintrc
5 | .gitattributes
6 | .gitignore
7 | CODE_OF_CONDUCT.md
8 | CONTRIBUTING.md
9 |
--------------------------------------------------------------------------------
/DOCUMENTATION.md:
--------------------------------------------------------------------------------
1 | # Instacam documentation
2 | Here you will find the documentation describing how to use the module.
3 |
4 | ## Summary
5 | 1. [How it works](#how-it-works)
6 | 2. [Markup](#markup)
7 | 3. [Usage](#usage)
8 | 4. [Data attributes](#data-attributes)
9 | 5. [Properties](#properties)
10 | 6. [Methods](#methods)
11 | 7. [Callbacks](#callbacks)
12 | 8. [Demo](#demo)
13 |
14 | ## How it works
15 | Instacam allows you to perform **instant canvas video** through the WebRTC API with a fresh touch of CSS filters: this means you can capture the webcam video stream *(media stream)* and broadcast it on an HTML5 `canvas` tag. Unlike the conventional HTML5 `video` tag, Instacam offers you the opportunity to **interact with the broadcasted media stream** by having the possibility to edit each pixels before they are drawn to the canvas. Moreover, Instacam can beautify the media stream by adding a fresh touch of CSS. Don't forget that Instacam only works on browsers that natively support the HTML5 `canvas` tag, `requestAnimationFrame` API, `HTMLMediaElement` API, `navigator.mediaDevices` and `Promises` API.
16 |
17 | ## Markup
18 | ### Viewport
19 | The viewport is a canvas representation of the media stream. Instacam captures the webcam media stream and replicates it on a canvas element, the viewport defined in the query selector must matched **a valid canvas element** to properly replicate the stream. An exception will be thrown on invalid viewport.
20 |
21 | ```html
22 |
23 | ```
24 |
25 | ## Usage
26 | ### Use with Webpack
27 | Instacam is using the **UMD** *(Unified Module Definition)* pattern, making it capable of working everywhere and compatible with webpack. The module is published on the **NPM** *(Node Package Manager)* registry, so you can install it through the command line interpreter using your favorite package manager:
28 |
29 | ```console
30 | # npm
31 | npm install instacam
32 |
33 | # yarn
34 | yarn add instacam
35 | ```
36 |
37 | This will **download and install** Instacam into the `node_modules` folder under your project directory. When it's done, you can start to use the module in one of your javascript file like this:
38 |
39 | ```js
40 | import Instacam from 'instacam';
41 |
42 | let camera = new Instacam(
43 | document.querySelector('#canvas1')
44 | );
45 | ```
46 |
47 | Using webpack has **many advantages** like output compression, code splitting, tree shaking, etc., so I encourage you to use this great tool with Instacam.
48 |
49 | ### Use with ESM
50 | As of May 2017, all major browsers have shipped a working implementation of **ESM** *(ECMAScript modules)*: this is another way of using Instacam directly in your browser:
51 |
52 | ```html
53 |
60 | ```
61 |
62 | > Note that you will need to **use the Instacam source files** as there is no ESM build today for this package
63 |
64 | ### Use with a CDN
65 | To rapidly **include the minified production** file in your webpage, load the latest build from a **CDN** *(Content Delivery Network)* using a generic script markup:
66 |
67 | ```html
68 |
69 |
70 |
71 |
72 |
73 | ```
74 |
75 | Then **instanciate the class** by using this javascript syntax:
76 |
77 | ```js
78 | let camera = new Instacam(
79 | document.querySelector('#canvas1')
80 | );
81 | ```
82 |
83 | You can also **pass a selector** to the constructor, and Instacam will get the DOM element for you:
84 |
85 | ```js
86 | let camera = new Instacam('#canvas1');
87 | ```
88 |
89 | **Custom defined properties** are passed through the second parameter:
90 |
91 | ```js
92 | let camera = new Instacam(
93 | document.querySelector('#canvas1'), {
94 | width: 800,
95 | height: 600
96 | }
97 | );
98 | ```
99 |
100 | ## Data attributes
101 | Instacam add a set of `data-instacam-*` attributes in the DOM to easily add custom styles/scripts in your application.
102 |
103 | - `data-instacam`
104 | - `data-instacam-viewport`
105 | - `data-instacam-stream`
106 | - `data-instacam-buffer`
107 | - `data-instacam-blend`
108 |
109 |
110 | ## Properties
111 | ### Getting property
112 | The class properties are stored in the private `_props` attribute but can be **retrieved easily**. If you want to get the current level of the saturation CSS filter, you can do the following:
113 |
114 | ```js
115 | // get the saturation (pretend that `camera` is the instance of the Instacam class)
116 | let saturation = camera.saturation;
117 | ```
118 |
119 | ### Setting property
120 | The class properties can be **setted easily**. If you want to set the current level of the brightness CSS filter, you can do the following:
121 |
122 | ```js
123 | // set the brightness (pretend that `camera` is the instance of the Instacam class)
124 | camera.brightness = 5;
125 | ```
126 |
127 | ### API
128 | Instacam reference that details all properties of the class.
129 |
130 | #### width
131 | Type: `Length`
132 | Default: `400`
133 |
134 | This represents **the ideal requested width** for the viewport. Depending on hardware capabilities, the device will try to be as close as possible to this value. If the requested width is not supported, it will fall back to the closest available width.
135 |
136 | #### height
137 | Type: `Length`
138 | Default: `300`
139 |
140 | This represents **the ideal requested height** for the viewport. Depending on hardware capabilities, the device will try to be as close as possible to this value. If the requested height is not supported, it will fall back to the closest available height.
141 |
142 | #### autostart
143 | Type: `Boolean`
144 | Default: `true`
145 |
146 | The autostart property allows you to **change the start behavior**. By default, Instacam capture the webcam stream when the class is instanciated. If you set this property to `false`, you will need to call the `start()` method to run the capture.
147 |
148 | #### camera
149 | Type: `Boolean`
150 | Default: `true`
151 |
152 | The camera property allows you to **capture the media stream of the camera**. By default, Instacam only captures media stream from the webcam. If you want to only capture the microphone, you need to set this property to `false` and set the sound property to `true`.
153 |
154 | #### mode
155 | Type: `String`
156 | Default: `front`
157 |
158 | The mode property allows you to **select the camera used to capture the media stream**. By default, Instacam uses the front camera. If you set the mode to `back` and no camera is found, Instacam will automatically switch to the default one.
159 |
160 | #### framerate
161 | Type: `Number`
162 | Default: `30`
163 | Minimum: `1`
164 | Maximum: `None`
165 |
166 | The framerate property allows you to **change the refresh rate of the camera**. By default, Instacam will capture the media stream at **30 frames per second**. The maximum framerate depends on the camera capabilities.
167 |
168 | #### ratio
169 | Type: `Number`
170 | Default: `4/3`
171 |
172 | The ratio property allows you yo **change the aspect ratio of the camera**. It must fit to the width/height ratio to render a proper image of the media stream. You can use float numbers (like 1.1, 1.7) or fractions (like 4/3, 16/9) for better syntax reading.
173 |
174 | #### sound
175 | Type: `Boolean`
176 | Default: `false`
177 |
178 | The sound property allows you to **capture the audio stream from the microphone**. By default, Instacam only captures media stream from the webcam. If you want to capture both the microphone and the camera, you need to set this property to `true`.
179 |
180 | #### paused
181 | Type: `Boolean`
182 | Default: `false`
183 |
184 | The paused property **indicate if the camera audio/video are currently paused**.
185 |
186 | #### muted
187 | Type: `Boolean`
188 | Default: `false`
189 |
190 | The muted property **indicate if the microphone is currently muted**.
191 |
192 | #### volume
193 | Type: `Number`
194 | Default: `100`
195 | Minimum: `0`
196 | Maximum: `100`
197 |
198 | The volume property allows you to **adapt the volume of the microphone**. By default, Instacam sets the volume to 100. Note that you can set the volume at **any time** as soon as the camera is ready.
199 |
200 | #### mirror
201 | Type: `Boolean`
202 | Default: `false`
203 | The mirror mode allows you to **flip the viewport horizontally**. This mode uses CSS transform property.
204 |
205 | #### opacity
206 | Type: `Number`
207 | Default: `1`
208 | Minimum: `0`
209 | Maximum: `1`
210 |
211 | The opacity property applies transparency to the viewport, making it **appear more or less transparent**. A value of 0 is completely transparent. A value of 1 leaves the viewport unchanged. Values between 0 and 1 are linear multipliers on the effect. Some browsers may provide **hardware acceleration** to render the opacity filter for better performance. If omitted, the CSS filter won't be applied.
212 |
213 | #### brightness
214 | Type: `Number`
215 | Default: `1`
216 | Minimum: `0`
217 | Maximum: `None`
218 |
219 | The brightness property applies a linear multiplier to the viewport, making it **appear more or less bright**. A value of 0 will create an image that is completely black. A value of 1 leaves the viewport unchanged. Other values are linear multipliers on the effect. Values of an amount over 1 are allowed, providing **brighter results**. If omitted, the CSS filter won't be applied.
220 |
221 | #### contrast
222 | Type: `Number`
223 | Default: `1`
224 | Minimum: `0`
225 | Maximum: `None`
226 |
227 | The contrast property **adjusts the contrast** of the viewport. A value of 0 will create an image that is completely black. A value of 1 leaves the viewport unchanged. Values of amount over 1 are allowed, providing **results with less contrast**. If omitted, the CSS filter won't be applied.
228 |
229 | #### saturation
230 | Type: `Number`
231 | Default: `1`
232 | Minimum: `0`
233 | Maximum: `None`
234 |
235 | The saturation property **saturates** the viewport. A value of 0 is completely un-saturated. A value of 1 leaves the viewport unchanged. Other values are linear multipliers on the effect. Values of amount over 1 are allowed, providing **super-saturated results**. If omitted, the CSS filter won't be applied.
236 |
237 | #### hue
238 | Type: `Number`
239 | Unit: `Degree`
240 | Default: `0`
241 | Minimum: `0`
242 | Maximum: `360`
243 |
244 | The hue property **applies a hue rotation** on the viewport. The value of angle defines the number of degrees around the color circle the viewport samples will be adjusted. A value of 0 degree leaves the viewport unchanged. The maximum value is 360 degree. If omitted, the CSS filter won't be applied.
245 |
246 | #### invert
247 | Type: `Number`
248 | Default: `0`
249 | Minimum: `0`
250 | Maximum: `1`
251 |
252 | The invert property **inverts the samples** in the viewport. A value of 1 is completely inverted. A value of 0 leaves the viewport unchanged. Values between 0 and 1 are linear multipliers on the effect. If omitted, the CSS filter won't be applied.
253 |
254 | #### grayscale
255 | Type: `Number`
256 | Default: `0`
257 | Minimum: `0`
258 | Maximum: `1`
259 |
260 | The grayscale property **converts the viewport to grayscale**. A value of 1 is completely grayscale. A value of 0 leaves the viewport unchanged. Values between 0 and 1 are linear multipliers on the effect. If omitted, the CSS filter won't be applied.
261 |
262 | #### sepia
263 | Type: `Number`
264 | Default: `0`
265 | Minimum: `0`
266 | Maximum: `1`
267 |
268 | The sepia property **converts the viewport to sepia**. A value of 1 is completely sepia. A value of 0 leaves the viewport unchanged. Values between 0 and 1 are linear multipliers on the effect. If omitted, the CSS filter won't be applied.
269 |
270 | #### blur
271 | Type: `Number`
272 | Unit: `Pixel`
273 | Default: `0`
274 | Minimum: `0`
275 | Maximum: `None`
276 |
277 | The blur property **applies a Gaussian blur** to the viewport. The value of radius defines the value of the standard deviation to the Gaussian function, or how many pixels on the screen blend into each other, so **a larger value will create more blur**. The property is specified as a CSS length, but does not accept percentage values. If omitted, the CSS filter won't be applied.
278 |
279 | #### url
280 | Type: `String`
281 | Default: `Empty`
282 |
283 | The url property takes the **location of an XML file** that specifies an **SVG filter**, and may include an anchor to a specific filter element. If omitted, the CSS filter won't be applied.
284 |
285 | #### blend
286 | Type: `Object`
287 | Default: `Empty`
288 |
289 | The blend property **applies a CSS mix blend mode filter** to the viewport. You need to define the blend mode and color to enable blending:
290 |
291 | ```js
292 | blend: {
293 | mode: 'lighten',
294 | color: 'darkslateblue'
295 | }
296 | ```
297 |
298 | To properly blend the viewport, Instacam need to create **a layout above the canvas**. Blending can be disable at any time by simply set the blend property to an empty object `{}`.
299 |
300 | #### filter
301 | Type: `Function`
302 | Return: `Array`
303 | Default: `null`
304 |
305 | The filter property allows you to applies a **custom filter** to the viewport, that is different than applying a CSS filter. The custom filter brings you the ability to edit each pixels of the media stream before they are drawn to the canvas. This property takes a `Function` with one parameter called `pixel` that corresponds to the current pixel parsed by the **class filtering loop**. On that pixel, you can get some informations like the `offset` *(index of the pixel)*, the `x` and `y` positions, the `red`, `green` and `blue` color components and finally the `alpha` layer. With this informations, you can **edit the pixel properties** and then return the edited informations. The return type of the function must be a pixel, represented by an `Array` with the red, green, blue components and the alpha layer: these new values will erase the previous informations of the pixel and will be drawn to the canvas. You can also **combine several CSS filters with a custom filter** to obtain pretty effects. If omitted, the custom filter won't be applied.
306 |
307 | Build a custom filter is very easy, because you can code **your own logic** inside the function, for example:
308 | ```js
309 | // grayscale
310 | filter: (pixel) => {
311 | let g = 0.2126 * pixel.red + 0.7152 * pixel.green + 0.0722 * pixel.blue;
312 | return [g, g, g, pixel.alpha];
313 | }
314 |
315 | // invert
316 | filter: (pixel) => {
317 | return [255 - pixel.red, 255 - pixel.green, 255 - pixel.blue, pixel.alpha];
318 | }
319 |
320 | // threshold
321 | filter: (pixel) => {
322 | let threshold = 0.2126 * pixel.red
323 | + 0.7152 * pixel.green
324 | + 0.0722 * pixel.blue;
325 |
326 | return (threshold >= 100) ? [255, 255, 255, 255] : [0, 0, 0, 255];
327 | }
328 | ```
329 |
330 | > If you want to contribute and share cool filters, you can send me your code or create a **pull request** on the `gh-pages` branch, and it will be added to the **[Instacam demo site](#demo)**. Thanks for contributing! :tada: :+1:
331 |
332 | #### style
333 | Type: `Array`
334 | Return: `Array`
335 | Default: `[]`
336 |
337 | The style property returns **styles that are applied to the viewport**.
338 |
339 | #### hardware
340 | Type: `Object`
341 | Return: `Object`
342 | Default: `null`
343 |
344 | The hardware property returns **a set of hardware informations** from the current audio/video tracks. Note that this property will only be available after camera initialization: if the capture fails, hardware informations won't be accessible.
345 |
346 | ## Methods
347 | ### API
348 | Instacam reference that details all methods of the class.
349 |
350 | #### start ( )
351 | Type: `Function`
352 |
353 | The start method allows you to **start the capture of the webcam stream**. If the `autostart` parameter is set to `true`, you don't need to call this method, Instacam will do it for you. Both camera and sound will be started, depending on the properties you have defined.
354 |
355 | ```js
356 | camera.start();
357 | ```
358 |
359 | #### stop ( )
360 | Type: `Function`
361 |
362 | The stop method allows you to **stop the capture of the webcam stream**. Both camera and sound will be stopped.
363 |
364 | ```js
365 | camera.stop();
366 | ```
367 |
368 | #### pause ( )
369 | Type: `Function`
370 |
371 | The pause method allows you to **pause the capture of the webcam stream**. Both camera and sound will be paused. Note that this method will only pause the `