As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
What solutions other than HTML5 canvas can be used to implement free-hand drawing in JavaScript?
I have tried using HTML5 canvas but it did not work out as i was having problem in saving the canvas along with the text. Moreover the canvas can only be saved as image. But i need to save it in a format in which i can open and again draw and edit text.
UPDATE:
Now after you added more info to your question I know why you don't want to use canvas (which you still can use, but in a different way that you did before, but you may prefer another approach for you application - see below). People have voted to close your answer and it means that no new answer can be posted until it is reopened so I'll try update my answer. I have also voted to reopen your question.
Drawing in JavaScript Options
For free-hand drawing in HTML you have only 3 options:
Canvas
SVG (VML on IE)
Plugins (eg. Flash, Java, Silverlight)
You didn't explain why you don't want to use canvas.
Browser support
If the browser that you need to target doesn't support Canvas then you can:
use SVG or VML (or a library that uses SVG/VML like Raphaël)
use something that implements canvas (eg. in Flash) like:
http://code.google.com/p/fxcanvas/
http://flashcanvas.net/
http://excanvas.sourceforge.net/
API
If the native Canvas API doesn't suit your needs then you can use some canvas library that provides more functionality or a better API.
Here are some quick links to get you started:
http://dmitrybaranovskiy.github.io/raphael/
http://processingjs.org/
http://kineticjs.com/ (No longer maintained!)
http://www.createjs.com/#!/EaselJS
http://paperjs.org/
http://www.bhivecanvas.com/
http://fabricjs.com/
Retained Mode vs. Immediate Mode
What you need is a retained mode rendering (as opposed to immediate mode).
Canvas is an example of an immediate mode rendering while SVG/VML work in retained mode. It means that once you draw something on canvas it's just pixels and you can't manipulate objects that were drawn or save anything other than a flat raster image. SVG on the other hand keeps the entire DOM of the objects that you draw (just like in HTML) and you can easily manipulate everything that you have there, attach events, change colors, fill styles, move things after they were drawn or saved etc.
You can still use Canvas to do what you want but you need some library to help you keep track of everything that is being drawn - a library that provides a retained mode as an abstraction layer on top of the immediate mode Canvas API - some of the libraries that I previously described work that way, see the links above - but still you may find another approach better suited for your needs.
A Ready Solution
Take a look as the SVG-edit (or on GitHub) project - and especially see the demo and other projects that use SVG-edit. Using SVG-edit would probably be the easiest way to achieve your goals.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I wanted to create an icon in css, with an svg in between, just the way I saw in duolingo, I have given the screenshot (because you’ll have to login to see). When I saw the source, I saw that there is an svg file with all the icons as a pack, but individually they were set as icons in circles. I suppose that they have used the viewBox property in svg. I just wanted to know I guessed right, and if it is a sensible way, or should I use PNG files?
I don't know, but I guess they were using the CSS Image Sprites technique in conjunction with SVG images instead of using PNGs. This is great for when you have vector graphics and would like to support high-dpi devices ("Retina" and "4k" screens).
Putting them into the same file just reduces the network load and improves loading time. Using SVG also improves network bandwidth usages for these kind of graphics and yields the best fidelity.
So unless you need to target older browsers, using SVGs is a great idea, IMHO.
Just visited Duolingo. They use different techniques, as far as I recognize it. Indeed they cut out icons from some kind of sprite to display these. However, they also use RaphaëlJS to import SVGs which is nice, because it is very easy to manipulate the SVG afterwards.
You can use them to adapt the size of your graphics depending on the resolution of the viewer. However, be aware that older browsers don't support SVG very well (Raphaël has a great backwards compatibility here, but the browser limits still apply).
SVG are surely consume smaller amounts of storage and bandwidth. So it is up to you, if you want to use these or not. If you need to manipulate the graphics it's the way to go IMHO. However, if you need to support old browsers go with png.
This depends on if you are going to support IE8 or not. It's about 3% global usage. Unfortunately for the sector I work for, its more like 10% so I need to support it.
Inlining SVG, as you've described, is a great way to use SVG sprites. SVG elements are available to be styled by CSS so if you name your SVG elements appropriately, you could do something like:
.food-level-2 #icon-food.level-marker-2,
.food-level-2 #icon-food.level-marker-1 {
fill: orange;
}
.food-level-3 #icon-food.level-marker-3,
.food-level-3 #icon-food.level-marker-2,
.food-level-3 #icon-food.level-marker-1 {
fill: orange;
}
Which is awesome! User levels up, you change the class from .food-level-2 to .food-level-3, put a nice transition in there, and all is happy. But this is totally not supported by IE8, and hard to do a fall back for.
Background images, as with traditional css sprites, are very easy to make a fallback for.
.food-level-2{
background-image: (../img/food-level-2.png);
background-image: (../img/food-level-2.svg);
}
If the browser doesn't understand svg, it falls back to the png. Generating extra PNGs is easy if you're using something like font-squirrel or grunt/gulp. Make it a SASS mixin to write the .pngs first, .svgs second.
All is, less happy, but ok. You spend more time in Illustrator making all the possible variations. This looks like the route Duolingo choose with 1-1 png fallbacks. You still get crispy vector graphics where supported, and generally reduced load times.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I am creating a piano roll like interface, one like you might find in a DAW such as ableton, that looks something like this http://www.abletonlife.com/wp-content/uploads/2010/04/midi-track-big.jpg . The grid represents a canvas to draw in notes to be played, the red squares being the notes to play. You double click on an empty space to create a new note, and you can drag the edges to change the length of the note.
I am new to web dev so I am having a bit of trouble seeing what the right architecture for this might be. With my limited knowledge, the following are the architectures I can think of.
1) Rows of horizontal flex-boxes.
display: box;
box-orient: horizontal;
box-flex: 1;
Something like this, http://jsfiddle.net/ZgzNw/.
Pros:
When resizing the browser window, the browser will automatically
handle resizing of the notes and therefore the grid. Resizing of divs/notes also handled easily for zooming in and out and changing quantization values.
All notes in all positions already exist, when double clicking to "create" a new note, all you have to do is change the css for that note (to be red) etc.
Cons:
Since there is a div for every space in the grid, even empty spaces where there is no note to be played, there will be a lot of divs. Can the browser handle thousands of divs? As an extreme example if there is a 32nd note quantization, a song of 200BPM would have 50 measures per minute, take a 10 minutes song, that would be 500 measures. Going back to the jsfiddle example above and setting measures=500 and quant=32, I get the following error in the Chrome Developer tools console after a few seconds "Uncaught RangeError: Maximum call stack size exceeded". This is when creating the divs in that bit of javascript, If I lower the number to around 300 it is able to create the divs, but things become laggy.
2) Create the grid using divs of width=1px for the vertical lines of the grid. Create new note divs on the fly, position them manually (with position: float?) based on the position of the mouse click.
Pros:
Only have a divs for actual note that are on, so don't have the con of method 1) being an issue
Cons:
Have to manually compute everything, Where to place newly created note, zooming in/out means repositioning vertical markers for grids, and calculating new sizes for note divs. This was mostly handled automatically in the method 1.
I'm sure there are a lot more architectures and pros/cons to the two methods I describe, but I've never created any web applications and the extent of my web-dev experience is the tutorials I've done over the last 2 weeks to teach myself.
My question I guess is what is the best architecture for creating this piano roll interface I am describing? Specifically the UI representation, not the backing model.
I would create a simple model (probably just a multi-dimensional array) to contain the representation of the score, where each array item represented a note at a point in time. From the model, you can then draw/redraw accordingly. You could also perform operations like time shifts, quantizing, thinning, etc. by modifying the arrays.
Can the browser handle thousands of divs?
A few thousand, yes, maybe more--maybe even a lot more--but results will greatly vary by browser, by computer, even by the way they are positioned (floats tend to be slower than absolute positioning, for example, because the browser has more to calculate).
Instead, I would research using a canvas and draw/redraw based on your underlying model. You can detect events on the whole canvas, and depending on coordinates, easily map the event to the note(s) to which it corresponds.
KineticJS has some cool examples using a canvas
I would use a background image to represent tracks and measures, and one div for each note. It is not necessary to keep all notes as div’s in the browser, it would work better only to have the div’s for the visible up to 10 measures.
Imho, this should be done fixed-width, and there should not be any resizing of the piano roll at all. So you can use calculation of pixels. I don’t think this will work without making use of Javascript heavily.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I'm creating an HTML 5 chess game. Server side is socket.io / node.js / backbone.js.
I'm now beginning to write the view for the game board. Would it be easier to represent a chess board in canvas or DOM elements (aka divs)? Disregard browser compatibility.
Really comes down to your motives.
If you know game developement well, and you're comfortable with dividing screens into segments for purposes of collision-detection or otherwise, and you can easily create your own custom click events, per square/unit, based on where on the canvas the player clicked, then go with the canvas, as you'll open more doors to advanced animations and graphical-interactions that way.
If you aren't comfortable with that, and would like a straightforward way of knowing which square was clicked, and would like a clean-cut way of knowing if there was a unit in the square you landed on, without having to figure it out based on the X and Y where you clicked inside the game window, then go with the DOM -- really, those are the benefits and most everything else is a side-effect of picking one or the other.
Canvas for animation and "polish", DOM for event-listeners and array-based (or attribute-based) notification of square clicked.
For what you're planning to do, I think DOM would be the best option. Not because Canvas has any drawbacks, but for just based on the amount of work you'd need to be done, and the ability to change how the board looks easily.
You can use divs and place them absolutely, add css styles to show/hide pieces on a certain square, and after all that, you can even make a large background-less canvas and draw special effects on top of the DOM based chess board.
So all in all, DOM should be the way to go for you.
It depends on your goals.
If your main interest is just to visualize the state of the game by rendering icons for the pieces as images then using the DOM (e.g. tables or divs) for board locations is probably easiest.
If your are more interested in advanced graphicals then canvas might be better.
I've developed one of those quite recently and used HTML5 Canvas for graphical interface. It was extremely powerful for drawing the board and moving the pieces.
It is a hobby project with a friend,
but since I will invest in it (for UI/UX design) I need to be sure about feasability.
I am a programmer myself but I do not consider being experienced with JS and HTML5.
[Description]
I will be doing this kind of project BUT in JS and Html5 not Flash or Silverlight.
Here is the list of questions about feasabilities with JavaScript and HTML5: https://www.greetingbee.com/card-studio.aspx
we drag drop and manipulate images and in the end we want to save the greeting card (the composed surface) as image file...
how to do it without canvas? to printscreen or generate an image of specific area of html composition (DOM)
how to do it with canvas? keeping in mind performance ?
using SVG and/or PNG for keeping quality of shapes of greeting cards againts resizing etc.. any suggestions and tools recommendations
is there a JS script that could be used to make browser support some HTML5 features if it is not supporting some things, like make browser emulate and support :)), I do not like this question myself but who knows ))
I know its abit unusual case but we all might benefit if those answers find solutions and tips.
I share these links which have some sort of solutions:
www.stackoverflow.com/questions/12652769/rendering-html-elements-to-canvas/12660867#12660867
I know about html2Canvas which is said to be not so perfect, and Modernizer script that help to determine html5 features with browser
I don't know how to do it without canvases but with them there is toDataURL method. You can read about it here: http://www.nihilogic.dk/labs/canvas2image/
If You want to save image on server-side you could send data returned by toDataURL() to your server through AJAX or smthing like that.
As for second question about emulation of HTML5 there is a piece of code which enables you to use canvas tag on old IEs http://code.google.com/p/explorercanvas/
After not finding anything I like with regards to this question I'm looking to build my own in-browser graph editor. As a first step, I'm looking for a Closure based library to draw objects on a canvas where so I can do things like update an objects definition and trigger a redraw without to much complication.
From a breef look this lib looks to do what I want but I see nothing indicating that it's intended to work with closure (and in fact seems to be targeted at jQuery).
It seems the question is to spesific: the standard closure libs contain goog.graphics supporting general drawing primitives that white washes over the difference between canvas, SVG and VML to give a general retained graphics mode effect via each. goog.graphics.createGraphics selects the 'best' implementation based on what platform is being used.