svg形状的文本区域 [英] Text area in svg shapes

查看:137
本文介绍了svg形状的文本区域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用联合js在svg中创建一个文本区域.但是,我无法在文本区域中输入任何文本.如何使文本区域可编辑?

Created a text area in svg using joint js. However, I am not able to enter any text in the text area. How to make the text area editable?

代码:

var graph = new joint.dia.Graph;

                var paper = new joint.dia.Paper({
                    el: $('#myholder'),
                    width: 1500,
                    height: 700,
                    model: graph
                });

                // Create a custom element.
                // ------------------------
                joint.shapes.html = {};
                joint.shapes.html.Element = joint.shapes.basic.Generic.extend(_.extend({}, joint.shapes.basic.PortsModelInterface, {
                    markup: '<g class="rotatable"><g class="scalable"><rect/></g><g class="inPorts"/><g class="outPorts"/></g>',
                    portMarkup: '<g class="port<%=1%>"><circle/></g>',
                    defaults: joint.util.deepSupplement({
                        type: 'html.Element',
                        size: {width: 100, height: 80},
                        inPorts: [],
                        outPorts: [],
                        attrs: {
                            '.': {magnet: false},
                            rect: {
                                stroke: 'none', 'fill-opacity': 0, width: 150, height: 250,
                            },
                            circle: {
                                r: 6, //circle radius
                                magnet: true,
                                stroke: 'black'
                            },
                            '.inPorts circle': {fill: 'green', magnet: 'passive', type: 'input'},
                            '.outPorts circle': {fill: 'red', type: 'output'}
                        }
                    }, joint.shapes.basic.Generic.prototype.defaults),
                    getPortAttrs: function (portName, index, total, selector, type) {

                        var attrs = {};
                        var portClass = 'port' + index;
                        var portSelector = selector + '>.' + portClass;
                        var portCircleSelector = portSelector + '>circle';
                        attrs[portCircleSelector] = {port: {id: portName || _.uniqueId(type), type: type}};
                        attrs[portSelector] = {ref: 'rect', 'ref-y': (index + 1) * (10 / total)};
                        if (selector === '.outPorts') {
                            attrs[portSelector]['ref-dx'] = 0;
                        }
                        return attrs;
                    }
                }));


                // Create a custom view for that element that displays an HTML div above it.
                // -------------------------------------------------------------------------

                joint.shapes.html.ElementView = joint.dia.ElementView.extend({
                    template: [
                        '<div class="html-element">',
                        '<button class="delete">x</button>',
                        '<span id="lbl" value="Please write here"></span>',
                        '<textarea id="txt" type="text" value="Please write here"></textarea>',
                        '</div>'
                    ].join(''),
                    initialize: function () {
                        _.bindAll(this, 'updateBox');
                        joint.dia.ElementView.prototype.initialize.apply(this, arguments);

                        this.$box = $(_.template(this.template)());
                        // Prevent paper from handling pointerdown.
                        this.$box.find('input,select').on('mousedown click', function (evt) {
                            evt.stopPropagation();
                        });


                        // This is an example of reacting on the input change and storing the input data in the cell model.
                        this.$box.find('textarea').on('change', _.bind(function (evt) {
                            this.model.set('textarea', $(evt.target).val());
                        }, this));
                        this.$box.find('.delete').on('click', _.bind(this.model.remove, this.model));
                        // Update the box position whenever the underlying model changes.
                        this.model.on('change', this.updateBox, this);
                        // Remove the box when the model gets removed from the graph.
                        this.model.on('remove', this.removeBox, this);

                        this.updateBox();

                        this.listenTo(this.model, 'process:ports', this.update);
                        joint.dia.ElementView.prototype.initialize.apply(this, arguments);
                    },
                    render: function () {
                        joint.dia.ElementView.prototype.render.apply(this, arguments);
                        this.paper.$el.prepend(this.$box);
                        // this.paper.$el.mousemove(this.onMouseMove.bind(this)), this.paper.$el.mouseup(this.onMouseUp.bind(this));
                        this.updateBox();
                        return this;
                    },
                    renderPorts: function () {
                        var $inPorts = this.$('.inPorts').empty();
                        var $outPorts = this.$('.outPorts').empty();

                        var portTemplate = _.template(this.model.portMarkup);

                        _.each(_.filter(this.model.ports, function (p) {
                            return p.type === 'in'
                        }), function (port, index) {

                            $inPorts.append(V(portTemplate({id: index, port: port})).node);
                        });
                        _.each(_.filter(this.model.ports, function (p) {
                            return p.type === 'out'
                        }), function (port, index) {

                            $outPorts.append(V(portTemplate({id: index, port: port})).node);
                        });
                    },
                    update: function () {

                        // First render ports so that `attrs` can be applied to those newly created DOM elements
                        // in `ElementView.prototype.update()`.
                        this.renderPorts();
                        joint.dia.ElementView.prototype.update.apply(this, arguments);
                    },
                    updateBox: function () {
                        // Set the position and dimension of the box so that it covers the JointJS element.
                        var bbox = this.model.getBBox();
                        // Example of updating the HTML with a data stored in the cell model.
                        // paper.on('blank:pointerdown', function(evt, x, y) { this.$box.find('textarea').toBack(); });
                        this.$box.find('span').text(this.model.get('textarea'));
                        this.model.on('cell:pointerclick', function (evt, x, y) {
                            this.$box.find('textarea').toFront();
                        });
                        this.$box.css({width: bbox.width, height: bbox.height, left: bbox.x, top: bbox.y, transform: 'rotate(' + (this.model.get('angle') || 0) + 'deg)'});
                    },
                    removeBox: function (evt) {
                        this.$box.remove();
                    }
                });


// Create JointJS elements and add them to the graph as usual.
// -----------------------------------------------------------

                var el1 = new joint.shapes.html.Element({
                    position: {x: 600, y: 250},
                    size: {width: 170, height: 100},
                    inPorts: ['in'],
                    outPorts: ['out'],
                    textarea: 'Start writing'
                });

                var el2 = new joint.shapes.html.Element({
                    position: {x: 600, y: 400},
                    size: {width: 170, height: 100},
                    inPorts: ['in'],
                    outPorts: ['out'],
                    textarea: 'Start writing'
                });

                graph.addCells([el1, el2]);

还可以根据文本区域内的文本缩放svg形状吗?

Also is it possible to scale the svg shape based on the text inside text area?

推荐答案

我假设您使用的是JointJS HTML教程(

I assume that you are using the CSS stylesheet from the JointJS HTML tutorial (http://jointjs.com/tutorial/html-elements).

请注意,.html-elementpointer-events设置为none.设置该属性后,所有事件都会传播到HTML元素下的(JointJS)SVG元素.因此,该文件知道与哪个元素进行了交互,例如可以开始拖动它.

Note that .html-element has pointer-events set to none. With that being set all events are propagated to the (JointJS) SVG Element under the HTML Element. The paper therefore knows what element was interacted with and e.g. can start dragging it.

.html-element {
   pointer-events: none;
}

我建议通过添加以下CSS规则为TextArea创建一个例外.

I suggest to create an exception for the TextArea by adding the following CSS rule.

.html-element textarea {
   pointer-events: all;
}

这篇关于svg形状的文本区域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆