我正在尝试构建一个应用程序,允许绘制一个绘图,一个绘图,一个绘图等...到目前为止我所拥有的是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);
});
我首先遇到两个问题,如果你双击一个盒子,它会在那个盒子里创建另一个小盒子。唯一的问题是我不能让它在创建时正确地定位在框中。如果您在创建框后找到该框(鼠标滚轮缩小)并尝试拖动它,则它会快速回到父框中。如果它会在创建之前检查新框是否在父框中,如果没有则移动它将会很棒。
第二个问题是当你创建一个新的子框(双击一个框)并在父框中创建两个子框。如果您拖动新的子框,然后选择另一个子框,您将无法再次选择新的子框(它将只选择父框)。这种剂量总会发生,但如果你玩它就应该发生在你身上。如何防止这种情况。
感谢。
第二个问题仍然没有运气。
答案 0 :(得分: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);
});