I am trying to implement an interface where users can dynamically enter text and upload images. I wish for the interface to have these features:
- The images should be moveable i.e, ability to drag and drop the images around.
- The text entered should automatically wrap around the images.
How could I accomplish this? I have looked at some jquery scripts and also looked through HTML5's canvas features, but am unable to find a solution.
Thanks for your time.
EDIT: This video shows the effect I wish to obtain:
http://www.youtube.com/watch?v=mYnj4Mz9g9g
TL;DR
This is a common and desirable feature that has been discussed numerous times in the history of CSS, and there is a specification under development to make it possible. Unfortunately, implementations are few and far-between, and some implementers are reluctant to work on it. Doing it with JavaScript is a complex problem for any non-trivial layout; such a solution is unlikely to be fast enough for your purposes and you will fast approach the sort of markup you'd expect from a PDF-to-HTML converter.
Background
There are two questions here: irregular text flow and excluding text and other inline elements from an arbitrary region of the page.
This is not the first time either feature has been discussed for CSS. In particular, flowing text around irregular floated shapes was mentioned in a CSS level 1 working draft back in 1996, and Eric Meyer's ragged float demo dates from at least 2002. This is a long overdue feature!
In June 2007, James Elmore suggested adding position
values to the float
property, enabling elements to be positioned arbitrarily on the page while excluding other elements from flowing underneath.
SVG 1.2 initially specified a model for flowed text regions, and goes into some detail on how this would be implemented. Unfortunately, the latest version of the spec (which is still in development) blows this out of the water by noting that previous work will be replaced with "a superset of the SVG 1.2 Tiny textArea
feature".
Current status (revised August 2012)
More recently, we have the CSS Exclusions specification, a proposal from Adobe and what you see being shown off in that video. As of August 2012, these have been implemented in IE 10 RTM and are slowly being rolled out in WebKit, but developers working for other vendors have expressed mixed feelings about the proposal.*
- Trident (IE): implemented in IE10 platform preview and available in the RTM. (Referred to as "positioned floats" in IE Test Drive, similar to James Elmore's proposal.)
- WebKit (Chrome, Safari): partially implemented, with patches gradually being approved for landing in the WebKit trunk, meaning we should start seeing this soon. (Bug 57311 - CSSRegions: add exclusions support in WebKit.)
- Gecko (Firefox): unlikely to be implemented soon; bug currently resolved as WONTFIX. (Bug 672053 - Add support for CSS3 Positioned Floats—note David Baron's objections concerning interoperability.)
- Presto (Opera): not yet implemented. (Bug tracker is private; I tried asking the ever gregarious Bruce Lawson if there was an open bug, but he is constrained from commenting on their roadmap.)
Adobe maintain a handy support matrix for easy reference.
Hackcough "Polyfilling"?
It would be difficult achieve a similar effect using JavaScript, and even more difficult to do it efficiently. I can think of two very naive approaches to make room for an absolutely positioned element in a region:
- "block out" space for element using strategically-inserted inline
span
s; or
- surround each word with a
span
element, and style each word individually to make room for the excluded element using padding.
I've hacked up a very broken demo of how the second approach might work. It's horrible, buggy and easy to break. I actually spent a few weeks after answering this question working on a polyfill for the Exclusions spec, but gave up because there were too many bugs and performance issues.
You will have myriad issues with either approach: columns, text alignment, errant child elements (especially floated or positioned elements!), various edge conditions, horrible things if you change the HTML, hyphenation—merciful heavens, I don't even want to think about hyphenation—and, of course, potentially magnificent performance issues after taking account of these things.
Performance issues can be ameliorated somewhat; for example, I've used elementFromPoint
to try and get the span
containing the first overlapping word directly, and some browsers even support caretPositionFromPoint
, which may also help. I think that with a lot of work, you could make something that works pretty well for static content; but making it fast enough that you can drag it around with the mouse? My demo page has precious little content and doesn't address any of the mind-bendingly complex issues you'd have to deal with to make this work on real web pages. Even if you can get around all of those issues, making it fast enough to drag around smoothly would be very challenging.
* I strongly hope vendors will implement CSS Exclusions. People have been asking for these features since the earliest days of CSS, and it is a common and legitimate visual design objective both on screen and in print.
This is possible in IE10, using positioned floats: http://ie.microsoft.com/testdrive/HTML5/PositionedFloats/Default.html
Other browsers have yet to support this.
Well, at least for the wrapping, if you want to use jQuery, you can use this jQSlickWrap plugin to have the text wrap around the irregularly-shaped image. It uses a nice HTML5 canvas technique.
See the text wrap example here: http://www.jwf.us/projects/jQSlickWrap/example2.html
Hope it helps!