JSFiddle - React, Tailwind, and code Playground
by dirtyd77
HTML
<svg height="200" width="200">
<rect x="10" y="10" width="100" height="100"></rect>
<text class="text"></text>
<foreignobject class="awesome" x="10" y="10" width="100" height="100">
<textArea></textArea>
</foreignobject>
</svg>
CSS
rect{
fill: red;
}
foreignObject{
position: relative;
}
textarea{
margin: 5px;
width: 80%;
height: 80%;
resize: none;
border: 2px solid blue;
outline: none;
}
textarea:disabled{
pointer-events: none;
-webkit-user-select: none; /* Chrome all / Safari all */
-moz-user-select: none; /* Firefox all */
-ms-user-select: none; /* IE 10+ */
-o-user-select: none;
user-select: none;
border: 1px solid gray;
}
JavaScript
var textArea = d3.select('textarea'),
foreignObject = d3.select('.awesome'),
daText = d3.select('.text'),
disable = false;
d3.select('foreignObject').on('dblclick', function (){
});
textArea.on('change', function (){
var textAreaNode = textArea.node(),
width = textAreaNode.clientWidth,
textValue = textAreaNode.value;
daText.html(textValue);
wrap(daText, width);
textArea.attr('display', 'none');
});
function wrap(text, width) {
text.each(function() {
var text = d3.select(this),
words = text.text().split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = 1.1, // ems
y = text.attr("y"),
dy = parseFloat(text.attr("dy")),
tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(" "));
if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join(" "));
line = [word];
tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
}
}
});
}
textArea.on('dblclick', function (){
disable = !disable;
console.log('double', disable);
textArea.attr('disabled', (disable ? 'disable' : null));
});