1. #1
    Sencha Premium Member vadimv's Avatar
    Join Date
    Sep 2010
    Location
    Chisinau, Moldova
    Posts
    642
    Vote Rating
    25
    vadimv will become famous soon enough vadimv will become famous soon enough

      1  

    Default Ext.ux.DrawPoly

    Ext.ux.DrawPoly


    An extension of "Ext.draw.Component" which shows how to draw polygons. It's just an quick made example which probably needs some optimizations, but I thought that is ok for demonstrating ExtJS's draw capabilities and especially polygons as are the most wanted by many users. I used also Raphael(2.1.0) for some utils methods wich ExtJS doesn't have.
    Extension's features:
    - draw polygons
    - polys resize
    - polys selecting and deselecting
    - add new vertices, just by clicking on edges
    - remove vertices, just by overlapping neighboring vertices
    - cancel drawing by right clicking

    Code:
      <html><head>
        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
        <title>Draw test</title>
        <link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />
    
    
        <script type="text/javascript" src="../../ext-all-debug.js"></script>
        <script type="text/javascript" src="test.js"></script>
        <script type="text/javascript" src="raphael-min.js"></script>
    
    
    </head>
    <body>
    </body>
    </html>
    test.js :
    Code:
    Ext.onReady(function() {
        Ext.namespace('Ext', 'Ext.ux');
        Ext.namespace('Draw', 'Draw.util');
    
    
    Draw.util = {
        pathToCoords: function(path){
            var coords = Ext.isArray(path) ? path.toString(): path;
     
            coords = '(' + coords.substr(1,coords.length-2)+ ')';
            coords = coords.replace(/L+/g,'),(');
    
            return coords;
        },
        coordsToPath: function(coords){
            var path = coords;
    
            path = 'M' + path.substr(2,path.length-4)+ 'Z';
            path = path.replace(/\),\(/g,'L');
    
            return path;
        },
        getMouseEvButton: function(e){
            var evt = (e==null ? event:e),
                clickType = 'LEFT';
    
             if (evt.which) { 
              if (evt.which==3) clickType='RIGHT';
              else if (evt.which==2) clickType='MIDDLE';
             }
             else if (evt.button) {
              if (evt.button==2) clickType='RIGHT';
              else if (evt.button==4) clickType='MIDDLE';
             }
            return clickType;
        }
    }
    
    
    
    Ext.define('Ext.ux.DrawPoly', {
        extend: 'Ext.draw.Component',
    
        closeMarge: 15,
        currentMode: 'addsprite',
        style: {
            //'opacity' : '0.7',
            'position': 'absolute',
            'z-index' : 0
        },
    
    
        initComponent: function(){
            var me = this;
            
            me.on({
                click : me.onMouseClick,
                mouseup: me.onDragStop,
                mousedown: me.onDragStart,
                afterrender: me.onAfterRender
            });
        },
        onAfterRender : function(){
            var me = this,
                delegate = 'circle';
    
            // Fix for IE8's VML
            if(Ext.isIE8) 
                delegate = 'shape';
    
            me.mon(me.getEl(), {
                click : {
                    fn : me.onVertexMouseClick,
                    delegate: delegate
                },
                contextmenu : {
                    fn: me.onContextMenu,
                    preventDefault: true
                },
                scope: me
            });
        },
        onMouseMove : function(e){
            var me = this;
            
            if(me.currentMode == 'edit'){
                me.edit(e);
             }else
             if(me.currentMode == 'drag'){
                me.drag(e);
             }
        },
        onDragStop : function(e){
            var me = this;
    
            if(me.currentMode == 'drag'){
                me.currentMode = 'selected';
                // Apply translations to path coordinates
                me.selected.setAttributes({
                    translate: {x:0,y:0},
                    path: me.applyPathTrans(me.selected)
                },true);
    
    
                // Apply translations to sprites from vertices group
                var items = me.surface.getGroup('vertices').items;
                for (var i = 0, length = items.length; i < length; i++) {
                    var item = items[i];
                    if(item.type == 'circle'){
                         item.setAttributes({
                            x: item.attr.x + item.attr.translation.x, 
                            y : item.attr.y + item.attr.translation.y,
                            translate: {x:0,y:0}
                        },true);
                    }
                };
                me.fireEvent('positionchange',me.selected);
            }
        },
        onDragStart : function(e){
            var me = this,
                xy = e.getXY(),
                position = me.getMousePosition(e),
                button = Draw.util.getMouseEvButton(e),
                item = me.surface.items.get(e.target.id);
    
                e.preventDefault();
    
            if(button == 'LEFT'){
                // If there's a poly selected and mousedown wasn't on draw surface 
                // then check for new vertex and prepare dragging start
                if(me.currentMode == 'selected' && item && me.selected.id == item.id) {
                    me.isNewVertex(me.selected,new Array(position.x,position.y)); 
                    me.prev = me.surface.transformToViewBox(xy[0],xy[1]);
                    me.currentMode = 'drag'; 
                }
                if(!me.hasListener('mousemove'))
                    me.on('mousemove',me.onMouseMove);
            }
        },
        onContextMenu: function(e){
            var me = this,
                item = me.surface.items.get(e.target.id);
    
            if(me.currentMode == 'edit'){
                 me.cancelEdit();
            }else
            // if right click was on a poly then show context menu for it
            if(item){
                me.currentMode = 'select';
                me.onMouseClick(e);
                me.fireEvent('polymapctxmenu',e.getXY());
            }
        },
        cancelEdit : function(){
            var me = this;
    
            if(me.currentMode == 'edit'){
                me.selected.destroy();
                me.selected = null;
                me.currentMode = 'addsprite';
            }  
        },
        onMouseClick: function(e){
            var me = this,
                position = me.getMousePosition(e),
                targetEl = Ext.get(e.target),
                targetItem = me.surface.items.get(targetEl.id);
    
           // If mousedown on path and is not editing mode then select that path
            if(targetItem && targetItem.type == 'path' && me.currentMode != 'edit')
                me.currentMode = 'select';
    
            switch(me.currentMode){
                case 'addsprite' : {
                    if(me.selected == null ) {
                        poly = Ext.create('Ext.draw.Sprite',{
                            type: 'path',
                            path: 'M1,1',
                            fill: '#7ff482',
                            "stroke-width": 3,
                            opacity: 1,
                            stroke: '#000000'                  
                        });
                        me.surface.add(poly).show();
                    }
                    poly.path = 'M'+position.x.toString() + ',' + position.y.toString();
                    poly.setAttributes({path: poly.path},true);
    
    
                    me.currentMode = 'edit';
                    me.selected = poly;
                } break;
    
    
                case 'edit' : {
                        var selected = me.selected,
                            segments = Raphael.parsePathString(selected.attr.path);
                        // If last point is first point then close the path
                        if(Math.abs(position.x - segments[0][1]) < me.closeMarge && Math.abs(position.y - segments[0][2]) < me.closeMarge){
                            
                            // if it's at least a triangle, then close it.
                            if(segments.length > 3) {
                                selected.path += 'Z';
                                selected.setAttributes({path: selected.path},true);
                                me.currentMode = 'selected';
                                me.selectSprite(selected);
    
    
                                me.fireEvent('create',selected);
                            }
                        } else
                            selected.path = selected.attr.path;
                } break;
                
                case 'selected' : {
                    // Deselect if was selected
                    var source = targetEl.dom.nodeName;
    
    
                    if(source != 'circle' && source != 'shape') {
                        me.deselect();
                    }
                } break;
    
    
                case 'select' : {
                        // Select sprite if was clicked
                        if(me.selected && me.selected.id != targetEl.id){
                            me.deselect();
                            me.selectSprite(targetItem);
                        }else
                        if(me.selected == null){
                            me.selectSprite(targetItem);
                        }
                        me.currentMode = 'selected';
                } break;
            }
        },
        onVertexMouseClick: function(e){
            var me = this,
                el = Ext.get(e.target),
                item = me.surface.items.get(el.id); 
            
            //Fix for IE8
            if(Ext.isIE8 && item.type != 'circle'){
                return;
            }
    
    
            if (me.currentMode == 'selected') {
                me.currentMode = 'reshape';
                me.reshapeTargetId = el.id;
                me.on('mousemove',me.onVertexMouseMove,me);    
            }else
            if(me.currentMode == 'reshape'){
                me.currentMode = 'selected';
                me.reshapeTargetId = null;
                me.un('mousemove',me.onVertexMouseMove,me);   
                //check if is needed to remove vertex  
                me.isRemoveVertex(item); 
                me.fireEvent('positionchange',me.selected);
            }
        },
        onVertexMouseMove: function(e){
            var me = this,
                vertex = me.surface.items.get(this.reshapeTargetId),
                poly = me.selected,
                position = me.getMousePosition(e);
    
    
            var segments = Raphael.parsePathString(poly.attr.path);
                segments[vertex.vertexIndex][1] = position.x;
                segments[vertex.vertexIndex][2] = position.y;
    
    
            poly.setAttributes({path: segments},true);
            vertex.setAttributes({x: position.x, y : position.y},true);
        },
        drag: function(e){
            var xy = e.getXY(),
                me = this,
                sprite = me.selected,
                attr = sprite.attr, dx, dy,
                vertices = me.surface.getGroup('vertices');
    
    
            xy = me.surface.transformToViewBox(xy[0], xy[1]);
            dx = xy[0] - me.prev[0];
            dy = xy[1] - me.prev[1];
    
    
            if(vertices){
                vertices.setAttributes({
                    translate: {
                        x: attr.translation.x + dx,
                        y: attr.translation.y + dy
                    }
                }, true);
            }
            me.prev = xy;
        },
        edit: function(e){
            var me = this,
                position = me.getMousePosition(e);
            me.selected.setAttributes({path: me.selected.path + 'L' + position.x +',' + position.y },true);
        },
        getMousePosition : function(e){
            var evt = e.browserEvent,
                x = evt.offsetX || evt.layerX,
                y = evt.offsetY || evt.layerY;
    
    
                if(Ext.isIE8){
                    var box = Ext.get(e.target.parentElement).getBox(),
                        xy = e.getXY();
                    x= xy[0] - box.x;
                    y= xy[1] - box.y;
                }
            return {x:x, y:y};
        },
        selectSprite: function(poly){
            var me = this,
                segments = Raphael.parsePathString(poly.attr.path),
                parentEl =poly.el.parent();
    
    
            // Adjust z-index by replacing poly's element to be the last one in the parent
            if(Ext.isIE8){
                poly.setStyle('z-index',10);
            }else
            if(poly.id != parentEl.last().id){
                me.surface.remove(poly,false);
                me.surface.add(poly);
                poly.show(true);
            }
    
    
            for (var i = 0, length = segments.length-1; i < length; i++) {
                me.createVertex({
                    x: segments[i][1],
                    y: segments[i][2],
                    translation : poly.attr.translation,
                    vertexIndex: i
                });
            };
            me.surface.getGroup('vertices').add(poly);
            me.selected = poly;
            me.fireEvent('select',me.selected);
        },
        deselect: function(){
            var me = this;
    
            if(Ext.isIE8){
                me.selected.setStyle('z-index','0');
            }
            var group = me.surface.getGroup('vertices')
            group.remove(me.selected);
            group.destroy();
            me.selected = null;
            me.currentMode = 'addsprite';
            me.fireEvent('deselect');
        },
        createVertex: function(cfg){
            var configs = {
                type: 'circle',
                fill: '#0FF',
                stroke: '#00F',
                'stroke-width': 3,
                radius:6,
                group: 'vertices',
                style: {
                    'z-index':11
                }
            };
            Ext.apply(configs,cfg);
            var vertex = Ext.create('Ext.draw.Sprite',configs);
            this.surface.add(vertex).show(true);
            return vertex;
        },
        applyPathTrans: function(pathSprite){
            var segments = Raphael.parsePathString(pathSprite.attr.path),
                tx = pathSprite.attr.translation.x,
                ty = pathSprite.attr.translation.y;
    
          for (var i = 0, length = segments.length-1; i < length; i++){
                segments[i][1] +=  tx;
                segments[i][2] +=  ty;     
            };
            return segments;
        },
        isNewVertex: function(pathSprite, xy){
            var me = this,
                segments = Raphael.parsePathString(pathSprite.attr.path),
                j,i = 0,
                length = segments.length-1,
                shortlength = length -1;
    
            function distance(x1,y1,x2,y2){
                return Math.sqrt(Math.pow(Math.abs(x1-x2),2) + Math.pow(Math.abs(y1-y2),2));
            }
    
            for (; i < length; i++) {
                i == shortlength ? j = 0 : j = i+1;
    
                var d = distance(segments[i][1], segments[i][2], segments[j][1], segments[j][2]),
                    d1 = distance(segments[i][1], segments[i][2], xy[0], xy[1]),
                    d2 = distance(xy[0], xy[1], segments[j][1], segments[j][2]);
    
                if(Math.abs(d- (d1+d2)) < 0.2 && d1 > 20 && d2 > 20){
                    var insertIndex = i+1;
                    Ext.Array.insert(segments,insertIndex,[['L',xy[0],xy[1]]]);
    
                    me.shiftVertices(insertIndex);
                    me.createVertex({
                        x: xy[0],
                        y: xy[1],
                        vertexIndex: insertIndex
                    });
                    pathSprite.setAttributes({path: segments},true);
                    break;
                }
            };
        },
        isRemoveVertex: function(vertex){
            var me = this,
                segments = Raphael.parsePathString(me.selected.attr.path),
                isOverlapped = -1,
                x = vertex.attr.x,
                y = vertex.attr.y;
    
            //if is at least triangle
            if(segments.length > 4) {
                if(vertex.vertexIndex == 0) {
                    // Check with last
                    if(Math.abs(segments[segments.length-1][1] - x) < 4 &&
                        Math.abs(segments[segments.length-1][2] - y) < 4)
                        isOverlapped = segments.length-1;
                    // Check with first
                    if(Math.abs(segments[1][1] - x) < 4 &&
                        Math.abs(segments[1][2] - y) < 4)
                        isOverlapped = 1;
                }
                else
                if(vertex.vertexIndex == segments.length-2){
                    // Check with -1
                    if(Math.abs(segments[vertex.vertexIndex-1][1] - x) < 4 &&
                        Math.abs(segments[vertex.vertexIndex-1][2] - y) < 4)
                        isOverlapped = vertex.vertexIndex-1;
                    //Check with first
                    if(Math.abs(segments[0][1] - x) < 4 &&
                        Math.abs(segments[0][2] - y) < 4)
                        isOverlapped = 0;
                }else{
                    //Check with +1
                    if(Math.abs(segments[vertex.vertexIndex+1][1] - x) < 4 &&
                        Math.abs(segments[vertex.vertexIndex+1][2] - y) < 4)
                        isOverlapped = vertex.vertexIndex+1;
                    //Check with -1
                    if(Math.abs(segments[vertex.vertexIndex-1][1] - x) < 4 &&
                        Math.abs(segments[vertex.vertexIndex-1][2] - y) < 4)
                        isOverlapped = vertex.vertexIndex-1;
                }
                    
                if(isOverlapped != -1){
                    if(vertex.vertexIndex == 0)
                        segments[1][0] = 'M';
                    Ext.Array.erase(segments,vertex.vertexIndex,1);
                    me.unshiftVertices(vertex.vertexIndex);
                    me.surface.items.remove(vertex); 
                    vertex.destroy();
                    me.selected.setAttributes({path: segments},true);
                }
            }
        },
        shiftVertices: function(index){
            var group = this.surface.getGroup('vertices');
            for (var i = 0; i < group.length; i++) {
                var item = group.items[i];
                if(item.type == 'circle' && item.vertexIndex >= index){
                    item.vertexIndex++;
                }
            };
        },
        unshiftVertices: function(index){
            var group = this.surface.getGroup('vertices');
            for (var i = 0; i < group.length; i++) {
                var item = group.items[i];
                if(item.type == 'circle' && item.vertexIndex > index){
                    item.vertexIndex--;
                }
            };
        },
        drawPoly: function(cfg){
            var me = this,
                config = {
                    type: 'path',
                    fill: '#7ff482',
                    "stroke-width": 3,
                    opacity: 1,
                    stroke: '#000000'  
                };
    
            Ext.apply(config,cfg)
    
            var poly = Ext.create('Ext.draw.Sprite',config);
            me.surface.add(poly).show(true);
            return poly;
        }
        });
    
        Ext.create('Ext.window.Window', {
            width: 600,
            height: 400,
            hidden: false,
            border: false,
            title: 'Draw Components',
            maximizable: true,
            layout: 'fit',
            items: [{
                xtype: 'tabpanel',
                defaults: {
                    padding: '0 0 0 0'
                },
                activeItem: 0,
                items: [{
                    xtype: 'panel',
                    title: 'Draw test',
                    layout: 'fit',
                    items: [ Ext.create('Ext.ux.DrawPoly')]
                }]
            }],
            resizable: {
                dynamic: true
            }
        }).show();
    });
    Attached Images

  2. #2
    Sencha - Support Team scottmartin's Avatar
    Join Date
    Jul 2010
    Location
    Houston, Tx
    Posts
    8,912
    Vote Rating
    443
    scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future

      0  

    Default


    Cool.. thanks for sharing.

    Scott.

  3. #3
    Sencha User
    Join Date
    Dec 2012
    Posts
    2
    Vote Rating
    0
    deepaganu123 is on a distinguished road

      0  

    Default can i get the entire code

    can i get the entire code


    Can I please get the entire code , Rapheal.js is not provided , I want to recreate this scenario on my own system

  4. #4
    Sencha Premium Member vadimv's Avatar
    Join Date
    Sep 2010
    Location
    Chisinau, Moldova
    Posts
    642
    Vote Rating
    25
    vadimv will become famous soon enough vadimv will become famous soon enough

      0  

    Default


    you have it, you can get raphael on related site.

  5. #5
    Sencha User
    Join Date
    Jan 2012
    Posts
    1
    Vote Rating
    0
    andre.foxsystems is on a distinguished road

      0  

    Default nice

    nice


    very nice work! thanks!

Turkiyenin en sevilen filmlerinin yer aldigi xnxx internet sitemiz olan ve porn sex tarzi bir site olan mobil porno izle sitemiz gercekten dillere destan bir durumda herkesin sevdigi bir site olarak tarihe gececege benziyor. Sitenin en belirgin ozelliklerinden birisi de Turkiyede gercekten kaliteli ve muntazam, duzenli porno izle siteleri olmamasidir. Bu yuzden iste. Ayrica en net goruntu kalitesine sahip adresinde yayinlanmaktadir. Mesela diğer sitelerimizden bahsedecek olursak, en iyi hd porno video arşivine sahip bir siteyiz. "The Best anal porn videos and slut anus, big asses movies set..." hd porno faketaxi