Avatar uploads with Meteor

In case it’s of use to anyone finding this thread in the future, I’ve refactored and improved this into a React component available here.

I’ve cleaned up the code a lot and removed the b64toBlob() stuff and replaced it with a Polyfill for HTML5’s canvas.toBlob() function that will eventually have native browser support. Oh and added proper support of PNG, JPG & WEBP.

Also made it customisable with props, only slingshot is required, they are: -

slingshot: slingshot Directive Name *required
width: upload width
height: upload height
imageType: image MIME type, compatible with canvas.toBlob()
imageQuality: image quality for JPG or WEBP, number 0.0 to 1.0
options: Jcrop options
onError: on upload error callback(error, downloadURL)
onSuccess: on upload success callback(downloadURL)
setFilename: set upload filename callback(fileEvent)

So just call it wherever you need a cropper with: -

<Cropper slingshot="userUploads" />

As before you need an existing Slingshot setup and to install mrt:jquery-jcrop. Also this uses Semantic UI for its styling so if you don’t want to use it, you can go into the render() function and tweak the markup however you need.

Anyhoo, might be useful to someone.

4 Likes

Sweet!

I’ll be looking at your solution today (finally!) - haven’t touched this code (or meteor) for a while so am likely to use most of the afternoon refamiliarising myself - but I’ll update you once I’ve got it working!

Edit: @firegoby Worked first time - lovely stuff mate. Barely have that success with a supported plugin! Now to go through your React component and port over some of the improvements, as I’m sure you did a better job than I’d do :smile:

Next stop: Drag and drop. I’ll let you know how I get on, hopefully it’ll be soon!

Thanks again

1 Like

@firegoby Not getting very far with the file drop functionality actually. The package you linked to, raix:ui-dropped-event has basically no documentation with only an example for FS - which I don’t totally ‘get’ to be honest (the pertinant file variable appears to be what I need, but it doesn’t come from anywhere). I’ve been messing around with it for the past half hour but all it seems to add is the event, I have no idea how to get a file from it.

All the other packages I can find are complete solutions with the upload functionality (i.e. dropzone, which needs a destination URL) :frowning:

Am I just being dense with the ui-dropped-event?

Edit: As is typical I found the solution shortly after asking the question. Kind of by accident. I stumbled across this tutorial for building a droppable file upload in jquery, and noticed the pertinant reference: e.originalEvent.dataTransfer.files.

So all I needed to do was swap:

var oFile = $('#jcrop-file')[0].files[0];

For:

var files = event.originalEvent.dataTransfer.files;
var oFile = files[0];

And obviously swap out the change #jcrop-file event for the dropped #dropzone event.

Job done :thumbsup:

1 Like

It would be nice if somebody could create a package for: aviary.com

There’s an NPM package and one for meteor (but it’s 3 years old) https://atmospherejs.com/belisarius222/aviary

Time to start using react:

Sorry to revive such an old thread but I had a couple comments for future readers. I am switching from a CFS graphicsmagick workflow to Slingshot with JCrop:

@firegoby Your code samples are awesome. Helped me out a ton. Thank you for posting. I used your second pollyfill version in a Blaze template. Works great. FYI to future readers: file.lastModifiedDate is deprecated in browsers (and removed from Safari), use file.lastModified instead

I love the Slingshot workflow, but I’m finding two limitations that I didn’t have using CFS and graphicsmagick:

  1. I could support TIF file uploads with CFS and convert them to JPG (can’t do with Slingshot)
  2. I used to support GIF uploading. You can with Slingshot, but if you crop/resize with JCrop, when you convert the canvas to a blob it kills the animation. :frowning:

These are fine for now, but in the future I may have to have a separate uploading route for GIFs because that was really cool in my app to see animations. GIFs are like the “little file format that could”. They’ve managed to be quite useful and prominent.