Multiline editable textarea in SVG - svg

I'm trying to implement multiline editable textfield in SVG. I have the following code in http://jsfiddle.net/ca4d3/ :
<svg width="1000" height="1000" overflow="scroll">
<g transform="rotate(5)">
<rect width="300" height="400" fill="#22DD22" fill-opacity="0.5"/>
</g>
<foreignObject x="10" y="10" overflow="visible" width="10000" height="10000"
requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<p style="display:table-cell;padding:10px;border:1px solid red;
background-color:white;opacity:0.5;font-family:Verdana;
font-size:20px;white-space: pre;
word-wrap: normal; overflow: visible; overflow-y: visible;
overflow-x:visible;" contentEditable="true"
xmlns="http://www.w3.org/1999/xhtml">
Write here some text.
Be smart and select some word.
If you wanna be really COOL,
paste here something cool!
</p>
</foreignObject>
</svg>
In newest Chrome, Safari and Firefox the code works in some way, but in Opera and IE 9 not.
The goal is that:
0) Works in newest Chrome, Safari, Firefox, Opera and IE and if ever possible in some pads.
1) White-spaces are preserved and text wraps only on newline char (works in Chrome, Safari and Firefox, but not in Opera and IE 9 *).
2) The textfield is editable (in the same reliable and stabile way as textareas and contenteditable p elements in html) and height and width is expanded to fit text (works in Chrome, Safari and Firefox, but not in Opera and IE 9 *).
3) Texfield can be transformed (rotated, skewed, translated) while maintaining text editability (Tested rotation, but not work in any browser *).
EDIT: Foreignobject rotation works on Firefox 15.0.1, but not in
Safari 5.1.7 (6534.57.2), Chrome 22.0.1229.79, Opera 12.02, IE 9. Tested on Mac OS X 10.6.8.
4) Textfield can be clipped and masked while not necessarily maintaining text editability (not yet tested).
*) using above code
These all can be achieved using Flash, but Flash has so severe problems that it is not suitable for my purposes (after every little change in code, all have to be compiled again using Flex, which is slow, font size has limits, tracking technique is pixeloriented, not relative to em size etc.) and there still are differences across platforms. And I want to give a try to SVG!
GUESTION:
Can I achieve my goals 0-4 with current SVG support in browsers? Is coming SVG 2.0 for some help in this case?
EDIT: Changed display:table to display:table-cell (and added new jsfiddle), because display:table made the field to loses focus when pressed arrow-up on first text row.

It seems that when coder says "browser", one of the next two words is "workaround".
So one possible workaround is to use contenteditable p, place it on top of svg and make transformations to this.
If some svg element have to be on top of contenteditable p, then we must add one svg more on top.
This combination can be rendered via phantomjs to png/pdf.
If we want svg masks, clips or filters, they are not supported in any browser on html-elements. So to make them work, we must convert text on contendeditable p to paths (using font data from server or get pathdata clientside using this when it is more complete) and mask or clip these.
Not very easy workaround, but SVG support for editable textareas is very poor. Editable textarea is not implemented nearly in any browser for now although the spec here and here is rather old. Opera 12.02 has some sort of support, but buggy: try here to move cursor using up and down arrow keys.

Related

SVG zoom limits in browser

I have generated a large SVG file, but when viewing it in a web browser I can't zoom in far enough to see all the detail in it. Is there something I can do in the SVG source code to allow this?
The SVG is very tall and thin (1000px wide, 11000px high). When I open it in a browser by default the browser fits the whole thing into the view port, so it's just like a thin stripe down the center of the page - far too zoomed out to actually see anything. The browser allows me to zoom in to some extent, but only up to a certain point and then further zooming is not possible. Is this something that I can control from the SVG code?
The <svg> element looks like this:
<svg viewBox="0 0 1000 11000" version="1.2" xmlns="http://www.w3.org/2000/svg">
Please note, I am not embedding the SVG in an HTML page, I just have an SVG. Since the most common SVG viewer is a web browser I want people to be able to view the document properly in one.
Add a suitable height to the SVG. That will force the browser to render it that tall (and the user has to scroll to see the whole thing). For example 5000px tall:
<svg height="5000" viewBox="0 0 1000 11000" version="1.2" xmlns="http://www.w3.org/2000/svg">

Text in SVG's foreignObject not selectable

I have a SVG and want to display some text within that. Due to the limited text formatting options available in SVG I've read that it can be recommended to use HTML for text instead. Thus, inside of the SVG whenever I want to show text I have a foreignObject and within that a text p.
So the structure is: SVG -> foreignObject -> p
Works well so far! However, I cannot select the text within the p with the mouse. Is there any workaround?
EDIT:
Looks like it works in an easy example as shown in the answer below, but for some reason it does not work in this structure here.
Works perfectly fine for me.
<svg width="200px" height="80px">
<foreignObject width="200px" height="80px">
<html style="font-size:30px">
<p>Select me</p>
</html>
</foreignObject>
</svg>

SVG, vector-effect="non-scaling-stroke" and IE

As I understand it, the SVG attribute vector-effect="non-scaling-stroke" should prevent strokes from being distorted (made thicker or thinner) if/when the SVG object is scaled or stretched.
For example - in this fiddle (http://jsfiddle.net/1cj0ovae/5/), I have two SVG objects; both are 5x wider than they are tall. Because the view box of both calls for a square, the SVGs are stretched and distorted.
In the upper SVG - the green path is distorted - it's much thicker than it's supposed to be (stroke-width="2").
In the lower SVG, however, the red path is displayed "correctly" - a 2px thick stroke - because it has the vector-effect="non-scaling-stroke" attribute set.
This seems to work in Chrome, Safari, and Firefox, but not in even recent versions of IE (e.g., IE10).
Is this an IE bug? Is there a workaround?
vector-effects is part of SVG 1.2 tiny and the upcoming and as-yet-unfinished SVG 2 specifications.
IE has only targeted SVG 1.1 which does not have vector-effects. Other UAs have cherry picked parts of SVG 1.2 tiny such as vector-effects but no current UA implements it all (Opera 12 did I think).
To work around it figure out how wide the stroke should be using javascript. I.e. work out the difference between the transform that's applied to the shape and apply the inverse of that to the stroke-width. It's not straightforward as I found when I implemented this in Firefox.

Browser difference in displaying SVG RTL text with bidi-override and text-anchor="end"

I'm noting a difference between browsers in displaying text forced right-to-left and also using text-anchor="end".
<?xml version="1.0" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" >
<text x="10" y="50" font-size="30" font-family="sans-serif" writing-mode="rl" direction="rtl" unicode-bidi="bidi-override" text-anchor="end" stroke="green" fill="green">
Force RTL
</text>
</svg>
In Chrome(v 27.0.1453.93 m) and I.E.(v 9.0.8112.16421), the text is shown as I would expect, with glyph stroking starting from the end point of the text and progressing to the left. With the example above, it is displayed in the upper left corner of the browser.
In Firefox (v 20.0.1) glyph stroking, with text-anchor="end", is starting from the start point of the text and the display is off the page. If I remove the text-anchor attribute, Firefox displays as Chrome and I.E. do with the text-anchor.
My questions are
Does anyone understand what's happening here? Or is this a FF bug?
If there's no work-around, how can I switch between user-agents in the SVG so for Firefox, I can avoid using the text-anchor?
Thanks very much
It's a bug in Firefox. Fortunately it will be fixed reasonably soon (not sure exactly when) as we're revamping/rewriting text support in SVG. If you want to see it working properly, download a Firefox nightly type about:config in the URL bar and set svg.text.css-frames.enabled to true. So be careful about user agent tests because this will get fixed before too long.

SVG 'maskContentUnits' not rendering properly in mobile safari

I have an SVG I am building with Javascript. I load in a large SVG file, break it apart into pieces all drawn with paths, and place each element in my page. I'm only using these SVGs as masks for other images I am loading. Basically my structure is like the following.
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="26.750152587890625 10.117172241210938 197.24969482421875 348.1596221923828" width="197.25" height="348.16015625">
<mask id="designMask" maskContentUnits="objectBoundingBox">
<g id="CutContour1bg">
<path d="[my path coords]" style="fill:#FFFFFF;">
</g>
</mask>
<image href="http://myImage.jpg" style="mask: url(#designMask);" width="800px" height="800px" x="26.75" y="10.1171875">
</svg>
This renders the image being masked by my SVG perfect, in FF, IE9, Chrome, Safari 5.1 (desktop). In mobile safari however, the image does not render properly. I trace out coords of the mask, they are all correct. In FF I can see the SVG load (all black) then disappear as it becomes the mask. (I am waiting until the design is loaded, then wrap my <g> with <mask> since FF has an issue looking for the mask before the content is loaded.
This tells me the mask's position is exactly where it needs to be, but the maskContentUnits are not. They remain in the top left corner instead of the object's bounding box, like I'm telling it. I can barely see part of the image in the mask, so the mask units are correct, but I cannot get the maskContentUnits to work or be read in mobile safari.
Has anyone ever seen this issue, or any idea how to correct it? I hate having this work everywhere except mobile safari, as it is meant to mostly work on mobile... which defeats its not purpose haha.
Thanks!
I haven't found a way to make maskContentUnits work properly in mobile safari yet, I'm pretty sure it's just not recognized yet like other browsers. But I figured out a 'hack' to make the example work.
The issue is, the mask area resides in the top left corner of the browser, rather than of the svg object being used as the mask. So if you have an svg in the middle of your page, the image being masked will not follow the same positioning.
The way I found for it to work, is, I wrapped the svg inside a div with the same width as the svg, and modify the position of the div instead of the svg. This way the mask is technically still in the 'top left' corner, but of the div rather than the offset position of the svg.
If anyone finds a better way, to make maskContentUnits render proper in mobile safari, I'd like to hear it!

Resources