# \[WIP\] reply by drawing

**URL:** https://meta.discourse.org/t/wip-reply-by-drawing/39080
**Category:** Plugin
**Tags:** broken
**Created:** [February 5, 2016, 2:30am UTC](https://meta.discourse.org/t/wip-reply-by-drawing/39080 "2016-02-05T02:30:49Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [February 5, 2016, 2:30am UTC](https://meta.discourse.org/t/wip-reply-by-drawing/39080/1 "2016-02-05T02:30:49Z")

</div>

I don’t know if this has been attempted yet, but here’s a very quick WIP hack together of a small plugin that will allow you to draw a reply in a canvas. I got jealous of google hangouts so I wanted to hack something similar into discourse.

It’s not yet functioning, so I’m throwing it under broken-plugins (it also has pretty primative drawing methods, and starts with some test data already filled in the canvas). I stole a lot of modal view and such from the [replygif plugin](https://meta.discourse.org/t/replygif-adding-reaction-gif-easily/33195). Credit where credit’s due. 😉

The broken part is – I’m not _quite_ sure how to shove the base-64 png data across the wire as a file upload just yet (it just prints the data in the console and the compose window for now). Any pointers or suggestions to actually perform an upload would be great!

[https://github.com/featheredtoast/discourse-plugin-draw-reply](https://github.com/featheredtoast/discourse-plugin-draw-reply)

---

<div class="post-metadata">

### Author: ![purldator](https://avatars.discourse-cdn.com/v4/letter/p/bcef8e/32.png) [@purldator](https://meta.discourse.org/u/purldator)
#### Post date: [February 5, 2016, 3:14am UTC](https://meta.discourse.org/t/wip-reply-by-drawing/39080/2 "2016-02-05T03:14:50Z")

</div>

Whoa.

I was thinking of something like this; had the whole thing coded in my head, or at least how and when specific data moved between client and server/db. Having an optional [oekaki](https://en.wikipedia.org/wiki/Oekaki#Internet_oekaki) input has been the Holy Grail of geekdom and art culture forums, Only phpBB got somewhere with a released mod…that crumbled with time, and the core’s constant advances at that moment.

Those traditional oekaki java applets will cease to load shortly; again, crumbling with time and in this case, closed-source code.

Any current reincarnations kept up to date are closed source (eg, Lascaux Sketch).

Searching for “oekaki” in my stars collection [@github](https://github.com/purldator) returns some attempts in JavaScript and HTML5. I hope they may help in some way to this data transfer and turn it into an actual image. That is where oekaki excelled.

(And as a clarification, I am not asking or expecting the grand Photoshop-like options or any multiple color choices the traditional setups were also known for. Gimmie a line on canvas. All anyone needs, I think.)

---

<div class="post-metadata">

### Author: ![gdpelican](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gdpelican/32/81308_2.png) [@gdpelican](https://meta.discourse.org/u/gdpelican)
#### Post date: [February 5, 2016, 5:05am UTC](https://meta.discourse.org/t/wip-reply-by-drawing/39080/3 "2016-02-05T05:05:53Z")

</div>

Neat feature; we’ve been talking a bunch over at Loomio about a composer which allows for a bunch more forms of communication than just writing text; (ie audio / video recordings, reactions, drawings, etc.), so this is an interesting idea.

If I were looking at implementing file upload I’d have a nice hard look at `discourse/mixins/upload.js.es6`, and how it’s used and triggered in other parts of the app. 😄

---

<div class="post-metadata">

### Author: ![Tom\_Newsom](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tom_newsom/32/115981_2.png) [@Tom\_Newsom](https://meta.discourse.org/u/Tom_Newsom)
#### Post date: [February 5, 2016, 11:05am UTC](https://meta.discourse.org/t/wip-reply-by-drawing/39080/4 "2016-02-05T11:05:53Z")

</div>

What a fantastic idea. I will watch this thread with great interest.

---

<div class="post-metadata">

### Author: ![ccdw](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/ccdw/32/51564_2.png) [@ccdw](https://meta.discourse.org/u/ccdw)
#### Post date: [February 5, 2016, 11:17am UTC](https://meta.discourse.org/t/wip-reply-by-drawing/39080/5 "2016-02-05T11:17:27Z")

</div>

How nice to see threads like this.

Can’t we add a button to the composer and popup a jQuery canvas editor, just by using client side code?

Something like [Sketch JS](http://intridea.github.io/sketch.js/), albeit with the download button saving the contents into the composer, as opposed to downloading.

 ![](https://global.discourse-cdn.com/meta/original/3X/b/b/bb8a94242bb785a6c7c91537fef89229c96db2a3.png)

More than happy to help out with a client side only demo if that’s of any interest. Which could then be hardened into a plugin if all went well.

Edit: Although over the top wrt the requirements stated here - tools [like this](http://jointjs.com/rappid#e2913282-5ad2-4c67-aefd-853aee2f4046) also have save as PNG options. Opening up all sorts of collaborative efforts, in amongst other things, wiki topics.

---

<div class="post-metadata">

### Author: ![purldator](https://avatars.discourse-cdn.com/v4/letter/p/bcef8e/32.png) [@purldator](https://meta.discourse.org/u/purldator)
#### Post date: [February 5, 2016, 12:24pm UTC](https://meta.discourse.org/t/wip-reply-by-drawing/39080/6 "2016-02-05T12:24:12Z")

</div>

Damn. How could I forget [ChibiPaint](http://www.chibipaint.com/).

Well, if any _want_ the grand Photoshop options, ChibiPaint would be the best option to use. Its development is a response to the need for some open source applet similar to the well-known traditional apps like PaintBBS by Shii-chan.

Searching for “chibipaint” in google makes it abundantly clear many resources exist for artists to learn about the app.

To make stunning masterpieces like this.

 ![](https://global.discourse-cdn.com/meta/original/3X/2/8/28ede69a7335caa5db9831ad3205349f93d5e086.png)

[source](http://oekaki.pl/oe/summary/140887/15-wade_into_the_quiet_of_the_stream)

And the massive store of more [here](http://oekaki.pl/board/select/) @ oekaki.pl. Anything with the Program listed as “Chibipaint” was created fully from the app.

I think oekaki mesmerized me by this notion someone can create real works of art without needing an expensive program and a powerful device to do it. It proves the notion all honest artists echo more so now than ever: [“Your tools do not make your art.”](https://aeon.co/essays/digital-art-is-what-you-can-do-not-how-you-did-it)

I only show this to give example the “max” one can go into this, if they decide to. Art communities thrive with this option; to arrive at the core reason they all congregate in the first place.

---

<div class="post-metadata">

### Author: ![ccdw](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/ccdw/32/51564_2.png) [@ccdw](https://meta.discourse.org/u/ccdw)
#### Post date: [February 5, 2016, 2:12pm UTC](https://meta.discourse.org/t/wip-reply-by-drawing/39080/7 "2016-02-05T14:12:17Z")

</div>

> [@awole20](#):
>
> The broken part is – I’m not quite sure how to shove the base-64 png data across the wire as a file upload just yet (it just prints the data in the console and the compose window for now). Any pointers or suggestions to actually perform an upload would be great!

Does it need to simulate a file upload? In addition to paste, drag 'n drop and upload, I’m wondering whether the routine that saves images away can’t be overridden to accept a Base64 string directly? Which I suppose is what you are already asking.

Or alternatively, maybe an img tag with base64 src - like this?

![](data:image/gif;base64,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)

---

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [February 5, 2016, 5:12pm UTC](https://meta.discourse.org/t/wip-reply-by-drawing/39080/8 "2016-02-05T17:12:44Z")

</div>

> [@ccdw](#):
>
> Or alternatively, maybe an img tag with base64 src - like this?

Ooh, neato – That could work! My one hesitation is overrunning discourses post character limits with complex/larger images (which is why my impulse says try to figure out uploading raw images via file uploader), but I’ll check it out, thanks!

(update!) Results!

 ![](https://global.discourse-cdn.com/meta/original/3X/2/f/2fad50f4fdade5640ccba0d93374c53b56eaf89b.gif)

> [@ccdw](#):
>
> Can’t we add a button to the composer and popup a jQuery canvas editor, just by using client side code?

That’s precisely how I’m playing it at the moment 🙂 I can also take the base64 data from a canvas, I just want to see if it’s possible to upload on ‘save’ rather than print directly into your editor window. gif screens coming when it’s more refined, swear!

> [@gdpelican](#):
>
> If I were looking at implementing file upload I’d have a nice hard look at discourse/mixins/upload.js.es6, and how it’s used and triggered in other parts of the app.

Will do! I’m admittedly a bit of an emberjs and es6 noob here, so any hints as to where to get started for example sets are appreciated, thanks!

---

<div class="post-metadata">

### Author: ![ccdw](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/ccdw/32/51564_2.png) [@ccdw](https://meta.discourse.org/u/ccdw)
#### Post date: [February 5, 2016, 8:43pm UTC](https://meta.discourse.org/t/wip-reply-by-drawing/39080/9 "2016-02-05T20:43:15Z")

</div>

![](https://global.discourse-cdn.com/meta/original/3X/a/3/a32c0a9148c0c00131cee14407fdedcb0123645d.png)

Great job! That looks very cool. The creative world is now your oyster.

> [@awole20](#):
>
> My one hesitation is overrunning discourses post character limits with complex/larger images (which is why my impulse says try to figure out uploading raw images via file uploader)

Yes, when I suggested that I realised it was only suitable for proof of concept. Next step then to pass the base64 string into the image save routine either by fooling the system into thinking you are uploading or _dropping_ a file, or by finding a way of persuading the existing code to accept your string directly.

---

<div class="post-metadata">

### Author: ![Cortrah](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/cortrah/32/51486_2.png) [@Cortrah](https://meta.discourse.org/u/Cortrah)
#### Post date: [February 16, 2016, 3:56pm UTC](https://meta.discourse.org/t/wip-reply-by-drawing/39080/10 "2016-02-16T15:56:14Z")

</div>

Nice job guys. This is a very fun idea.

Just a thought, but depending on how rasteresque you need the drawings to look, you might find it easier, more flexible and work better with the infrastructure in production to use svg paths instead of canvas.

You’d be able to post as character data and even if the paths were drawn on top of a raster image you could add layers so that multiple people might be able to collaborate on a drawing or whiteboard annotation in some sort of pseudo realtime which would be much more difficult and take an absurd amount of bandwidth with raster data and file uploads/downloads.

---

<div class="post-metadata">

### Author: ![ccdw](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/ccdw/32/51564_2.png) [@ccdw](https://meta.discourse.org/u/ccdw)
#### Post date: [February 16, 2016, 7:43pm UTC](https://meta.discourse.org/t/wip-reply-by-drawing/39080/11 "2016-02-16T19:43:52Z")

</div>

Indeed 🙂

Not so good for freehand signatures tho, although could have some fun with splines 🙂

---

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [February 16, 2016, 7:59pm UTC](https://meta.discourse.org/t/wip-reply-by-drawing/39080/12 "2016-02-16T19:59:35Z")

</div>

My primary focus was to enable replying with silly doodles (I’ve got a few more-than-broken experimental branches for figuring out how to upload after ‘submit’ which is my primary focus right now), but I’d be open to PRs if anyone else (who knew a thing or two about SVGs) wanted to bolster the front end to push out more higher quality draw tools. 😉

---

<div class="post-metadata">

### Author: ![Cortrah](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/cortrah/32/51486_2.png) [@Cortrah](https://meta.discourse.org/u/Cortrah)
#### Post date: [February 16, 2016, 9:32pm UTC](https://meta.discourse.org/t/wip-reply-by-drawing/39080/13 "2016-02-16T21:32:52Z")

</div>

Actually I wasn’t thinking of something fancy like Illustrator light or that chibipaint thing (which looks really interesting), I think my description got carried away with itself.

I was also thinking of something like that sketch js interface for just that kind of thing. Simple fun line drawings or annotating an image with an overlay.

The reason for my suggestion had more to do with just how much simpler it would be to store the image data as character data embedded in a post instead of as a file upload.

If I can, I’ll install discourse and see if I can test out the idea. I can really imagine this being a fun and useful thing.

---

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [February 16, 2016, 9:47pm UTC](https://meta.discourse.org/t/wip-reply-by-drawing/39080/14 "2016-02-16T21:47:39Z")

</div>

I’m assuming you can embed SVG character data in the same way as I’m doing with PNG data, correct? If that’s the case, your method is the same as my current implementation, over canvas.

I’m still concerned for the character limit in a single post, which is why I was looking into uploading, rather than pasting an encoded image inline into the response.

Though as an advantage, I’m assuming that SVG has less data to store, and then would take up less space in your post?

---

<div class="post-metadata">

### Author: ![Cortrah](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/cortrah/32/51486_2.png) [@Cortrah](https://meta.discourse.org/u/Cortrah)
#### Post date: [February 16, 2016, 9:57pm UTC](https://meta.discourse.org/t/wip-reply-by-drawing/39080/15 "2016-02-16T21:57:36Z")

</div>

I was assuming that the canvas version was modifying the pixels of an image (or capturing the canvas as a bitmap) and then uploading the file.

If it’s layered on top then that is just like what I’m thinking already.

If I had a WIP: reply by drawing tool I’d do a diagram 😃

I’ll look at your source once I get discourse installed and configured and let you know once I understand it a bit beter.

In short if it ends up uploading the image, svg would be much smaller until a drawing got really complicated. If it is just recording the x and y values of the strokes as number values and saving those number values in the post. Then replaying/redrawing them on display they’d be about the same in terms of filesize.

So it occurs to me that that’s another way to go about it. Have the post just have a data structure of points that are redrawn on canvas when viewed if that’s not how it currently works.

---

<div class="post-metadata">

### Author: ![Cortrah](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/cortrah/32/51486_2.png) [@Cortrah](https://meta.discourse.org/u/Cortrah)
#### Post date: [February 17, 2016, 12:08am UTC](https://meta.discourse.org/t/wip-reply-by-drawing/39080/16 "2016-02-17T00:08:24Z")

</div>

Ok, I have discourse installed and configured, have read the plugin guides and have looked at the plugin. Nice job by the way, it was very easy to read.

While I could be wrong, I’m pretty sure that this is encoding the data in the image. If that’s the case, then every time it would need to save the image for sharing it would need to save the image data somewhere on the server in a binary format. The toDataUrl call is probably doing that in the browser via the canvas context but eventually it would need to be turned into a png in the file upload process, which is a nice format, but not very efficient for stuff like a line drawing.

But we can make this a lot easier and also more efficient without changing the code too much or moving to svg, though I need to figure out more about how discourse saves data and it may still be worth going to svg later.

Essentially what I’d suggest is that every time that you write a new path segment to the drawing context, that you also add the x and y coordinates to an array or tree data structure that gets embedded in the post in some non-visible way.

When rendering we can extract the coordinates and redraw again on the end users client in their canvas context.

Does that make sense or am I missing something?

---

<div class="post-metadata">

### Author: ![Cortrah](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/cortrah/32/51486_2.png) [@Cortrah](https://meta.discourse.org/u/Cortrah)
#### Post date: [February 17, 2016, 4:51am UTC](https://meta.discourse.org/t/wip-reply-by-drawing/39080/17 "2016-02-17T04:51:00Z")

</div>

Incidentally, what is the character limit?

---

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [February 17, 2016, 4:56pm UTC](https://meta.discourse.org/t/wip-reply-by-drawing/39080/18 "2016-02-17T16:56:13Z")

</div>

You can set it in the admin, but it defaults to 32k

---

<div class="post-metadata">

### Author: ![riking](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/riking/32/170938_2.png) [@riking](https://meta.discourse.org/u/riking)
#### Post date: [February 17, 2016, 6:54pm UTC](https://meta.discourse.org/t/wip-reply-by-drawing/39080/19 "2016-02-17T18:54:52Z")

</div>

Which means you can, at most, fit 24kb of base64 data.

---

<div class="post-metadata">

### Author: ![Cortrah](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/cortrah/32/51486_2.png) [@Cortrah](https://meta.discourse.org/u/Cortrah)
#### Post date: [February 17, 2016, 7:18pm UTC](https://meta.discourse.org/t/wip-reply-by-drawing/39080/20 "2016-02-17T19:18:51Z")

</div>

Oh ok. That’s plenty for what I think we are talking about.

[Next page](https://meta.discourse.org/t/wip-reply-by-drawing/39080.md?page=2)
