1

我正在尝试构建一个应用程序,该应用程序将允许在其中绘制绘图、绘图内部、绘图等...到目前为止我所拥有的是 jsfiddle http://jsfiddle.net/viciouskinid/MYYRa/

$(function () {

ABC.Container = function () {
    var base = this;

}

/////////////////////////////////////////////////////////////////////////////

ABC.Canvas = function (containerID) {
    var base = this;

    var $container = $("#" + containerID);
    base.stage = new Kinetic.Stage({
        container: containerID,
        width: $container.width(),
        height: $container.height(),
        //draggable: true,
    });
    //$container.css('height','');

    base.ui = {
        stage: base.stage,
        scale: 1,
        zoomFactor: 1.1,
        origin: {
            x: 0,
            y: 0
        }
    };
    base.selectedElement=null;

    base.init = function () { 
        $(window).resize(base.resize);
        $(base.stage.content).on('mousewheel', base.zoom);


        base.childgroup = new Kinetic.Group(); 
        base.layer = new Kinetic.Layer();
        base.layer.add(base.childgroup);
        base.stage.add(base.layer);
    }

    base.resize = function(event) {
        base.stage.width = $container.width();
        base.stage.height = $container.height();
    }
    base.zoom = function(event) {
        event.preventDefault();
        var evt = event.originalEvent,
            mx = evt.clientX /* - canvas.offsetLeft */
            ,
            my = evt.clientY /* - canvas.offsetTop */
            ,
            wheel = evt.wheelDelta / 120; //n or -n
        var zoom = (base.ui.zoomFactor - (evt.wheelDelta < 0 ? 0.2 : 0));
        var newscale = base.ui.scale * zoom;
        base.ui.origin.x = mx / base.ui.scale + base.ui.origin.x - mx / newscale;
        base.ui.origin.y = my / base.ui.scale + base.ui.origin.y - my / newscale;

        base.ui.stage.setOffset(base.ui.origin.x, base.ui.origin.y);
        base.ui.stage.setScale(newscale);
        base.ui.stage.draw();

        base.ui.scale *= zoom;
    } 
    base.setSelectedElement = function(element) {
        if(base.selectedElement)
        {
            base.selectedElement.shape.setStroke('black'); 
        }
        base.selectedElement=element;
        base.selectedElement.shape.setStroke('red'); 
    }
    base.init();
}
ABC.Canvas.prototype = new ABC.Container();

/////////////////////////////////////////////////////////////////////////////


ABC.Element = function (x,y) {
    var base = this;         

    base.init = function () { 

        base.elements=[];
        base.shape = new Kinetic.Rect({
            x: 0,
            y: 0,
            width: 50,
            height: 50,
            //fill: 'green',
            stroke: 'black',
            strokeWidth: 1, 
        }); 
        base.shape.on('mouseover', base.shape_mouseover );
        base.shape.on('mouseout', base.shape_mouseout );

        base.childgroup = new Kinetic.Group(); 
        base.group = new Kinetic.Group({
            x: x,
            y: y,
            width: 50,
            height: 50,
            draggable: true, 
            layer: true,
        }); 
        //prevent even bubbling so downstream group is selected on drag not upstream group.
        base.group.on('mousedown', base.shape_mousedown );
        base.group.on('dragstart', base.group_dragstart );
        base.group.on('dragend', base.group_dragend );
        //element2.moveToTop();
        base.group.add(base.shape);
        base.group.add(base.childgroup);

        base.group.on('dblclick', base.newElement);
    } 

    ///////////////////////////////////////////////////

    base.shape_mouseover = function (e) { 
        e.cancelBubble = true; 
        //this.setStroke('blue'); 
        base.group.draw();
    }
    base.shape_mouseout = function (e) {
        e.cancelBubble = true;  
        //this.setStroke('black'); 
        base.group.draw();
    }
    base.shape_mousedown =  function(e) {
        canvas.setSelectedElement(base);
        e.cancelBubble = true; 
    }
    base.group_dragstart =  function(e) {
        //e.cancelBubble = true; 
    }
    base.group_dragend =  function(e) {
        //cannot select after drag
        ////
        //base.shape.moveDown();
    }
    base.dragBoundFunc =  function(p,e) { 

        var scale = base.getAbsoluteScale(base.group);

        //hold shif to allign with grid.
        if(e.shiftKey)
        { 
            var gridW=10;
            p.x = Math.round(p.x/gridW / scale.x)*gridW * scale.x;
            p.y = Math.round(p.y/gridW / scale.y)*gridW * scale.y;
        } 

        return base.fitToBound(p,scale,base.parent.shape);
    }
    base.newElement = function (e) { 
        e.cancelBubble = true; 

        // var pos=base.group.getAbsolutePosition();
        // var x=(e.x-pos.x)/canvas.ui.scale;
        // var y=(e.y-pos.y)/canvas.ui.scale;

        // var scale = base.getAbsoluteScale(base.group); 
        // var p = base.fitToBound({x:x,y:y},scale,base.shape);//not working for some reason.
        //writeMessage(messageLayer, 'x: ' + x + ', y: ' + y);
        var element = new ABC.Element(0,0);  

        base.addElement(element); 
                }
    base.addElement = function (element) { 
        base.elements.push(element);
        element.parent=base;

        element.group.setDragBoundFunc(element.dragBoundFunc);
        element.group.setScale(0.5);


            //fit to bounds
        element.fitElementToBound();/////////////////change to use dragboundsfunc
        base.childgroup.add(element.group); 
        canvas.setSelectedElement(element);
    } 
    base.fitToBound =  function(p,scale,shape) { 

        //Fit to bounds of parent shape.
        var boundpos=shape.getAbsolutePosition();  
        var boundsize=shape.getSize();  

        var x1=boundpos.x+boundsize.width*scale.x;
        var y1=boundpos.y+boundsize.height*scale.y;
        return {
            x: p.x<boundpos.x?boundpos.x:(p.x > x1 ? x1 :p.x),
            y: p.y<boundpos.y?boundpos.y:(p.y > y1 ? y1 :p.y)
        }
    }
    base.fitElementToBound =  function() { 

        var p1=base.group.getPosition();
        var scale = base.getAbsoluteScale(base.group);
        var p = base.fitToBound(p1,scale,base.parent.shape);
        base.group.setPosition( p.x, p.y);
    }
    base.getAbsoluteScale =  function(t) {  
        var scale = t.getScale();  
        if(t.parent)
        {
            var scale1 = base.getAbsoluteScale(t.parent);
            return {x:scale.x*scale1.x,y:scale.y*scale1.y};
        }
        return scale;
    }



    base.init();
}
ABC.Element.prototype  = new ABC.Container();

/////////////////////////////////////////////////////////////////////////////

  var messageLayer = new Kinetic.Layer();
  function writeMessage(messageLayer, message) {
    var context = messageLayer.getContext();
    messageLayer.clear();
    context.font = '18pt Calibri';
    context.fillStyle = 'black';
    context.fillText(message, 10, 25);
  } 

var canvas = new ABC.Canvas('container');


var element01 = new ABC.Element(0,0);  
canvas.childgroup.add(element01.group);


var element0 = new ABC.Element(10,20);

element01.addElement(element0);


var element1 = new ABC.Element(20,30);  
element0.addElement(element1);


var element2 = new ABC.Element(40,50);  
element1.addElement(element2);

canvas.stage.draw();


  canvas.stage.add(messageLayer);


});

我首先遇到两个问题,如果您双击一个框,它将在该框内创建另一个较小的框。唯一的问题是,当它被创建时,我无法让它在盒子中正确定位。如果您在创建后找到该框(鼠标滚轮缩小)并尝试拖动它,那么它将重新回到父框。如果它会在创建新框之前检查新框是否在父框中,如果没有则移动它,那就太好了。

第二个问题是当您创建一个新的子框(双击一个框)并在父框中创建两个子框时。如果您拖动新的子框然后选择另一个子框,您将无法再次选择新的子框(它只会选择父框)。这种情况总是会发生,但如果你玩弄它,它应该会发生在你身上。我该如何防止这种情况。

谢谢。


越来越近,第一个问题几乎解决了。在启动时添加新框之前和双击时会移动一个新框。唯一的问题是如果您移动主块然后双击它不在正确的位置。

在第二个问题上仍然没有运气。

http://jsfiddle.net/viciouskinid/MYYRa/6/

4

1 回答 1

0

好的解决了。

http://jsfiddle.net/viciouskinid/MYYRa/9/

    var ABC = {};

    /////////////////////////////////////////////////////////////////////////////

    $(function () {

        ABC.Container = function () {
            var base = this;

        }

        /////////////////////////////////////////////////////////////////////////////

        ABC.Canvas = function (containerID) {
            var base = this;

            var $container = $("#" + containerID);
            base.stage = new Kinetic.Stage({
                container: containerID,
                width: $container.width(),
                height: $container.height(),
                //draggable: true,
            });
            //$container.css('height','');

            base.ui = {
                stage: base.stage,
                scale: 1,
                zoomFactor: 1.1,
                origin: {
                    x: 0,
                    y: 0
                }
            };
            base.selectedElement = null;

            base.init = function () {
                $(window).resize(base.resize);
                $(base.stage.content).on('mousewheel', base.zoom);


                base.childgroup = new Kinetic.Group();
                base.layer = new Kinetic.Layer();
                base.layer.add(base.childgroup);
                base.stage.add(base.layer);
            }

            base.resize = function (event) {
                base.stage.width = $container.width();
                base.stage.height = $container.height();
            }
            base.zoom = function (event) {
                event.preventDefault();
                var evt = event.originalEvent,
                    mx = evt.clientX /* - canvas.offsetLeft */
                    ,
                    my = evt.clientY /* - canvas.offsetTop */
                    ,
                    wheel = evt.wheelDelta / 120; //n or -n
                var zoom = (base.ui.zoomFactor - (evt.wheelDelta < 0 ? 0.2 : 0));
                var newscale = base.ui.scale * zoom;
                base.ui.origin.x = mx / base.ui.scale + base.ui.origin.x - mx / newscale;
                base.ui.origin.y = my / base.ui.scale + base.ui.origin.y - my / newscale;

                base.ui.stage.setOffset(base.ui.origin.x, base.ui.origin.y);
                base.ui.stage.setScale(newscale);
                base.ui.stage.draw();

                base.ui.scale *= zoom;
            }
            base.setSelectedElement = function (element) {
                if (base.selectedElement) {
                    base.selectedElement.shape.setStroke('black');
                }
                base.selectedElement = element;
                base.selectedElement.shape.setStroke('red');
            }
            base.init();
        }
        ABC.Canvas.prototype = new ABC.Container();

        /////////////////////////////////////////////////////////////////////////////


        ABC.Element = function (x, y) {
            var base = this;

            base.init = function () {

                base.elements = [];
                base.shape = new Kinetic.Rect({
                    x: 0,
                    y: 0,
                    width: 50,
                    height: 50,
                    //fill: 'green',
                    stroke: 'black',
                    strokeWidth: 1,
                });
                base.shape.on('mouseover', base.shape_mouseover);
                base.shape.on('mouseout', base.shape_mouseout);

                base.childgroup = new Kinetic.Group();
                base.group = new Kinetic.Group({
                    x: x,
                    y: y,
                    width: 50,
                    height: 50,
                    draggable: true,
                    layer: true,
                });
                //prevent even bubbling so downstream group is selected on drag not upstream group.
                base.group.on('mousedown', base.shape_mousedown);
                base.group.on('dragstart', base.group_dragstart);
                base.group.on('dragend', base.group_dragend);
                //element2.moveToTop();
                base.group.add(base.shape);
                base.group.add(base.childgroup);

                base.group.on('dblclick', base.newElement);
            }

            ///////////////////////////////////////////////////

            base.shape_mouseover = function (e) {
                e.cancelBubble = true;
                //this.setStroke('blue'); 
                base.group.draw();
            }
            base.shape_mouseout = function (e) {
                e.cancelBubble = true;
                //this.setStroke('black'); 
                base.group.draw();
            }
            base.shape_mousedown = function (e) {
                canvas.setSelectedElement(base);
                e.cancelBubble = true;
            }
            base.group_dragstart = function (e) {
                //e.cancelBubble = true; 
            }
            base.group_dragend = function (e) {
                //cannot select after drag
                ////
                //base.shape.moveDown();
            }
            base.dragBoundFunc = function (p, e) {

                var scale = base.getAbsoluteScale(base.group);

                //hold shif to allign with grid.
                if (e.shiftKey) {
                    var gridW = 10;
                    p.x = Math.round(p.x / gridW / scale.x) * gridW * scale.x;
                    p.y = Math.round(p.y / gridW / scale.y) * gridW * scale.y;
                }

                return base.fitToBound(p, scale, base.parent.shape);
            }
            base.newElement = function (e) {
                e.cancelBubble = true;

                var pos = base.group.getAbsolutePosition();
                var x = (e.x - pos.x) / canvas.ui.scale;
                var y = (e.y - pos.y) / canvas.ui.scale;
                // var scale = base.getAbsoluteScale(base.group); 
                // var p = base.fitToBound({x:x,y:y},scale,base.shape);//not working for some reason.
                //writeMessage(messageLayer, 'x: ' + x + ', y: ' + y);
                var element = new ABC.Element(x, y);

                base.addElement(element);
            }
            base.addElement = function (element) {
                base.elements.push(element);
                element.parent = base;

                element.group.setDragBoundFunc(element.dragBoundFunc);
                element.group.setScale(0.5);


                //fit to bounds
                element.fitElementToBound(); /////////////////change to use dragboundsfunc
                base.childgroup.add(element.group);
                canvas.setSelectedElement(element);
            }
            base.fitToBound = function (p, scale, shape) {

                //Fit to bounds of parent shape.
                var boundpos = shape.getAbsolutePosition();
                var boundsize = shape.getSize();

                var x1 = boundpos.x + boundsize.width * scale.x;
                var y1 = boundpos.y + boundsize.height * scale.y;
                return {
                    x: p.x < boundpos.x ? boundpos.x : (p.x > x1 ? x1 : p.x),
                    y: p.y < boundpos.y ? boundpos.y : (p.y > y1 ? y1 : p.y)
                }
            }
            base.fitToBound2 = function (p, shape) {

                var scale = base.getAbsoluteScale(base.group);
                var scale1 = base.getAbsoluteScale(shape);
                var p = base.group.getPosition();
                var size = base.group.getSize();

                //Fit to bounds of parent shape.
                var boundpos = shape.getAbsolutePosition();
                var boundsize = shape.getSize();

                var x1 = boundpos.x + (boundsize.width) * scale1.x - size.width * scale.x;
                var y1 = boundpos.y + (boundsize.height) * scale1.y - size.height * scale.y;

                //alert((boundsize.width )*scale1.x +" "+ size.width*scale.x);
                //alert(scale.x +" "+ scale1.x);
                //alert(boundsize.height +" "+ size.height);
                return {
                    x: p.x < boundpos.x ? boundpos.x : (p.x > x1 ? x1 : p.x),
                    y: p.y < boundpos.y ? boundpos.y : (p.y > y1 ? y1 : p.y)
                }
            }
            base.fitElementToBound = function () {

                var p1 = base.fitToBound2(p1, base.parent.shape);

                base.group.setPosition(p1.x, p1.y);
            }
            base.getAbsoluteScale = function (t) {
                var scale = t.getScale();
                if (t.parent) {
                    var scale1 = base.getAbsoluteScale(t.parent);
                    return {
                        x: scale.x * scale1.x,
                        y: scale.y * scale1.y
                    };
                }
                return scale;
            }



            base.init();
        }
        ABC.Element.prototype = new ABC.Container();

        /////////////////////////////////////////////////////////////////////////////

        var messageLayer = new Kinetic.Layer();

        function writeMessage(messageLayer, message) {
            var context = messageLayer.getContext();
            messageLayer.clear();
            context.font = '18pt Calibri';
            context.fillStyle = 'black';
            context.fillText(message, 10, 25);
        }

        var canvas = new ABC.Canvas('container');


        var element01 = new ABC.Element(0, 0);
        canvas.childgroup.add(element01.group);


        var element0 = new ABC.Element(100, 200);

        element01.addElement(element0);


        var element1 = new ABC.Element(200, 300);
        element0.addElement(element1);


        var element2 = new ABC.Element(400, 800);
        element1.addElement(element2);

        canvas.stage.draw();


        canvas.stage.add(messageLayer);


    });
于 2013-03-04T09:02:37.960 回答