Recently, I wanted to embed an photograph of a book page. I thought it would be nifty if the text from the page could be selected.
If you hover your mouse over this image, you should be able to select part of the text.
Ideally, it will look something like this…
It even works on Android (tried on Chrome, Opera, FireFox) and iOS 7.
So, how did I do it?
I then turned to SVG – Scalable Vector Graphics.
The way I’ve done this is almost certainly wrong and I’d appreciate any advice about the proper way to render text in an SVG.
The first part is easy – displaying a PNG as the background to the SVG. In this case, I’ve taken the image and Base64 encoded it.
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="566" height="166" > <image xlink:href="data:image/png;base64,iVBORw0KGg...." x="0" y="0" width="566" height="166" />
The X & Y co-ordinates are from the top left. I’ve manually added in the height and width of the image.
Next, we add the text.
<g fill-opacity="0"> <text x="70" y="45" font-size="14" font-family="serif" textLength="415" lengthAdjust="spacingAndGlyphs"> For nearly three years, between 1960 and 1963, MI5 and GCHQ </text> <text x="42" y="62" font-size="14" font-family="serif" textLength="440" lengthAdjust="spacingAndGlyphs"> read the French high grade cipher coming in and out of the French </text> ... </g> </svg>
As you can see, I’ve grouped the text together in a <g> element. I’ve set the opacity to zero – so while they are on top of the image, they cannot be seen unless selected. I’ve also manually split the lines and placed them on the image. I’ve set a “textLength” so that they’ll fit across the page and automatically adjust themselves if they’re too long.
This is very imprecise and quite time consuming. To get a better idea of how accurate (or not) it is, here’s the same image, with the opacity set to 0.5.
Close enough, but not brilliant.
Finally, I’ve had to reference the images via an iframe. Without doing that, I wasn’t able to select the text. I’m not sure if that’s a browser fault, or expected functionality.
If you can suggest a quicker and more accurate way of doing this – I’d love for you to leave a comment below.