Text in SVG's foreignObject not selectable - text

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>

Related

Re-using Tooltip text

I have a number of shapes that I want to display browser tooltips when I hover over them. However, because they contain images and caption texts, it means duplicating the same tooltip on each of their contents because they are higher in the Z-Order than the shape.
I was hoping to put them in a <defs> so that I could re-use them. For instance:
<defs>
<title id='t1'>This is my tooltip</title>
</defs>
<image ...etc...>
<use xlink:href="#t1"/>
</image>
but this doesn't work. Although it sounds like a fairly obvious use-case, I'm guessing that defs only helps with graphic elements. Is that true? Is there another way I can do this?
Having the same tooltip for my rectangle captions (or any text) is unnecessary if I include the CSS text { pointer-events: none; }.
Duplicating the tooltip across the combined shapes can be done by putting a transparent rectangle over them all and giving that a (single instance) tooltip.

Simple test SVG with 2 strokes in a path are different widths

There are many forms of this question on SO but none of them seem to cover this simple case: I have 2 lines in an SVG and they are drawn with different stroke widths. I've tried multiple tricks from the other posts but nothing seems to work. There is something simple here that I'm missing.
Here is the simplest form of this bug I can reproduce:
<!DOCTYPE html>
<html>
<body>
<svg width="120px" height="410px" viewBox="0 0 120 410">
<g id="rooms" stroke-width="8" stroke="#979797">
<path d="M0,0 L40,0"></path>
<path d="M0,20 L40,20"></path>
</g>
</svg>
</body>
</html>
And here is the drawing result:
I've also created a fiddle, trying to use the other SO articles suggestions, with no effect. I've also tested this in Safari, Chrome, and Firefox and all have the same result.
I'm a little stunned that such a simple thing has this type of drawing bug. I must be missing something very obvious. In the fiddle I also try using LINE instead of PATH and that DOES work properly. This appears to be related to paths.
OK, this was indeed a noob mistake. It wasn't clear that the width of a stoke is centered on the line. All paths drawn along the edge of my viewBox were effectively clipped.
TL;DR: Don't draw from 0,0

Svg viewbox and preserveAspectRatio is not doing like expected

I am viewing the following svg http://pastebin.com/pNdNEQ6z in my Firefox and chome.
Can someone tell me why the two graphs are somewhere in der middle of y an not starting at the top? If you change the viewbox to "0 200 650 800" everything is fine. why 200? I have played with preserveAspectRatio="xMidYMin" but this is not doing anything.
At the end of the day I want to display both charts completely visible starting at the top? And I would like to understand why it is not doing so right now :-)
Your problem is that you had a typo on your first embedded <svg> element (you had hight="400" instead of height="400") and were not using a …YMin alignment on the outer.
Fixed, it looks like this:
<svg … preserveAspectRatio="xMidYMin">
<svg … height="400">
Demo: http://jsfiddle.net/WAVZj/

Multiline editable textarea in 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.

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