├── LICENSE.txt
├── README.md
├── avatar.css
├── avatar.js
├── demo.html
├── placekitten.jpg
└── usage.html
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2014 Dan Harper, http://danharper.me
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Avatar Upload
2 |
3 | by [Dan Harper](http://danharper.me)
4 |
5 | ## Usage
6 |
7 | ### 1. Include Files
8 | Include the `avatar.js` and `avatar.css` files in your document.
9 |
10 | ### 2. Wrap a Replacable Image
11 | Insert the current image (or a placeholder) in the page, inside a div with a custom class (eg. `avatar-upload`):
12 |
13 | ```html
14 |
15 |
16 |
17 | ```
18 |
19 | ### 3. Set your max images widths
20 | You must set a max width, otherwise images will fill the container. eg.
21 |
22 | ```css
23 | .avatar-upload {
24 | width: 200px;
25 | height: 200px;
26 | }
27 |
28 | .avatar-upload img {
29 | max-width: 200px;
30 | max-height: 200px;
31 | }
32 | ```
33 |
34 | ### 4. Boot the module
35 | Now boot the module, providing it with the element containing the image to replace & the URL to upload to.
36 |
37 | ```js
38 | new AvatarUpload({
39 | el: document.querySelector('.avatar-upload'),
40 | uploadUrl: ''
41 | });
42 | ```
43 |
44 | This will swap the contents of your `.avatar-upload` element with the uploader's markup. The image currently set won't appear any different. But you can now click the image to swap it out!
45 |
46 | You can optionally provide the following configuration settings to the module:
47 |
48 | * `el` **[required]** The element containing the current replaceable image
49 | * `uploadUrl` **[required]** Where to sent the new image to
50 | * `uploadMethod` The HTTP method to use when uploading (defaults to `POST`)
51 | * `uploadData` An object of additional data to send with the upload
52 | * `onProgress` A function to be called continuously as the upload progresses - takes one argument, the current upload percentage completion
53 | * `onSuccess` A function to be called when the upload completes successfully - takes one argument, the response from the server
54 | * `onError` A function to be called when the upload fails - takes one argument, the error response from the server
55 | * `pretentUpload` If `true`, no upload will be performed, it will be faked through a `setInterval`, pretending to upload - useful for testing initial set up
56 |
57 | ## Credit
58 |
59 | Kitten image in demo courtesy of [Paul Reynolds](http://www.flickr.com/photos/bigtallguy/148771151/) via [placekitten](http://placekitten.com/)
60 |
--------------------------------------------------------------------------------
/avatar.css:
--------------------------------------------------------------------------------
1 | /*avatar upload module*/
2 | .avatar-upload__shell {
3 | position: relative;
4 | width: 100%;
5 | height: 100%;
6 | }
7 |
8 | /*module wrapper*/
9 | .avatar-upload__wrapper {
10 | position: relative;
11 | overflow: hidden;
12 | width: 100%;
13 | height: 100%;
14 | }
15 |
16 | /*input element positioned over module, transparent*/
17 | .avatar-upload__wrapper input {
18 | position: absolute;
19 | top: 0;
20 | left: 0;
21 | bottom: 0;
22 | right: 0;
23 | opacity: 0;
24 | }
25 |
26 | /*wraps the "real" image. width is increased during upload progress*/
27 | .avatar-upload__image-wrapper {
28 | position: absolute;
29 | top: 0;
30 | bottom: 0;
31 | left: 0;
32 | right: 0;
33 | overflow: hidden;
34 | width: 0%;
35 | }
36 |
37 | /*general image positioning*/
38 | .avatar-upload__wrapper img {
39 | position: absolute;
40 | width: 100%;
41 | height: 100%;
42 | }
43 |
44 | /*"real" image width auto so it doesn't resize as wrapper width increases on progress*/
45 | .avatar-upload__image-wrapper img {
46 | width: auto;
47 | }
48 |
49 | /*progress text is vertically aligned in the middle*/
50 | .avatar-upload__progress-wrapper {
51 | position: relative;
52 | top: 50%;
53 | -webkit-transform: translateY(-50%);
54 | -ms-transform: translateY(-50%);
55 | transform: translateY(-50%);
56 | z-index: 1;
57 | width: 100%;
58 | text-align: center;
59 | font-size: 2.2em;
60 | color: white;
61 | text-shadow: 1px 1px rgba(0,0,0,.7);
62 | }
63 |
64 | /*the "faded" image appears in the background of the upload, becoming covered by real image*/
65 | .avatar-upload__faded-image {
66 | opacity: .3;
67 | }
68 |
69 | /*when no upload is in progress, the "real" image should be fully visible*/
70 | .avatar-upload--complete .avatar-upload__image-wrapper {
71 | width: 100%;
72 | }
73 |
74 | /*when no upload is in progress, progress is hidden*/
75 | .avatar-upload--complete .avatar-upload__progress-wrapper {
76 | display: none;
77 | }
78 |
79 | /*when no upload is in progress, the "faded" image is hidden*/
80 | .avatar-upload--complete .avatar-upload__faded-image {
81 | display: none;
82 | }
83 |
--------------------------------------------------------------------------------
/avatar.js:
--------------------------------------------------------------------------------
1 | (function ( root, factory ) {
2 | if ( typeof define === 'function' && define.amd ) {
3 | // AMD. Register as an anonymous module.
4 | define(function () {
5 | // Also create a global in case some scripts
6 | // that are loaded still are looking for
7 | // a global even when an AMD loader is in use.
8 | return ( root.AvatarUpload = factory() );
9 | });
10 | } else {
11 | // Browser globals
12 | root.AvatarUpload = factory();
13 | }
14 | }( this, function () {
15 |
16 | var extend = function(original, extra) {
17 | return Object.keys(extra).forEach(function(key) {
18 | original[key] = extra[key];
19 | });
20 | };
21 |
22 | var parseJson = function(input) {
23 | try {
24 | return JSON.parse(input);
25 | }
26 | catch (e) {
27 | return false;
28 | }
29 | };
30 |
31 | var AvatarUpload = function(config) {
32 | extend(this.config, config);
33 |
34 | if ( ! this.config.el) {
35 | throw new Error('An element is required to manipulate');
36 | }
37 |
38 | if ( ! this.config.uploadUrl && ! this.config.pretendUpload) {
39 | throw new Error('Upload URL not specified');
40 | }
41 |
42 | this.el = this.config.el;
43 | this.renderInput();
44 | this.bindInput();
45 |
46 | this.progressText = this.el.querySelector('span');
47 | this.imageWrapper = this.el.querySelector('.avatar-upload__image-wrapper');
48 | };
49 |
50 | AvatarUpload.prototype.config = {
51 | el: undefined,
52 |
53 | uploadUrl: '',
54 | uploadMethod: 'post',
55 | uploadImageKey: 'upload',
56 | uploadData: {},
57 |
58 | pretendUpload: false,
59 |
60 | onProgress: undefined,
61 | onSuccess: undefined,
62 | onError: undefined
63 | };
64 |
65 | AvatarUpload.prototype.renderInput = function() {
66 | var imgEl = this.el.querySelector('img'),
67 | img = imgEl.src;
68 |
69 | var el = document.createElement('div');
70 | el.className = 'avatar-upload__shell';
71 |
72 | el.innerHTML = [
73 | '
This will swap the contents of your .avatar-upload element with the uploader's markup. The image currently set won't appear any different. But you can now click the image to swap it out!
96 |
You can optionally provide the following configuration settings to the module:
97 |
98 |
el[required] The element containing the current replaceable image
99 |
uploadUrl[required] Where to sent the new image to
100 |
uploadMethod The HTTP method to use when uploading (defaults to POST)
101 |
uploadData An object of additional data to send with the upload
102 |
onProgress A function to be called continuously as the upload progresses - takes one argument, the current upload percentage completion
103 |
onSuccess A function to be called when the upload completes successfully - takes one argument, the response from the server
104 |
onError A function to be called when the upload fails - takes one argument, the error response from the server
105 |
pretentUpload If true, no upload will be performed, it will be faked through a setInterval, pretending to upload - useful for testing initial set up