我正在尝试构建一个应用程序,该应用程序将允许在其中绘制绘图、绘图内部、绘图等...到目前为止我所拥有的是 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);
});
我首先遇到两个问题,如果您双击一个框,它将在该框内创建另一个较小的框。唯一的问题是,当它被创建时,我无法让它在盒子中正确定位。如果您在创建后找到该框(鼠标滚轮缩小)并尝试拖动它,那么它将重新回到父框。如果它会在创建新框之前检查新框是否在父框中,如果没有则移动它,那就太好了。
第二个问题是当您创建一个新的子框(双击一个框)并在父框中创建两个子框时。如果您拖动新的子框然后选择另一个子框,您将无法再次选择新的子框(它只会选择父框)。这种情况总是会发生,但如果你玩弄它,它应该会发生在你身上。我该如何防止这种情况。
谢谢。
越来越近,第一个问题几乎解决了。在启动时添加新框之前和双击时会移动一个新框。唯一的问题是如果您移动主块然后双击它不在正确的位置。
在第二个问题上仍然没有运气。