d3 textbox - drag and resize

by Amanda Williamson

HTML

<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<button id='textBox'>Text Box</button>

CSS

svg {
    border: solid 1px;
    height: 400px;
}

rect {
    fill: transparent;
    stroke: blue;
    stroke-width: 2px;
}

JavaScript

var w = 600, h = 500;
var svg = d3.select('body').append('svg').attr({width: w, height: h});

d3.select('#textBox').on('click', function () {
    new TextBox();
});

function TextBox() {
    var self = this, g, rect, rectData = [], isDown = false, m1, m2, isDrag = false;
    
    svg.on('mousedown', function() {
        m1 = d3.mouse(this);
        if (!isDown && !isDrag) {
            rectData = [{ x: m1[0], y: m1[1], w: 100, h: 50 }];
            g = svg.append('g');            
            rect = g.append('rect').attr('class', 'rect').data(rectData).call(dragR);
            point = g.append('circle').attr('class', 'point').data(rectData).call(dragP);
            drawTextArea();            
            updateRect();
            updatePoint();
            isDrag = false;
        } else { 
            isDrag = true;
        }
        isDown = !isDown;     
    })
    
    .on('mousemove', function() {
        m2 = d3.mouse(this);
        if(isDown && !isDrag) { 
            rectData[1] = { x: m2[0], y: m2[1] };
            updateRect();
        } 
    });   
    
    function updateRect() {
        rect.attr({
            x: rectData[0].x,
            y: rectData[0].y,
            width: rectData[0].w,
            height: rectData[0].h          
        });
        rect.style({ cursor: 'move' });
    }
    
    function updatePoint() {
        var x2 = rectData[0].x + rectData[0].w, y2 = rectData[0].y + rectData[0].h;
        point.attr({
            cx: x2,
            cy: y2,
            r: 5
        });            
    }
    
    function drawTextArea() {
        
        fo = g.append('foreignObject').attr('contentEditable', 'true')
        .style({
            position: 'relative',
            top: m1[1] + 'px',
            left: m1[0] + 'px',
            width: '70px',
            height: '70px'
        });
        div = fo.append("xhtml:div").html('text').attr('class', 'text-area');
        div.style({
            position: 'relative',            
        ...