{"id":13811376,"url":"https://github.com/samanthaming/not-fancy-image-upload","last_synced_at":"2025-05-14T19:33:03.586Z","repository":{"id":132258837,"uuid":"141522244","full_name":"samanthaming/not-fancy-image-upload","owner":"samanthaming","description":"A simple, not fancy at all, image upload with drag \u0026 drop built with Vue","archived":false,"fork":false,"pushed_at":"2018-07-20T15:32:01.000Z","size":215,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-11-19T06:52:57.667Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://samanthaming.github.io/not-fancy-image-upload/","language":"CSS","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/samanthaming.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2018-07-19T03:56:17.000Z","updated_at":"2023-10-09T14:22:35.000Z","dependencies_parsed_at":"2023-04-13T15:32:23.500Z","dependency_job_id":null,"html_url":"https://github.com/samanthaming/not-fancy-image-upload","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samanthaming%2Fnot-fancy-image-upload","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samanthaming%2Fnot-fancy-image-upload/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samanthaming%2Fnot-fancy-image-upload/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samanthaming%2Fnot-fancy-image-upload/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/samanthaming","download_url":"https://codeload.github.com/samanthaming/not-fancy-image-upload/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254213997,"owners_count":22033617,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-04T04:00:17.917Z","updated_at":"2025-05-14T19:33:03.281Z","avatar_url":"https://github.com/samanthaming.png","language":"CSS","funding_links":[],"categories":["Uncategorized"],"sub_categories":["Uncategorized"],"readme":"# Not Fancy Image Upload\n\nA simple, not fancy at all, image upload.\n\n**Features include:**\n\n- Upload image through file input\n- Drag and drop image upload\n- Hosting image through `FileReader` API\n- Simple image type validation\n- Decorate image with border \n- Customize border color and thickness\n\n**Built using:**\n\n- Vue\n- Google Fonts - Happy Monkey\n\n\u003cbr\u003e\n\nPlay around with it on [CodePen](https://codepen.io/samanthaming/pen/XBKBBv)  \nOr see it live! [here](https://samanthaming.github.io/not-fancy-image-upload/)\n\n\u003cbr\u003e\n\n![App](images/not-fancy-image-upload.png)\n\n![App](images/not-fancy-image-upload-image.png)\n\n# Notes\n\nHere are the general steps to create your own Not Fancy Image Upload. You need to understand 2 concepts in dealing with your image Upload. To handle our image upload, we need to utilize 2 APIs:\n\n**1. File API**\n\nThis will allow you to interact with your local files. The File API will give us access to a `FileList` which contains the `File` object. The `File` object will have all of the metadata about the image that was uploaded. It is what we will use to pass to our `FileReader`.\n\n![FileList](images/file-list.png)\n\n**2. FileReader API**\n\nThe `FileReader` API is what will allow use to create a local url that can be used as the `src` of our image element. It reads the content of our `File` object asynchronously. So we need to trigger the `onload` event when the load finishes, so we can access the `result` attribute that will our src url.\n\n## A. Image Upload through File Input\n\n### A-1: Load File with `input`\n\n```html\n\u003cinput \n  type=\"file\" \n  @change=\"onFileChange\" \n  accept=\"image/*\"\u003e\n```\n\n### A-2: Handle the Image Upload\n\n```javascript\nmethods: {\n  onFileChange(e) {\n    // Extract the FileList \n    const fileList = e.target.files;\n    \n    // Destructure the File from the Filelist\n    const [file] = filesList;\n    \n    // Generate our src url with the FileReader API\n    const reader = new FileReader();\n    \n    // Encode our file data as a \"data url\" (base64 format)\n    reader.readAsDataURL(file);\n    \n    // Once the FileReader finish loading, \n    //  trigger the onload event to extract the url\n    reader.onload = (e) =\u003e {\n      this.imageUrl = e.target.result;\n    }\n  }\n}\n```\n\n### A-3: Displaying the Image\n\n```html\n\u003cimg :src=\"imageUrl\"\u003e\n```\n\n## B. Image Upload through Drag and Drop\n\nWe're going to utilize HTML Drag and Drop API to create a drop zone. The 2 events we're going to call are:\n\n**dragover**: This event is fired when the dragged image is moving withint our drop zone.\n\n**drop**: This event is fired when the user drops the image into our drop zone.\n\n## B-1. Create our Drop Zone\n\n```html\n\u003cdiv \n  @dragover.prevent \n  @drop.stop.prevent=\"dropImage\"\n\u003e\u003c/div\u003e\n```\n\n## B-2. Handle the Dropped Image\n\n```javascript\nmethods: {\n  dropImage(e) {\n    const fileList = this.validateImageFile(e.dataTransfer.files);\n    \n    // The rest follows the same step as #A-2\n  }\n}\n```\n\n### B-3: Displaying the Image\n\n```html\n\u003cimg :src=\"imageUrl\"\u003e\n```\n\n## Centering Absolute Image\n\nTo center an image with position absolute. We need to use both the `transform` and `left` property.\n\nCSS **left** property is based on the size of the parent element.  \nCSS **transform** property is based on the the size of the target element.\n\nleft 50% will move the element exactly at the center of the main container where this element belongs! BUT translateX(50%) will move the element right exactly to 50% of its width,and NOT at the center of the whole Container element!\n\n```css\n.parent {\n  position: relative;\n}\n\nimg {\n  position: absolute;\n  \n  /* This will move the element exactly at the center of the parent container */\n  left: 50%;\n  \n  /* This will re-adjust the element right exactly to 50% of its own width */\n  transform: translateX(-50%);\n}\n```\n\n# Resources\n\n- [CodePen: Select or drop image with Vuejs](https://codepen.io/raffo1234/pen/bZQXwZ)\n- [JSFiddle: Image upload](https://jsfiddle.net/mani04/5zyozvx8/)\n- [David Walsh: File Reader](https://davidwalsh.name/filereader)\n- [David Walsh: File API](https://davidwalsh.name/file-api)\n- [CodePen: Vue CSS Custom Property Test](https://codepen.io/richardtallent/pen/yvpERW/)\n- [Reading files in JavaScript using the File APIs](https://www.html5rocks.com/en/tutorials/file/dndfiles/)\n- [Stack Overflow: Why does “left: 50%, transform: translateX(-50%)” horizontally center an element?](https://stackoverflow.com/questions/25982135/why-does-left-50-transform-translatex-50-horizontally-center-an-element)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsamanthaming%2Fnot-fancy-image-upload","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsamanthaming%2Fnot-fancy-image-upload","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsamanthaming%2Fnot-fancy-image-upload/lists"}