Skip to content

Instantly share code, notes, and snippets.

@thejsj
Last active July 22, 2019 00:52
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thejsj/3dacf02edf6b744a9f60 to your computer and use it in GitHub Desktop.
Save thejsj/3dacf02edf6b744a9f60 to your computer and use it in GitHub Desktop.
Realtime Image Whiteboard
/**
* Client Side
*
* Query an element and listen to files being drarg and dropped in order to
* send the file to the server throuth a POST and a PUT request
*/
// You must have an element with the ID `dropzone`
var el = document.getElementById('dropzone');
el.addEventListener("drop", function( event ) {
// prevent default action (open as link for some elements)
event.preventDefault();
evt.stopPropagation();
// Save the X and Y position fo the mouse, to send it to the server
var x = evt.clientX, y = evt.clientY;
var files = evt.dataTransfer.files; // FileList object.
_.each(files, function (file) {
var reader = new FileReader();
reader.onload = function(e) {
// e.target.result resturns a string with the image encoded as base64
var base64 = e.target.result;
// We want to find the MIME Type for this image
var matches = base64.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/);
var image = {
'fileName': file.name,
'type': matches[1], // Mime Type
'image': e.target.result,
'x': x,
'y': y
};
// Add the image to a FormData object
// Separete the file from the metadata in two different fields
var data = new FormData();
data.append('file', e.target.result);
data.append('image', image);
var opts = {
transformRequest: function(data) { return data; }
};
// Send an HTTP POST request using the axios library (an angular-like HTTP request library)
// https://github.com/mzabriskie/axios
axios.post('/image',data, opts);
}.bind(this);
// Read the file
reader.readAsDataURL(file);
}.bind(this));
}, false);
/**
* Server Side
*
* Listen to new image objects coming in through the POST /image router and Save them
* Listen to new images coming in th
*/
var _ = require('lodash');
var r = require('../db');
var multiparty = require('multiparty');
var checkType = require('../check-type');
var imageCreate = function (req, res) {
var form = new multiparty.Form();
// This form is a `multipart/form-data` so we need to parse it
// `form.parse` will get all our images and fields
form.parse(req, function (err, fields) {
var imageFile = fields.file[0]; // Our file in a base64 string
var image = fields.image[0]; // Our metadata
var matches = imageFile.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/);
if (Array.isArray(matches)) {
// Convert our base64 string into a buffer
var buffer = new Buffer(matches[2], 'base64');
// Convert our buffer into a ReQL binary object
// RethinkDB accepts buffers when saving something as a binary object in the database
image.file = r.binary(buffer);
// Insert image into the database
r
.table('photos')
.insert(image)
.run(r.conn)
.then(function (query_result) {
res.json( {
id: req.params.id
});
});
};
});
}
module.exports = imageCreate
/*jshint node:true */
'use strict';
var express = require('express');
var app = express();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var bodyParser = require('body-parser');
var socketHandler = require('./socket-handler');
var imageCreate = require('./api/image');
server.listen(8000);
// Middlewares
app
.use(bodyParser.urlencoded({
extended: true
}))
.use(bodyParser.json());
// Routes
app
.post('/image/', imageCreate)
.use(express.static(__dirname + '/../client'))
.use('*', function (req, res) {
res.status(404).send('404 Not Found').end();
});
io.on('connection', socketHandler.bind(null, io));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment