Permalink
Browse files

first commit

  • Loading branch information...
0 parents commit 31bbbe8af5b8086e6a26f5cbd700bef862ac952f @chriscoyier chriscoyier committed Jan 14, 2013
Showing with 327 additions and 0 deletions.
  1. +109 −0 avatar.js
  2. +13 −0 css/style.css
  3. BIN images/256.jpg
  4. +42 −0 index.html
  5. +95 −0 resample.js
  6. +68 −0 style.css
109 avatar.js
@@ -0,0 +1,109 @@
+// Required for drag and drop file access
+jQuery.event.props.push('dataTransfer');
+
+// IIFE to prevent globals
+(function() {
+
+ var s;
+ var Avatar = {
+
+ settings: {
+ bod: $("body"),
+ img: $("#profile-avatar"),
+ fileInput: $("#uploader")
+ },
+
+ init: function() {
+ s = Avatar.settings;
+ Avatar.bindUIActions();
+ },
+
+ bindUIActions: function() {
+ s.bod.on("dragover", function(event) {
+ if (event.currentTarget == s.bod[0]) {
+ Avatar.showDroppableArea();
+ }
+
+ // Required for drop to work
+ return false;
+ });
+
+ s.bod.on('dragleave', function(event) {
+ if (event.currentTarget == s.bod[0]) {
+ Avatar.hideDroppableArea();
+ }
+ });
+
+ s.bod.on('drop', function(event) {
+
+ // Or else the browser will open the file
+ event.preventDefault();
+
+ Avatar.handleDrop(event.dataTransfer.files);
+ });
+
+ s.fileInput.on('change', function(event) {
+ Avatar.handleDrop(event.target.files);
+ });
+ },
+
+ showDroppableArea: function() {
+ s.bod.addClass("droppable");
+ },
+
+ hideDroppableArea: function() {
+ s.bod.removeClass("droppable");
+ },
+
+ handleDrop: function(files) {
+
+ Avatar.hideDroppableArea();
+
+ // Multiple files can be dropped. Lets only deal with the "first" one.
+ var file = files[0];
+
+ if (file.type.match('image.*')) {
+
+ Avatar.resizeImage(file, 256, function(data) {
+ Avatar.placeImage(data);
+ });
+
+ } else {
+
+ alert("That file wasn't an image.");
+
+ }
+
+ },
+
+ resizeImage: function(file, size, callback) {
+
+ var fileTracker = new FileReader;
+ fileTracker.onload = function() {
+ Resample(
+ this.result,
+ size,
+ size,
+ callback
+ );
+ }
+ fileTracker.readAsDataURL(file);
+
+ fileTracker.onabort = function() {
+ alert("The upload was aborted.");
+ }
+ fileTracker.onerror = function() {
+ alert("An error occured while reading the file.");
+ }
+
+ },
+
+ placeImage: function(data) {
+ s.img.attr("src", data);
+ }
+
+ }
+
+ Avatar.init();
+
+})();
@@ -0,0 +1,13 @@
+/*
+ CSS-Tricks Example
+ by Chris Coyier
+ http://css-tricks.com
+*/
+
+* { margin: 0; padding: 0; }
+body { font: 14px Georgia, serif; }
+
+article, aside, figure, footer, header, hgroup,
+menu, nav, section { display: block; }
+
+#page-wrap { width: 960px; margin: 80px auto; }
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <meta charset='UTF-8'>
+
+ <title>Drag Avatar</title>
+
+ <link rel='stylesheet' href='style.css'>
+</head>
+
+<body>
+
+ <div class="page-wrap">
+
+ <h1>Drag & Drop Image to Change Avatar</h1>
+
+ <div class="profile">
+
+ <div class="profile-avatar-wrap">
+ <img src="images/256.jpg" id="profile-avatar" alt="Image for Profile">
+ </div>
+
+ <h2>Betty Miller</h2>
+ <div class="location">Palo Alto, CA</div>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequatur voluptatem accusantium voluptas doloremque porro temporibus aut rerum possimus cum minus.</p>
+
+ </div>
+
+ <h3>You could do this with a file input too...</h3>
+ <input type="file" id="uploader">
+
+ </div>
+
+ <!-- In real life, these scripts are combined -->
+ <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
+ <script src="resample.js"></script>
+ <script src="avatar.js"></script>
+
+</body>
+
+</html>
@@ -0,0 +1,95 @@
+var Resample = (function (canvas) {
+
+ // (C) WebReflection Mit Style License
+
+ function Resample(img, width, height, onresample) {
+ var
+
+ load = typeof img == "string",
+ i = load || img;
+
+ // if string, a new Image is needed
+ if (load) {
+ i = new Image;
+ i.onload = onload;
+ i.onerror = onerror;
+ }
+
+ i._onresample = onresample;
+ i._width = width;
+ i._height = height;
+ load ? (i.src = img) : onload.call(img);
+ }
+
+ function onerror() {
+ throw ("not found: " + this.src);
+ }
+
+ function onload() {
+ var
+ img = this,
+ width = img._width,
+ height = img._height,
+ onresample = img._onresample
+ ;
+ // if width and height are both specified
+ // the resample uses these pixels
+ // if width is specified but not the height
+ // the resample respects proportions
+ // accordingly with orginal size
+ // same is if there is a height, but no width
+ var minValue = Math.min(img.height, img.width);
+ width == null && (width = round(img.width * height / img.height));
+ height == null && (height = round(img.height * width / img.width));
+
+ delete img._onresample;
+ delete img._width;
+ delete img._height;
+
+ // when we reassign a canvas size
+ // this clears automatically
+ // the size should be exactly the same
+ // of the final image
+ // so that toDataURL ctx method
+ // will return the whole canvas as png
+ // without empty spaces or lines
+ canvas.width = width;
+ canvas.height = height;
+ // drawImage has different overloads
+ // in this case we need the following one ...
+ context.drawImage(
+ // original image
+ img,
+ // starting x point
+ 0,
+ // starting y point
+ 0,
+ // image width
+ minValue,
+ // image height
+ minValue,
+ // destination x point
+ 0,
+ // destination y point
+ 0,
+ // destination width
+ width,
+ // destination height
+ height
+ );
+ // retrieve the canvas content as
+ // base4 encoded PNG image
+ // and pass the result to the callback
+ onresample(canvas.toDataURL("image/png"));
+ }
+
+ var context = canvas.getContext("2d"),
+ // local scope shortcut
+ round = Math.round
+ ;
+
+ return Resample;
+
+}(
+ this.document.createElement("canvas"))
+);
@@ -0,0 +1,68 @@
+* {
+ box-sizing: border-box;
+}
+
+/* Make sure draggable area is whole page */
+html, body {
+ height: 100%;
+}
+
+body.droppable:after {
+ content: "Drop File Anywhere";
+ text-align: center;
+ color: white;
+ font-weight: bold;
+ padding-top: 150px;
+ font-size: 60px;
+ position: absolute;
+ top: 20px;
+ left: 20px;
+ right: 20px;
+ bottom: 20px;
+ background: rgba(252, 135, 20, 0.9);
+ border: 5px dashed orange;
+ z-index: 9999;
+}
+
+.page-wrap {
+ width: 960px;
+ margin: 100px auto;
+}
+
+h1 {
+ margin: 0 0 30px 0;
+ border-bottom: 5px solid #ccc;
+}
+h3 {
+ clear: both;
+ margin: 100px 0 0 0;
+}
+
+.profile {
+ width: 50%;
+}
+.profile-avatar-wrap {
+ width: 33.33%;
+ float: left;
+ margin: 0 20px 5px 0;
+ position: relative;
+}
+.profile-avatar-wrap:after {
+ /* Drag Prevention */
+ content: "";
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+}
+.profile-avatar-wrap img {
+ max-width: 100%;
+}
+.location {
+ text-transform: uppercase;
+ color: #999;
+ letter-spacing: 1px;
+ margin: 0 0 10px 0;
+ font-size: 90%;
+}

0 comments on commit 31bbbe8

Please sign in to comment.