bebraw / Harmony-Brushes

Harmony+rhyolight's brushes+own modifs (mirror, constraints)
MIT License
9 stars 1 forks source link

Chrome... or bust? #3

Open stewie opened 14 years ago

stewie commented 14 years ago

v038a UI still not rendering properly in FF and Opera

Even with Iron Portable (Chromium), some issues: Although the cursor crosshairs don't seem to be the exact same color as the canvas background color, the crosshairs disappear while pointed to any "not-yet-painted a different color than the bg" canvas coordinates.

Perhaps by design, the mini samples of stroke styles are no longer displayed at left for each brush name.

No button to "start a new page" or "clear the canvas". Click the X and close the current canvas... and the only way to continue drawing it to refresh the page. [edit] I eventually clicked the unlabeled plus sign icon. Create new page? The textbox accepts focus but won't accept my input. Clicking 'Copy' seemed to clear the canvas or display a blank slate (didn't copy the existing content to a new page. After several tries, I now have several canvases -- 'Page' and 'Tab1' and 'Tab2'...

'Array' and 'Group' are awesome. From looking at screencaps, I had no idea what these controls provided.

THE 4 CORNERS PALETTE BUILDER... wasn't immediately intuitive, but now that I've used it, I'm blown away! I've never seen such a device in any graphics app. Is this your own, novel, construct?

Usability note: idunno what your screen resolution during testing is/was... but about half the width of the canvas is hidden (scrollbar present) on my 1280x1024 screen. Because of this, horizontalmirror seemed like it wasn't working at first, until I figure out the entire canvas wasn't visible. Probably should have init() consider screen size when creating the canvas... and users will probably welcome inputs to control resizing the canvas on-the-fly. The jQueryUI-powered dragbars for resizing the side containers are awkward (and their layout gets scrambled when dragged to a narrow width). Bumping the window edge to expand the side menu, along with autocollapsing to minimal width onblur, that might be a usable construct... but dockable, floating menus (ala mugtug.com/sketchpad) seem much more usable. Did I read somewhere you mentioned "can't draw under the panels"? (the mugtug app doesn't suffer this problem).

Consider applying bgcolor via CSS to the element containing the canvas, rather than solid-filling the canvas to create a bgcolor. (I haven't checked your code. Maybe you are already doing this.) Later, ala the 'Artist Sketchbook' Opera widget, you can enable users to load a background image to that container... and utilize a separate stacked canvas (under working layer, above background div) with variable opacity, to create a 'tracing' mode of usage.

Related to the above, if the unpainted canvas pixels remain transparent, vs a solid fill, the "destination-over" compositing mode becomes useful (and interesting!) -- enabling the user to play with "underpainting" effects, in conjunction with variable stroke opacity.

Today is the first I've successfully loaded your app (in IronPortable). Maybe they're removed from the current version, but I don't see controls to toggle constraints.

Hmm, upon creating a new 'page' I realized there's nothing onscreen to indicate the current brush color.

Eraser 'brush': He not worky. Does nothing.

mirroring: Something is awry, or is "not as expected". Without radial enabled, and both hMirror + vMirror enabled, the brush is only drawing to THREE quadrants. WITH radial enabled along with the other 2... the result is only "as expected" if the radial slider is at the (numerically unlabeled) far left position. These controls shouldn't be interdependent, nor should they conflict. Maybe that's why the kaleidosketch author adopted the "rotations" and "reflection" nomenclature?

Yeah, some of my rambling here is beyond the scope of 'issues' with the current version. FYI, earlier today I tried posting to your nixtu blog, but iNtENsEdeBatE woudn't accept my 'guest' post.

Chrome has, what, 5-8% market share? Doesn't make sense to use that alone as a testbed for the app.

'Scuse me for saying so (or don't), but MrDoob and y'all seem to have a propellerhead fixation on 'closure' and preserving the global namespace, and object prototypification-alism (or sumpthin). I don't give a rat's ass whether the end result is 'embeddable', able to be integrated (ala the poorly-appointed canvasPaint, destined for Moodle, callable by TinyMCE). Programmically building the menu content via document.container.appendChild and myriad, scripted, lines like this.xyz.syle.property for every blessed CSS attribute is INSANELY obtuse, IMO.

The scope of the app I'm cobbling together is broader than 'procedural drawing'. I began tinkering with the canvas object with the hope of replicating the mouse-chasing behavior and visual effect demonstrated in the 'grappa' Java applet. A year or so ago i discovered bomomo.com and, sifting through its inscrutable (to me) code, I thought "close, but no cigar". I did manage to add controls for the number of bomomo particles/lines and drawing speed. Now, after discovering Harmony (and, specifically, the 'Ribbon' brush) I can finally grasp the "how to build a drawing app around it".

With that (my) scope in mind, I'm at a loss to understand why most of the Harmony forks ASSume that each 'brush' (er, drawing mode) will fit the same, chockablock, prototype template... or should be 'extended' from some base {cough} object 'class'. Equally confusing to me is tendency to create local vars and redundant local $(#myAssIsHuge) jQuery selector lookups. The UI controls are globally accessible. For the sake of speed, reference the DOM once per control and create a label for it in the global scope. Done. Am I overlooking something? Is there, somehow, merit in cluttering the code with redundant local $selector lookups?

bebraw commented 14 years ago

v038a UI still not rendering properly in FF and Opera

Noted. Thanks for the info.

Even with Iron Portable (Chromium), some issues: Although the cursor crosshairs don't seem to be the exact same color as the canvas background color, the crosshairs disappear while pointed to any "not-yet-painted a different color than the bg" canvas coordinates.

That looks like a browser bug for me (I can confirm it here). Perhaps there's nicer type of cursor to use (alternative one could be overlayed on canvas but that would incur a small performance penalty).

Perhaps by design, the mini samples of stroke styles are no longer displayed at left for each brush name.

I disabled that feature for now as it renders too slow (no cache). If you want, you can enable it at src/conf.js (SHOWPREVIEWIMAGES). You can find various other settings there as well.

No button to "start a new page" or "clear the canvas". Click the X and close the current canvas... and the only way to continue drawing it to refresh the page. [edit] I eventually clicked the unlabeled plus sign icon. Create new page? The textbox accepts focus but won't accept my input. Clicking 'Copy' seemed to clear the canvas or display a blank slate (didn't copy the existing content to a new page. After several tries, I now have several canvases -- 'Page' and 'Tab1' and 'Tab2'...

The UI is a bit kludgy, yes. I have to look into that focus issue. I suppose it's nicer to replace + with "New Page" button as that reads better.

I cannot reproduce the issue with "copy". The idea is that is toggles whether or not to copy the content of the currently active page to the new one. As it's a bit hidden there, I think it makes sense to move it to the page tools (more appropriate context).

'Array' and 'Group' are awesome. From looking at screencaps, I had no idea what these controls provided.

Ideally it should be possible to combine different modifiers. I want to separate ones dealing with symmetry (mirrors, etc.) and perhaps move the others to brushes in some neat manner.

It would be nice if there was a way to construct new brushes easily within the app. Currently there are too many brush options visible. It should be possible to customize which options to show for given brush. Additionally there should be a way to determine which brushes to show in the painting UI altogether.

THE 4 CORNERS PALETTE BUILDER... wasn't immediately intuitive, but now that I've used it, I'm blown away! I've never seen such a device in any graphics app. Is this your own, novel, construct?

I have always found conventional palette found in most apps somewhat cumbersome. I decided to replace it with something fitting my needs better. I'm glad you found it useful. :)

Usability note: idunno what your screen resolution during testing is/was... but about half the width of the canvas is hidden (scrollbar present) on my 1280x1024 screen. Because of this, horizontalmirror seemed like it wasn't working at first, until I figure out the entire canvas wasn't visible. Probably should have init() consider screen size when creating the canvas... and users will probably welcome inputs to control resizing the canvas on-the-fly. The jQueryUI-powered dragbars for resizing the side containers are awkward (and their layout gets scrambled when dragged to a narrow width). Bumping the window edge to expand the side menu, along with autocollapsing to minimal width onblur, that might be a usable construct... but dockable, floating menus (ala mugtug.com/sketchpad) seem much more usable. Did I read somewhere you mentioned "can't draw under the panels"? (the mugtug app doesn't suffer this problem).

Good point about resolution/horizontal mirror. Ideally it should be possible to set the pivot of mirrors manually.

I plan to get rid of jQuery dragbars and replace them with something more comfortable. The idea is that the canvas should be on the background and the UI elements should be overlayed upon it. This should alleviate the resolution issue.

I plan to split the UI controls in two sidebars. The left one should contain minimal controls for selecting and manipulating brushes. The right one should contain controls that deal with more general settings (canvas, symmetry and such).

Consider applying bgcolor via CSS to the element containing the canvas, rather than solid-filling the canvas to create a bgcolor. (I haven't checked your code. Maybe you are already doing this.) Later, ala the 'Artist Sketchbook' Opera widget, you can enable users to load a background image to that container... and utilize a separate stacked canvas (under working layer, above background div) with variable opacity, to create a 'tracing' mode of usage.

I'm doing it using CSS already. :) Later on it would be nice to offer means to use gradient background, textures, images ie.

Today is the first I've successfully loaded your app (in IronPortable). Maybe they're removed from the current version, but I don't see controls to toggle constraints.

Right. I haven't restored constraints yet. I have some ideas how to make them better (interactive UI, cycling target and such) but haven't mucked around with the implementation yet.

Hmm, upon creating a new 'page' I realized there's nothing onscreen to indicate the current brush color.

As the idea is that the artist changes color via keyboard while painting (ijkl keys) and concentrates on the cursor, perhaps there could be a "flash" of the current color. Basically all it would do would be to render a simple box containing the new color at the location of the cursor for a sec or two (just long enough to realize what color it is).

Alternatively the current color could be highlighted better at the color selector (perhaps using a dot). Perhaps this would be a nice feature to have in any case.

Eraser 'brush': He not worky. Does nothing.

Yup. Not implemented yet.

mirroring: Something is awry, or is "not as expected". Without radial enabled, and both hMirror + vMirror enabled, the brush is only drawing to THREE quadrants. WITH radial enabled along with the other 2... the result is only "as expected" if the radial slider is at the (numerically unlabeled) far left position. These controls shouldn't be interdependent, nor should they conflict. Maybe that's why the kaleidosketch author adopted the "rotations" and "reflection" nomenclature?

Currently the modifiers are considered separate (just for testing :) ). Ideally they should be treated as a stack. That's something to be done still. The UI is still very far from finished.

Yeah, some of my rambling here is beyond the scope of 'issues' with the current version. FYI, earlier today I tried posting to your nixtu blog, but iNtENsEdeBatE woudn't accept my 'guest' post.

Gah! Can you provide more details (browser, error) so I can debug the issue further?

Chrome has, what, 5-8% market share? Doesn't make sense to use that alone as a testbed for the app.

Well. Considering it's not a commercial product (target market is just one person :) ), it's fine enough for now. I can see your point though. Given that the concept works well on Chrome, I don't see why not to focus on other platforms after that too.

'Scuse me for saying so (or don't), but MrDoob and y'all seem to have a propellerhead fixation on 'closure' and preserving the global namespace, and object prototypification-alism (or sumpthin). I don't give a rat's ass whether the end result is 'embeddable', able to be integrated (ala the poorly-appointed canvasPaint, destined for Moodle, callable by TinyMCE). Programmically building the menu content via document.container.appendChild and myriad, scripted, lines like this.xyz.syle.property for every blessed CSS attribute is INSANELY obtuse, IMO.

If you compare the source of my version and mydoob's, you will notice they are somewhat different. I pretty much rewrote everything to fit my view on how to construct apps (coming from Python world I appreciate modularity).

Feel free to point out specific issues you happen to find. I'm always willing to learn from my errors. :)

The scope of the app I'm cobbling together is broader than 'procedural drawing'. I began tinkering with the canvas object with the hope of replicating the mouse-chasing behavior and visual effect demonstrated in the 'grappa' Java applet. A year or so ago i discovered bomomo.com and, sifting through its inscrutable (to me) code, I thought "close, but no cigar". I did manage to add controls for the number of bomomo particles/lines and drawing speed. Now, after discovering Harmony (and, specifically, the 'Ribbon' brush) I can finally grasp the "how to build a drawing app around it".

With that (my) scope in mind, I'm at a loss to understand why most of the Harmony forks ASSume that each 'brush' (er, drawing mode) will fit the same, chockablock, prototype template... or should be 'extended' from some base {cough} object 'class'. Equally confusing to me is tendency to create local vars and redundant local $(#myAssIsHuge) jQuery selector lookups. The UI controls are globally accessible. For the sake of speed, reference the DOM once per control and create a label for it in the global scope. Done. Am I overlooking something?

Is there, somehow, merit in cluttering the code with redundant local $selector lookups?

Probably not. I haven't focused on optimizing the code yet. Valid point about the globals, though.

stewie commented 14 years ago

In our dialog so far, we've covered a lot of ground. I read that you have a Wacom tablet, so I understand your enthusiasm for providing Wacom support. There should be a way to conditionally insert the embed tag. I don't know whether the HTTP User Agent request header reflects Wacom, but seems to me it should (if you have the browser plugin installed, hmm or is it an 'extension'? it might be mentioned in the UA string, along with Flash and/or Silverlight etc). If you can't autodetect, perhaps the app init() could display a confirm prompt "activate Wacom support?" and body.appendChild the [embed] or [object] Wacom object. This would preclude the chore of maintainng dual codebases.

I'm not positive, but I believe the canvas.fillText() method may the hangup for (unsupported by) Firefox and Opera. If you're only using fillText() to overlay brush 'names' onto mini-canvases which serve as graphic buttons... that might be the only thing standing in the way of FF/Opera users successfully loading the app. If you feel compelled to retain the 'sexy' buttons, screencapping and creating images to serve as CSS background-images for the buttons would be a workable alternative.

crosshairs browser bug: Across numerous canvas apps/demos, this is the first time I've noticed the disappearing crosshairs. Perhaps changing to a slightly different bgcolor will resolve the problem? Perhaps explicit declaration of the canvas "cursor" attribute in the stylesheet will resolve the problem?

I cannot reproduce the issue with "copy".

Again, the (mis)behavior is: "the textbox accepts focus + displays a text cursor, but typed characters do not register in the textbox".

It would be nice if there was a way to construct new brushes easily within the app.

I heartily agree. My wording is slightly different: "enable user to save the current brush settings to a new, named, preset"... and I think that's unattainable until we can count on universal support for localStorage. JSON? I hear ya... but that leaves the user screwed when he wants to use the app offline.

Currently there are too many brush options visible.

Place the controls for "advanced" parameters in a collapsible div?

It should be possible to customize which options to show for given brush.

It's absolutely possible and, IMO, necessary to do so. Instead of attempting to accomplish it programmatically, by passing args or push()ing args to a stack... my approach is to simply place the set of controls specific to each brush into hand-coded dedicated DIVs (each initially style.visibility=hidden), and use the onChange event handler for the brush selector control to toggle the appropriate DIV visible within the parent container.

Additionally there should be a way to determine which brushes to show in the painting UI altogether.

I'm handling it (conditional display of input/control sets) like this:

An everpresent label "Drawing mode:" along with radio buttons for the user to choose: o manual brushstrokes: sketch / doodle o interactive, mouse-chasing painter boids o autodraw / screensaver mode

During the workflow of drawing on a given canvas, the user can (will) jump between modes. I haven't yet allowed for a "shapemaker" mode (polygon, ellipse, rect, bezier, etc); this will probably be bound to a fourth radio button.

When user chooses "manual drawing" mode, a "brush styles" selectbox is toggled visible. (No graphical clues to suggest what each brush does -- let the user explore, or he can click contextual [?] links to read tips/explanation/help specific to a given feature.) Based on user's "brush style" selection, a "brushstroke options" panel becomes visible, populated with the appropriate brush-specific DIV. (is the panel draggable? dockable, ala mugtug.com ...I'm not that far into coding it)

Regardless which "drawing mode" is active, a "Layers" panel is visble to the user. Reiterating what I mentioned earlier, "I think Kaleidosketch got it mostly right" http://www.pumpkinpirate.info/ks/

If you think in terms of layers... SEVERAL headaches evaporate. First of all, technically "there is no canvas BACKGROUND color" (necessitating a separate UI control). Upon save, unpainted pixels are sent to output as transparent. If user desires a "solid color background" (helptext conditionally displayed during the 'save' workflow re-emphasizes this) he can create a layer, floodfill it to the desired color (drawRect op) and drag it to the bottom of the layer stack. Second, even if the app doesn't provide per-layer canvas opacity control, a single (adjustable opacity) "tracing layer" can be provided (below the canvas stack; above an imported CSS bgimage). Third...

...third, 'cept it may be "Numba One" in terms of headache relief, the layers construct frees you from the chore of providing history/undo. Any time the user wishes to preserve (but not yet output) a waypoint, he can just add a new layer and continue working in the new layer -- toggling the previous layer(s) hidden or visible, at will -- for comparison and/or for selective (flattenCanvas) output later. (I trust you'll agree the 'stack' construct beats the 'tabbed, "saved" Pages' construct, hands-down.)

A single-step undo/redo is all the user really needs. Considering all the exploratory 'fun' from rearranging and selectively hiding various layers in the stack (perhaps the scenario begs availability of a 'merge with previous layer' command, but)... I just can't abide the chore of wrestling with memory optimization toward supporting multiple undo.

sets of colors to use as pre-built palettes

You should be able to source 'sets' from colorjack.com and mugtug.com and a number of other sites. ViewSource and check the code driving their webpages -- for some sites, you'll find that the datasets sent to the browser (and rendered into CSS containers) are, conveniently, already in js arrays [rrr,ggg,bbb,rrr2,ggg2..]

changes color via keyboard while painting (ijkl keys)

Ha! Thanks, I completely missed that.

bebraw commented 14 years ago

As there are quite a few little issues to sort out, I'm filling the issue tracker with those as I reply. This should make it easier to track what to focus on. :)

I'm not positive, but I believe the canvas.fillText() method may the hangup for (unsupported by) Firefox and Opera. If you're only using fillText() to overlay brush 'names' onto mini-canvases which serve as graphic buttons... that might be the only thing standing in the way of FF/Opera users successfully loading the app. If you feel compelled to retain the 'sexy' buttons, screencapping and creating images to serve as CSS background-images for the buttons would be a workable alternative.

Thanks! Added to TODO. Perhaps http://code.google.com/p/canvas-text/ will fit the bill in this case.

Currently there are too many brush options visible. Place the controls for "advanced" parameters in a collapsible div?

Good idea. That will do just fine for now. :)

It's absolutely possible and, IMO, necessary to do so. Instead of attempting to accomplish it programmatically, by passing args or push()ing args to a stack... my approach is to simply place the set of controls specific to each brush into hand-coded dedicated DIVs (each initially style.visibility=hidden), and use the onChange event handler for the brush selector control to toggle the appropriate DIV visible within the parent container.

Yeah. That sounds simple enough.

Additionally there should be a way to determine which brushes to show in the painting UI altogether.

By this I meant that the user should be able to build some sort of sets that contain brushes suitable for the current task at hand.

I did find your idea of "drawing mode" really cool, though. I never thought about it that way. Finally a good reason to dive into boids and such. :)

I'm still a bit ambivalent on the concept of layers. Sure, the Kaleidosketch approach works. Perhaps it might make sense to extend the concept of pages a bit instead.

In this case each tab would represent a "project" that consists of "pages" (a layer). As new pages are created they are overlayed on the old ones just like in conventional layer systems.

I think this sort of approach would be somewhat compact UI wise (opacity, mixing mode etc. could be hidden in page tools) compared to conventional approach.

If you think in terms of layers... SEVERAL headaches evaporate. First of all, technically "there is no canvas BACKGROUND color" (necessitating a separate UI control). Upon save, unpainted pixels are sent to output as transparent. If user desires a "solid color background" (helptext conditionally displayed during the 'save' workflow re-emphasizes this) he can create a layer, floodfill it to the desired color (drawRect op) and drag it to the bottom of the layer stack. Second, even if the app doesn't provide per-layer canvas opacity control, a single (adjustable opacity) "tracing layer" can be provided (below the canvas stack; above an imported CSS bgimage). Third...

I think it might be enough just to provide means to set initial color for background (CSS style) and handle more advanced options directly via special pages (layers) that may contain gradients/images/whatnot.

...third, 'cept it may be "Numba One" in terms of headache relief, the layers construct frees you from the chore of providing history/undo. Any time the user wishes to preserve (but not yet output) a waypoint, he can just add a new layer and continue working in the new layer -- toggling the previous layer(s) hidden or visible, at will -- for comparison and/or for selective (flattenCanvas) output later. (I trust you'll agree the 'stack' construct beats the 'tabbed, "saved" Pages' construct, hands-down.)

Yeah. This sort of layered approach definitely fits the app better. :)

A single-step undo/redo is all the user really needs. Considering all the exploratory 'fun' from rearranging and selectively hiding various layers in the stack (perhaps the scenario begs availability of a 'merge with previous layer' command, but)... I just can't abide the chore of wrestling with memory optimization toward supporting multiple undo.

Good point. Sometimes even a step or two is enough. That should be quite simple to add.

You should be able to source 'sets' from colorjack.com and mugtug.com and a number of other sites. ViewSource and check the code driving their webpages -- for some sites, you'll find that the datasets sent to the browser (and rendered into CSS containers) are, conveniently, already in js arrays [rrr,ggg,bbb,rrr2,ggg2..]

I just took a look at colorjack. In order to fit the sets to the current palette system there should be way to render it in arbitrary shapes (triangle, hexagon, whatnot).

I think this means that to make this work well, the gradient should be rendered as smooth within the shape while it should be possible to set the colors of the vertices of the shape as currently. In this case the current navigation scheme would still be valid (just offset cursor within shape).

stewie commented 14 years ago

colordata for palette sets: Without regard to presentation, I was just suggesting a few places which might serve as sources for pre-built datasets (thematic named sets of colors, like "crayola32", "reds n purples", "skintones", and whatnot).

Since you mentioned presentation... the shaded cell borders in your current palette device will make it difficult to tell which color is selected. At the moment, I don't think you're applying different CSS attributes to highlight the cell displaying the active color... but the shaded borders suggest recessed/inactive choices -- I repeatedly caught myself squinting, attempting to 'find' the highlighted color swatch (which, by convention, would indicate the currently selected color).

bebraw commented 14 years ago

Without regard to presentation, I was just suggesting a few places which might serve as sources for pre-built datasets (thematic named sets of colors, like "crayola32", "reds n purples", "skintones", and whatnot).

Ok. That makes sense.

Since you mentioned presentation... the shaded cell borders in your current palette device will make it difficult to tell which color is selected. At the moment, I don't think you're applying different CSS attributes to highlight the cell displaying the active color... but the shaded borders suggest recessed/inactive choices -- I repeatedly caught myself squinting, attempting to 'find' the highlighted color swatch (which, by convention, would indicate the currently selected color).

I just improved it by setting border of the currently selected color black. Later on there could be some nice heuristic for figuring out nice one perhaps (ie. invert currently selected color and use it). At least it's a bit better now. :)