我目前正在开发一个带有javascript和html画布的网站构建器。我现在很困惑我的下一步将是什么。我完成了拖放,调整大小功能。但是当我在某个表单上放置一个元素时,我希望它生成一个代码(非常类似于visual basic IDE的工作原理)。如何让元素生成代码?
的index.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>DnD initial</title>
<script type="text/javascript" src="shapes.js"></script>
</head>
<body onload="init()">
<div id="container">
<canvas id="canvas1" width="500" height="500" style="border: 1px solid #95a5a6;">
This text is displayed if your browser does not support HTML5 Canvas.
</canvas>
</div>
</body></html>
shapes.js
function Shape(state, x, y, w, h, fill) {
"use strict";
this.state = state;
this.x = x || 0;
this.y = y || 0;
this.w = w || 1;
this.h = h || 1;
this.fill = fill || '#AAAAAA';
}
// Draws this shape to a given context
Shape.prototype.draw = function(ctx, optionalColor) {
"use strict";
var i, cur, half;
ctx.fillStyle = this.fill;
ctx.fillRect(this.x, this.y, this.w, this.h);
if (this.state.selection === this) {
ctx.strokeStyle = this.state.selectionColor;
ctx.lineWidth = this.state.selectionWidth;
ctx.strokeRect(this.x,this.y,this.w,this.h);
half = this.state.selectionBoxSize / 2;
this.state.selectionHandles[0].x = this.x-half;
this.state.selectionHandles[0].y = this.y-half;
this.state.selectionHandles[1].x = this.x+this.w/2-half;
this.state.selectionHandles[1].y = this.y-half;
this.state.selectionHandles[2].x = this.x+this.w-half;
this.state.selectionHandles[2].y = this.y-half;
this.state.selectionHandles[3].x = this.x-half;
this.state.selectionHandles[3].y = this.y+this.h/2-half;
this.state.selectionHandles[4].x = this.x+this.w-half;
this.state.selectionHandles[4].y = this.y+this.h/2-half;
this.state.selectionHandles[6].x = this.x+this.w/2-half;
this.state.selectionHandles[6].y = this.y+this.h-half;
this.state.selectionHandles[5].x = this.x-half;
this.state.selectionHandles[5].y = this.y+this.h-half;
this.state.selectionHandles[7].x = this.x+this.w-half;
this.state.selectionHandles[7].y = this.y+this.h-half;
ctx.fillStyle = this.state.selectionBoxColor;
for (i = 0; i < 8; i += 1) {
cur = this.state.selectionHandles[i];
ctx.fillRect(cur.x, cur.y, this.state.selectionBoxSize, this.state.selectionBoxSize);
}
}
};
Shape.prototype.contains = function(mx, my) {
"use strict";
return (this.x <= mx) && (this.x + this.w >= mx) &&
(this.y <= my) && (this.y + this.h >= my);
};
function CanvasState(canvas) {
"use strict";
this.canvas = canvas;
this.width = canvas.width;
this.height = canvas.height;
this.ctx = canvas.getContext('2d');
var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop,
html, myState, i;
if (document.defaultView && document.defaultView.getComputedStyle) {
this.stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(canvas, null).paddingLeft, 10) || 0;
this.stylePaddingTop = parseInt(document.defaultView.getComputedStyle(canvas, null).paddingTop, 10) || 0;
this.styleBorderLeft = parseInt(document.defaultView.getComputedStyle(canvas, null).borderLeftWidth, 10) || 0;
this.styleBorderTop = parseInt(document.defaultView.getComputedStyle(canvas, null).borderTopWidth, 10) || 0;
}
html = document.body.parentNode;
this.htmlTop = html.offsetTop;
this.htmlLeft = html.offsetLeft;
this.valid = false;
this.shapes = [];
this.dragging = false;
this.resizeDragging = false;
this.expectResize = -1;
this.selection = null;
this.dragoffx = 0;
this.dragoffy = 0;
this.selectionHandles = [];
for (i = 0; i < 8; i += 1) {
this.selectionHandles.push(new Shape(this));
}
myState = this;
canvas.addEventListener('selectstart', function(e) { e.preventDefault(); return false; }, false);
canvas.addEventListener('mousedown', function(e) {
var mouse, mx, my, shapes, l, i, mySel;
if (myState.expectResize !== -1) {
myState.resizeDragging = true;
return;
}
mouse = myState.getMouse(e);
mx = mouse.x;
my = mouse.y;
shapes = myState.shapes;
l = shapes.length;
for (i = l-1; i >= 0; i -= 1) {
if (shapes[i].contains(mx, my)) {
mySel = shapes[i];
myState.dragoffx = mx - mySel.x;
myState.dragoffy = my - mySel.y;
myState.dragging = true;
myState.selection = mySel;
myState.valid = false;
return;
}
}
if (myState.selection) {
myState.selection = null;
myState.valid = false;
}
}, true);
canvas.addEventListener('mousemove', function(e) {
var mouse = myState.getMouse(e),
mx = mouse.x,
my = mouse.y,
oldx, oldy, i, cur;
if (myState.dragging){
mouse = myState.getMouse(e);
myState.selection.x = mouse.x - myState.dragoffx;
myState.selection.y = mouse.y - myState.dragoffy;
myState.valid = false;
} else if (myState.resizeDragging) {
oldx = myState.selection.x;
oldy = myState.selection.y;
// 0 1 2
// 3 4
// 5 6 7
switch (myState.expectResize) {
case 0:
myState.selection.x = mx;
myState.selection.y = my;
myState.selection.w += oldx - mx;
myState.selection.h += oldy - my;
break;
case 1:
myState.selection.y = my;
myState.selection.h += oldy - my;
break;
case 2:
myState.selection.y = my;
myState.selection.w = mx - oldx;
myState.selection.h += oldy - my;
break;
case 3:
myState.selection.x = mx;
myState.selection.w += oldx - mx;
break;
case 4:
myState.selection.w = mx - oldx;
break;
case 5:
myState.selection.x = mx;
myState.selection.w += oldx - mx;
myState.selection.h = my - oldy;
break;
case 6:
myState.selection.h = my - oldy;
break;
case 7:
myState.selection.w = mx - oldx;
myState.selection.h = my - oldy;
break;
}
myState.valid = false;
}
if (myState.selection !== null && !myState.resizeDragging) {
for (i = 0; i < 8; i += 1) {
cur = myState.selectionHandles[i];
if (mx >= cur.x && mx <= cur.x + myState.selectionBoxSize &&
my >= cur.y && my <= cur.y + myState.selectionBoxSize) {
myState.expectResize = i;
myState.valid = false;
switch (i) {
case 0:
this.style.cursor='nw-resize';
break;
case 1:
this.style.cursor='n-resize';
break;
case 2:
this.style.cursor='ne-resize';
break;
case 3:
this.style.cursor='w-resize';
break;
case 4:
this.style.cursor='e-resize';
break;
case 5:
this.style.cursor='sw-resize';
break;
case 6:
this.style.cursor='s-resize';
break;
case 7:
this.style.cursor='se-resize';
break;
}
return;
}
}
myState.resizeDragging = false;
myState.expectResize = -1;
this.style.cursor = 'auto';
}
}, true);
canvas.addEventListener('mouseup', function(e) {
myState.dragging = false;
myState.resizeDragging = false;
myState.expectResize = -1;
if (myState.selection !== null) {
if (myState.selection.w < 0) {
myState.selection.w = -myState.selection.w;
myState.selection.x -= myState.selection.w;
}
if (myState.selection.h < 0) {
myState.selection.h = -myState.selection.h;
myState.selection.y -= myState.selection.h;
}
}
}, true);
canvas.addEventListener('dblclick', function(e) {
var mouse = myState.getMouse(e);
myState.addShape(new Shape(myState, mouse.x - 10, mouse.y - 10, 20, 20, '#bdc3c7'));
}, true);
this.selectionColor = '#3498db';
this.selectionWidth = 2;
this.selectionBoxSize = 6;
this.selectionBoxColor = '#2980b9';
this.interval = 30;
setInterval(function() { myState.draw(); }, myState.interval);
}
CanvasState.prototype.addShape = function(shape) {
"use strict";
this.shapes.push(shape);
this.valid = false;
};
CanvasState.prototype.clear = function() {
"use strict";
this.ctx.clearRect(0, 0, this.width, this.height);
};
CanvasState.prototype.draw = function() {
"use strict";
var ctx, shapes, l, i, shape, mySel;
if (!this.valid) {
ctx = this.ctx;
shapes = this.shapes;
this.clear();
l = shapes.length;
for (i = 0; i < l; i += 1) {
shape = shapes[i];
if (shape.x <= this.width && shape.y <= this.height &&
shape.x + shape.w >= 0 && shape.y + shape.h >= 0) {
shapes[i].draw(ctx);
}
}
if (this.selection !== null) {
ctx.strokeStyle = this.selectionColor;
ctx.lineWidth = this.selectionWidth;
mySel = this.selection;
ctx.strokeRect(mySel.x,mySel.y,mySel.w,mySel.h);
}
this.valid = true;
}
};
CanvasState.prototype.getMouse = function(e) {
"use strict";
var element = this.canvas, offsetX = 0, offsetY = 0, mx, my;
if (element.offsetParent !== undefined) {
do {
offsetX += element.offsetLeft;
offsetY += element.offsetTop;
element = element.offsetParent;
} while (element);
}
offsetX += this.stylePaddingLeft + this.styleBorderLeft + this.htmlLeft;
offsetY += this.stylePaddingTop + this.styleBorderTop + this.htmlTop;
mx = e.pageX - offsetX;
my = e.pageY - offsetY;
return {x: mx, y: my};
};
function init() {
"use strict";
var s = new CanvasState(documen// add a large green rectangle
s.addShape(new Shape(s, 260, 70, 60, 65, 'rgba(0,205,0,0.7)'));
s.addShape(new Shape(s, 240, 120, 40, 40, 'rgba(2,165,165,0.7)'));
s.addShape(new Shape(s, 5, 60, 25, 25, 'rgba(150,150,250,0.7)'));
}
答案 0 :(得分:0)
类似......
var elSource= (whatever element was dragged & dropped - will leave you to work that out);
var elTarget = (target element of drag & drop - presumably you can find that)
var elClone=elSource.cloneNode(true); // makes a copy of source node
elTarget.appendChild(elClone); // adds the cloned html element to 'inside' the target element