1

内に描画、内に描画、ドローインなどを描画できるアプリケーションを構築しようとしています...これまでのところjsfiddlehttp : //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);


});

最初に2つの問題があります。ボックスをダブルクリックすると、そのボックス内に別の小さなボックスが作成されます。唯一の問題は、作成時にボックスを正しく配置できないことです。作成されたボックスを見つけて(マウスホイールでズームアウト)、ドラッグしようとすると、親ボックスにスナップバックします。新しいボックスが作成される前に親ボックスにあるかどうかをチェックし、そうでない場合は移動するとよいでしょう。

2番目の問題は、新しい子ボックスを作成し(ボックスをダブルクリック)、親ボックスに2つの子ボックスを作成する場合です。新しい子ボックスをドラッグしてから他の子ボックスを選択すると、新しい子ボックスを再度選択することはできなくなります(親ボックスが選択されるだけです)。このdosentは常に発生しますが、それをいじってみると、それはあなたのために発生するはずです。これを防ぐ方法。

ありがとう。


近づくと、最初の問題はほぼ解決されます。新しいボックスは、起動時およびダブルクリック時に追加される前に移動されます。唯一の問題は、メインブロックを移動してからダブルクリックすると、正しい場所に配置されないことです。

2番目の問題についてはまだ運がありません。

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 に答える