├── LICENSE ├── LoadAssets.js ├── README.md ├── examples ├── gifs.html ├── loading.gif └── video.html ├── index.js └── package.json /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Juan Cabrera (juan.me) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | -------------------------------------------------------------------------------- /LoadAssets.js: -------------------------------------------------------------------------------- 1 | var LoadAssets = React.createClass({ 2 | getInitialState: function () { 3 | // 'loaded' state by default is false 4 | return {loaded: false}; 5 | }, 6 | 7 | componentDidMount: function () { 8 | var 9 | _self = this, 10 | totalAssets = this.props.assets.length, 11 | loadedAssets = 0 12 | ; 13 | 14 | // Start loading all the assets 15 | Array.prototype.forEach.call(this.props.assets, function(asset) { 16 | _self.loadAsset(asset.uri, function(e) { 17 | loadedAssets++; 18 | if (loadedAssets == totalAssets) { 19 | // when all the assets are loaded set state 'loaded' to true 20 | _self.setState({loaded: true}); 21 | 22 | // when all the assets are loaded call the callback function if any 23 | if (typeof(_self.props.onLoad) === "function") _self.props.onLoad(); 24 | } 25 | }); 26 | }); 27 | }, 28 | 29 | loadAsset: function(uri, callback) { 30 | // preload if asset is image 31 | if (uri.toLowerCase().match("jpg|jpeg|gif|png|webp") !== null) { 32 | var image = new Image(); 33 | image.src = uri; 34 | image.onload = callback; 35 | } 36 | 37 | // preload if asset is video 38 | if (uri.toLowerCase().match("mp4|webm|ogv") !== null) { 39 | var video = document.createElement('video'); 40 | var source = document.createElement('source'); 41 | source.src = uri; 42 | video.setAttribute("preload", "auto"); 43 | video.appendChild(source); 44 | video.addEventListener('canplaythrough', callback, false); 45 | } 46 | }, 47 | 48 | render: function() { 49 | var output = []; 50 | 51 | if (!this.state.loaded) { 52 | // asset not loaded yet - loading UI 53 | output.push(
); 54 | } else { 55 | // asset fully loaded - show asset 56 | var assets = this.props.assets.map(function(asset) { 57 | var assetOutput; 58 | // it's an image 59 | if (asset.uri.toLowerCase().match("jpg|jpeg|gif|png|webp") !== null) { 60 | assetOutput = (); 61 | } 62 | // it's a video 63 | if (asset.uri.toLowerCase().match("mp4|webm|ogv") !== null) { 64 | // TODO: make it smart so it will create a video element with many sources instead of many video elements for different video formats 65 | assetOutput = ( 66 | 69 | ); 70 | } 71 | 72 | // adding props if any 73 | if (asset.attributes !== undefined) { 74 | Array.prototype.forEach.call(asset.attributes, function(a) { 75 | assetOutput.props[Object.keys(a)[0]] = a[Object.keys(a)[0]]; 76 | }); 77 | } 78 | 79 | output.push(assetOutput); 80 | }); 81 | } 82 | 83 | return (
{output}
); 84 | } 85 | }); 86 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React Asset Loader 2 | A simple react component for loading assets. It allows you to load from a single asset to multiple assets without affecting the pageload speed. You can also add custom classes, attributes and callback functions. 3 | 4 | ## Concept 5 | We all get scared of heavy websites, there are tons and tons of articles telling us why we shouldn't build websites using heavy assets like videos or gifs. But sometimes, you just need to, sometimes you just need to build a cool interactive experience with videos, or so something cool with gifs, or a long page with lots of high quality images, etc. This component is precisely for that. 6 | 7 | ## How it works 8 | This component allows you to load all the assets you want without affecting the pageload speed, this is because it will load the page and then it will start loading all the assets, it adds a `
` wrapper while it's loading the asset so you can have a nice custom loader, when the assets are loaded it will replace the `loading` wrapper with the actual assets. 9 | 10 | ## Install 11 | ``` 12 | npm install react-asset-loader --save-dev 13 | ``` 14 | Or just grab the component [LoadAsset.js](https://raw.githubusercontent.com/juancabrera/react-asset-loader/master/LoadAssets.js) directly. 15 | 16 | ## Usage 17 | #### Load a single asset 18 | 19 | ```javascript 20 | 21 | ``` 22 | #### Load multiple assets 23 | When you need to load more than one asset for one experience. It will be loadad after all the assets passed are loaded. 24 | 25 | ```javascript 26 | 27 | 28 | // or also 29 | 30 | var videos = [ 31 | {"uri":"/static/videos/video1.mp4"}, 32 | {"uri":"/static/videos/video2.mp4"} 33 | ] 34 | 35 | ``` 36 | #### Adding classes 37 | You can add classes to each asset you pass to the component. 38 | 39 | ```javascript 40 | 41 | ``` 42 | #### Adding attributes 43 | You can also add attributes to each asset you pass to the component. 44 | 45 | ```javascript 46 | 47 | 48 | // or also 49 | 50 | var video = [{ 51 | "uri":"/static/videos/video.mp4", 52 | "attributes": [ 53 | {"autoPlay":"true"}, 54 | {"loop":"true"} 55 | ] 56 | }] 57 | 58 | ``` 59 | #### Custom onLoad callback 60 | You can have a custom callback for when your assets are loaded. 61 | 62 | ```javascript 63 | 64 | ``` 65 | 66 | ## Examples 67 | You'll need a webserver in order to run the examples (CORS). The quickest way to do this is just run this on the project folder: 68 | 69 | ```python -m SimpleHTTPServer``` 70 | ## Feedback and contributions 71 | Are more than welcome 👊 72 | 73 | ## License 74 | MIT Copyright (c) [Juan Cabrera](http://juan.me) -------------------------------------------------------------------------------- /examples/gifs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 35 | 36 | 37 |
38 | 77 | 78 | -------------------------------------------------------------------------------- /examples/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juancabrera/react-asset-loader/acac7e928c6245b194d7b4efd7b4bbe3eaeb3f41/examples/loading.gif -------------------------------------------------------------------------------- /examples/video.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 28 | 29 | 30 |
31 | 37 | 38 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | LoadAssets: require('./LoadAssets') 5 | }; 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-asset-loader", 3 | "version": "0.0.1", 4 | "description": "A simple react component for loading assets. It allows you to load from a single asset to multiple assets without affecting the pageload speed. You can also add custom classes, attributes and callback functions.", 5 | "main": "index.js", 6 | "author": { 7 | "name": "Juan Cabrera", 8 | "email": "juan.acc@gmail.com", 9 | "url" : "http://juan.me/" 10 | }, 11 | "homepage": "https://github.com/juancabrera/react-asset-loader", 12 | "scripts": { 13 | "test": "echo \"Error: no test specified\" && exit 1" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "https://github.com/juancabrera/react-asset-loader" 18 | }, 19 | "keywords": [ 20 | "react", 21 | "asset-loader", 22 | "image", 23 | "video" 24 | ], 25 | "licenses": [ 26 | { 27 | "type": "MIT", 28 | "url": "https://github.com/juancabrera/react-asset-loader/blob/master/LICENSE" 29 | } 30 | ], 31 | "bugs": { 32 | "url": "https://github.com/juancabrera/react-asset-loader/issues" 33 | } 34 | } --------------------------------------------------------------------------------