├── .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 `