Open stewie opened 14 years ago
Hi,
Can you elaborate on your issue (which browser, how does it fail) a bit? I just downloaded http://github.com/bebraw/Harmony-Brushes/zipball/v0.37 , extracted it and opened "harmony.html" in Chrome. It just worked.
Since 0.37 I have made quite a bit of changes (different UI layout, better palette). I suppose it's time to finalize those changes and get 0.38 finally out.
I have yet to figure out how/where to host the app. You can find my first hack at http://storage.dangertree.net/harmonyStrokes/harmony.html (hosted by rhyolight). You can find more information about my initial work at http://nixtu.blogspot.com/2010/03/harmony-new-experimental-features.html .
Thanks for interest in the project.
I had been trying to load it in various browsers, but not in Chrome (closest to chrome that I tried was the SE Iron browser). Firefox wouldn't load the page (complaining about missing plugins) until I outcommented the Wacom [embed] object; afterwards I faced a string of various errors. Every time I tried to patch/fix the raised error, a different error showed up, so I abandoned the effort.
I just re-downloaded the v0.37 zipfile. First try is in Opera v10.something ...and its error console reports two instances of "linked script not loaded". One of these is 'square.js' (Typo? Should be 'squares.js') and the other Not Loaded script is ~panels/menu.js (the zipfile doesn't contain a file by that name)
So, just now, I've edited harmony.html (line 39) changing 'square.js' to 'squares.js', and would manually download the individual js/panels/menu.js file from github... but it doesn't exist.
When the app loads, the brushes panel is open. Its layout seems to be wrecked, some sliders are apparently missing, and not all displayed sliders are operational (cannot be dragged). I could close the panel and reopen it using the 'Brushes' link in the top menu; no other functionality.
After the square to squares edit, I'm seeing big-azzed top menu buttons labeled 'Brushes', 'Canvas', 'Modifiers'... and (due to hardcoded constrained container width?) the top portion of a 4th button which has been wrapped to a second row. Clicking it, I find that it opens 'Playback' panel.
Doggedly slow, but I can adjust the stroke width slider in the brushes panel (and see the mini display updated to reflect the changed setting)... but nothing I do/change in the panel enables me to draw. Mouse click/move over the canvas does not draw.
FWIW, excluding the Wacom issue (I can't recall whether that build is Wacom enabled) the 'dangertree' version worked perfectly for me across the various browsers I tested.
I tagged a new version, v0.38-pre, that does not use the panel approach anymore. The UI is still far from finished, though. Ideally the canvas should be on the background and tools/etc. should have their own panels on left and right.
Note that I have disabled brush preview by default for performance reasons. There might be ways to make it fast enough (cache?) but that has to wait for now.
I cannot guarantee that it will work without any problems. I guess there might be some bugs around as well.
I am not sure what's the right way to handle the wacom issue. Perhaps there should be separate versions (wacom/non-wacom), option or something. That's something to look into.
I will let you know once I have a proper version ready for some testing.
I'll try the new version and report back. Thanks.
You mentioned that you don't know where you might host an online demo. FWIW, I found a demo of another Harmony version at http://harmony.uphero.com ...and when I tried to view http://uphero.com I discovered its hosted by http://www.000webhost.com (free web hosting). Another hosting option would be sourceforge.net
Somewhere I read that you thrive (strive) toward minimalism. I suppose you meant in terms of UI appearance. Personally, I'm not keen on bloat -- in terms of jQuery dependence. It might run okay for you (on your kickass fast PC, rendered via Chrome browser) but it, and HTML canvas apps utilitzing it, is noticeably slow on various platforms I've tried. (Processing.js is even worse -- no op, or intolerably slow, across various browsers.)
Why include the Wacom support? Do you own/use a graphics tablet... or the feature is just included for the sake of uberkewlness? Considering that the friggin "additional plugins are required" error blocks non-Wacom users of various browsers from loading the app, the situation begs a separate Wacom-enabled build. Perhaps load the generic version first, and display a "click here for a Wacom-enabled version" link on the page... or point users to an interstitial URL which asks them to choose "Wacom or non-" link to the appropriate app.
The harmony colorselector has been buggy for me, across broswers, all the way back to the doob REV6 version. I'm nixing it, replacing it with 'jscolor' (from jscolor.com). The hotkey (shift) support from the current color picker is a great usability feature, so I'll want to hack jscolor to reposition its popup relative to cursor coordinates.
At Mr.Doob's blog, I had commented that I'd like to consider the prospect of embedding a custom 'chunk' into the saved PNG (or other format) imagefile header reflecting a snapshot of the current app settings, setting used to produce the image. Flags values for the chunk would specify 'non-essential' (so that the imagefile can still be opened with any app); any editor should preserve the chunk upon resaving. Loaded back into the Harmony app later (or if uploaded to a Harmony-centric online gallery), the embedded settings could be read/displayed like EXIF data is for digital photos... or the app could snap the values for each setting to match those reflected within an imported Harmony-created imagefile. Your base64.js could help make this possible.
Separately (until localStorage is widely supported across broswers) I'd like to enable the user to send (via a click) the current settings to a new browser window/tab. By copy/paste, a saavy user could create a new, named brush (preset) bearing those settings; a less saavy user could at least save the list of settings to a text file to later jog their memory "How did I do that?"
Undo / Playback: Considering that Harmony is an 'interactive drawing app'... seriously, aside from 'geeky kewlness', how much merit is there for a ( MEMORY HOG) 'Playback' feature? As for 'Undo', how many steps are enough? I really think that the 'Daniel' version of Harmony is on the right track -- provide an Undo feature, but set it disabled by default. A more mature build would (I'm saying) popup a modal window the first time a user enables Undo during a given session, cautioning that the feature can be a memory hog, advising that "by default, only xx (12?) undo steps are saved" and enabling him to alter the setting (#history steps saved). History? Undo? Stack? How about LAYERS? I really think kaleidosketch ( http://www.pumpkinpirate.info/ks/ ) got it "mostly right", several years ago.
You mentioned that you don't know where you might host an online demo. FWIW, I found a demo of another Harmony version at http://harmony.uphero.com ...and when I tried to view http://uphero.com I discovered its hosted by http://www.000webhost.com (free web hosting). Another hosting option would be sourceforge.net
Thanks. I will keep that in mind and give it a go at some point.
Somewhere I read that you thrive (strive) toward minimalism. I suppose you meant in terms of UI appearance. Personally, I'm not keen on bloat -- in terms of jQuery dependence. It might run okay for you (on your kickass fast PC, rendered via Chrome browser) but it, and HTML canvas apps utilitzing it, is noticeably slow on various platforms I've tried. (Processing.js is even worse -- no op, or intolerably slow, across various browsers.)
Good point about jQuery UI. I'm willing to replace it with a lighter alternative. Basically it should provide support for tabs, buttons and sliders. That should about do it. Any ideas are welcome.
Why include the Wacom support? Do you own/use a graphics tablet... or the feature is just included for the sake of uberkewlness? Considering that the friggin "additional plugins are required" error blocks non-Wacom users of various browsers from loading the app, the situation begs a separate Wacom-enabled build. Perhaps load the generic version first, and display a "click here for a Wacom-enabled version" link on the page... or point users to an interstitial URL which asks them to choose "Wacom or non-" link to the appropriate app.
I happen to use Wacom myself so that's why it's there for now. :) I did not expect anyone to actually use my version (at least yet). Good point about linking. I will just get rid of the plugin dependency for now and worry about it later.
The harmony colorselector has been buggy for me, across broswers, all the way back to the doob REV6 version. I'm nixing it, replacing it with 'jscolor' (from jscolor.com). The hotkey (shift) support from the current color picker is a great usability feature, so I'll want to hack jscolor to reposition its popup relative to cursor coordinates.
Solved (I use jscolor and a custom solution for palette).
At Mr.Doob's blog, I had commented that I'd like to consider the prospect of embedding a custom 'chunk' into the saved PNG (or other format) imagefile header reflecting a snapshot of the current app settings, setting used to produce the image. Flags values for the chunk would specify 'non-essential' (so that the imagefile can still be opened with any app); any editor should preserve the chunk upon resaving. Loaded back into the Harmony app later (or if uploaded to a Harmony-centric online gallery), the embedded settings could be read/displayed like EXIF data is for digital photos... or the app could snap the values for each setting to match those reflected within an imported Harmony-created imagefile. Your base64.js could help make this possible.
I'm not entirely convinced that storing app settings in image header is the way to go. See answer below for nicer alternatives.
Separately (until localStorage is widely supported across broswers) I'd like to enable the user to send (via a click) the current settings to a new browser window/tab. By copy/paste, a saavy user could create a new, named brush (preset) bearing those settings; a less saavy user could at least save the list of settings to a text file to later jog their memory "How did I do that?"
There are a couple of ways to handle persistency I can think of:
I suppose it might be interesting to fiddle with cookies to see how that plays out. At some point the size constraint is going to be an issue but I guess for now it just might do it.
Undo / Playback: Considering that Harmony is an 'interactive drawing app'... seriously, aside from 'geeky kewlness', how much merit is there for a ( MEMORY HOG) 'Playback' feature? As for 'Undo', how many steps are enough? I really think that the 'Daniel' version of Harmony is on the right track -- provide an Undo feature, but set it disabled by default. A more mature build would (I'm saying) popup a modal window the first time a user enables Undo during a given session, cautioning that the feature can be a memory hog, advising that "by default, only xx (12?) undo steps are saved" and enabling him to alter the setting (#history steps saved). History? Undo? Stack? How about LAYERS? I really think kaleidosketch ( http://www.pumpkinpirate.info/ks/ ) got it "mostly right", several years ago.
I have plans for a proper undo. A naive solution just stores whole image per step. My idea is to crop each step (contains only background of the stroke within its bounds) and to stash corner so it can be restored later on easily. This takes some extra computation during an actual stroke (old state of the canvas has to be stored before it can be cropped, min/max of stroke bounds (x/y) must be stored) but the penalty for that should be minimal.
Currently all brushes draw using the same API. It's up to that API to handle tracking min/max x/y during a stroke. The rest should be straightforward.
I know there are even neater ways (ie. crop more!) to handle this to save even more memory but I guess even this version would be somewhat superior compared to the naive approach. It can't be any worse. :)
jQuery UI. I'm willing to replace it with a lighter alternative.
I apologize for spouting about that. The widgetized UI operations aren't affecting the brushstroke operations, so performance-wise it's a non-issue.
I have plans for a proper undo
I've already provided my opinion about 'undo' in the other thread. Here, I'll mention that I've regarded 'playback' as a separate feature, different from 'undo'. The few playback demos I've seen actually (apparently) take into consideration the 'timeline', generating a replay which mimics the relative time(s) each operation occurred. In other words, if you recorded a session where you drew 2 ellipses in quick succession, then drummed your fingers for 10secs before deciding to also draw a rectangle... that 10sec period of inactivity would be reproduced as part of the playback. Here's one of the examples I had bookmarked: http://caimansys.com/painter/index.html
So, unless the brushstroke includes randomized sub-operations (and perhaps even if it does!) the app doesn't need to save a canvas (or cropped canvas, or imageData array). It has sufficient data onhand for playback if it just adds an array element at each stroke, representing: the values of any variable environmental params in effect (opacity, lineWidth, globalCompositeOperation mode [if selectable], strokeColor, etc) plus the moveTo coordinates for the stroke. (plus, optionally, a timestamp)
Wouldn't this suffice for a multi-step undo? If a slightly different result occurs due to some randomized factor, so what, who cares? Hmm... actually, it might be enlightening-slash-entertaining to repeatedly undo/redo a recorded draw operation and check out any slight variations due to randomization. Anyhow, push()ing a delimited set of numeric values to an array (or via JSON, check out http://colorillo.com ) involves minimal overhead. Matter o' fact, now that I'm thinking about it, I recall the colorillo helptext describing "while playing back a recorded drawing, you can pause it at any given step and begin painting. Afterward, you can save the 'forked' drawing to a new filename" (I don't recall the exact wording).
I'm not entirely convinced that storing app settings in image header is the way to go.
Badabing, badaboom. Okay, you talked me out of it. For (my) offline use, viewing the app from an xampp localhost URL and using JSON + PHP/mysql to store interesting 'custom brush' settings as well as "imagefile + caption" pairs... seems like the most appealing alternative.
I apologize for spouting about that. The widgetized UI operations aren't affecting the brushstroke operations, so performance-wise it's a non-issue.
No worries. The discussions have been really enlightening so far. Thanks for your time. :)
About undo: I played around with playback earlier (tag v0.2) and got it to work to some extent. There are some bugs and undo is slow (it redraws the whole painting) but at least I got a better idea how to really solve it now.
As you mentioned implementation is somewhat trivial (just stash brush + dab settings + timestamp). There are some issues like randomization (stash seed) that needs to be taken in count but nothing too serious. Playback is easy. The reason why a proper cropping scheme is needed has to do with undo.
Eventually you will paint on other strokes. This means that in order to restore their pixel data, you have to store the it somehow. Forgetting all about stroke data and just storing pure pixels within cropped area seems like a way to me.
There are some problematic cases (big strokes from corner to corner for instance) that fail with a simple solution (one cropped area). In this kind of corner cases it most likely makes sense to evaluate the stroke further and chop the area in small cropped parts.
In case drawn strokes are relatively small, the crop approach should provide substantial gains compared to a naive approach.
For now single step undo can be hacked in as discussed before. I do believe it would be somewhat nice and useful to have "unlimited" undo in the app at some point.
Badabing, badaboom. Okay, you talked me out of it. For (my) offline use, viewing the app from an xampp localhost URL and using JSON + PHP/mysql to store interesting 'custom brush' settings as well as "imagefile + caption" pairs... seems like the most appealing alternative.
Yeah. Probably using some light framework (web.py and co.) would work just fine for local usage. On db side even sqlite would be adequate for this sort of system.
The 'bebraw' codebase (zipfile) from GitHub... won't work for me. Many of the individual files have been edited more recently than those in the (0.37?) zipfile, so I tried manually grabbing the newer files. Still no luck getting it to work. I WOULD REALLY LOVE TO SEE THIS IN ACTION! IS THERE A WORKING DEMO ONLINE?