Hallo Leute,
ich versuche mich gerade an einem kleinen Canvas-Projekt. Irgendwann soll damit ein einfaches Organigramm angezeigt (und vielleicht auch noch bearbeitet) werden.
Alles funktioniert in meinem Test soweit schonmal, aber das Vergrößern/Verkleinern über das Mausrad leider nicht so ganz.
Die ursprüngliche Canvas-Anzeige bleibt stehen und die skalierte Version wird erst bei Drag&Drop "mit" angezeigt.
Wieso bleibt das alte Teil stehen und wird nicht durch das clearRect gelöscht?
Hier der aktuelle Source-Code:
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Canvas</title>
<style>
.canvas-container {
text-align: center;
}
.canvas {
border: 5px solid black;
background-color: #fff;
}
</style>
</head>
<body>
<div class="canvas-container">
<canvas id="canvas" class="canvas"></canvas>
</div>
<script>
let canvas = document.getElementById("canvas");
let sizeX = window.innerWidth - 30 ;
let sizeY = window.innerHeight - 60 ;
canvas.style.width = sizeX + "px";
canvas.style.height = sizeY + "px";
let scale = window.devicePixelRatio;
canvas.width = sizeX * scale;
canvas.height = sizeY * scale;
let canvas_width = canvas.width;
let canvas_height = canvas.height;
let ctx = canvas.getContext("2d");
ctx.scale(scale, scale);
let shapes = [];
let current_shape_index = null;
let is_dragging = false;
let startX;
let startY;
let lastX = canvas.width/2
let lastY = canvas.height/2;
let scaleFactor = 0.2;
let originx = 0;
let originy = 0;
shapes.push( { id: "1", form: 'rect', x:50, y:50, width: 180, height: 100, color: 'blue'} );
shapes.push( { id: "2", form: 'rect', x:150, y:250, width: 180, height: 100, color: 'red'} );
shapes.push( { id: "3", form: 'connector', from: "1", to: "2", from_point: "B", to_point: "T", color: 'black'} );
shapes.push( { id: "4", form: 'rect', x:350, y:150, width: 180, height: 100, color: 'lightblue'} );
shapes.push( { id: "5", form: 'connector', from: "2", to: "4", from_point: "R", to_point: "L", color: 'black'} );
let offset_x;
let offset_y;
let get_offset = function() {
let canvas_offsets = canvas.getBoundingClientRect();
offset_x = canvas_offsets.left;
offset_y = canvas_offsets.top;
}
get_offset();
window.onscroll = function() {
get_offset();
}
window.onresize = function() {
get_offset();
}
window.onscroll = function() {
get_offset();
}
canvas.onresize = function() {
get_offset();
}
let is_mouse_in_shape = function(x, y, shape) {
let shape_left = shape.x;
let shape_right = shape.x + shape.width;
let shape_top = shape.y;
let shape_bottom = shape.y + shape.height;
if (x > shape_left && x < shape_right && y > shape_top && y < shape_bottom) {
return true;
}
return false;
}
let mouse_down = function(event) {
event.preventDefault();
startX = parseInt(event.clientX) - offset_x;
startY = parseInt(event.clientY) - offset_y;
let index = 0;
for (let shape of shapes) {
if (is_mouse_in_shape(startX, startY, shape)) {
current_shape_index = index;
is_dragging = true;
return;
}
index ++;
}
}
let mouse_out = function(event) {
if (!is_dragging) {
return;
}
event.preventDefault();
is_dragging = false;
}
let mouse_up = function(event) {
if (!is_dragging) {
return;
}
event.preventDefault();
is_dragging = false;
}
let mouse_move = function(event) {
if (!is_dragging) {
return;
}
event.preventDefault();
let mouseX = parseInt(event.clientX) - offset_x;
let mouseY = parseInt(event.clientY) - offset_y;
let dx = mouseX - startX;
let dy = mouseY - startY;
let current_shape = shapes[current_shape_index];
current_shape.x += dx;
current_shape.y += dy;
draw_shapes();
startX = mouseX;
startY = mouseY;
}
let mouse_wheel = function(event) {
event.preventDefault();
let mouseX = parseInt(event.clientX) - offset_x;
let mouseY = parseInt(event.clientY) - offset_y;
let wheel = event.deltaY < 0 ? 1 : -1;
let zoom = Math.exp(wheel * scaleFactor);
ctx.translate(originx, originy);
ctx.scale(zoom,zoom);
originx -= mouseX / (scale * zoom) - mouseX / scale;
originy -= mouseY / (scale * zoom) - mouseY / scale;
ctx.translate(-originx, -originy);
scale *= zoom;
draw_shapes();
return false;
}
canvas.onmousedown = mouse_down;
canvas.onmouseup = mouse_up;
canvas.onmouseout = mouse_out;
canvas.onmousemove = mouse_move;
canvas.onwheel = mouse_wheel;
let getCoords = function(shape,point) {
var _x = 0;
var _y = 0;
switch (point) {
case "B":
_x = shape.x + ( shape.width / 2 );
_y = shape.y + shape.height;
break;
case "T":
_x = shape.x + ( shape.width / 2 );
_y = shape.y;
break;
case "L":
_x = shape.x;
_y = shape.y + ( shape.height / 2 );
break;
case "R":
_x = shape.x + shape.width;
_y = shape.y + ( shape.height / 2 );
break;
}
return { y: _y, x: _x };
}
let draw_shapes = function() {
ctx.clearRect(0, 0, canvas_width, canvas_height);
for (let shape of shapes) {
switch (shape.form) {
case "rect":
ctx.fillStyle = shape.color;
ctx.fillRect(shape.x, shape.y, shape.width, shape.height);
break;
case "connector":
let from_shape = shapes.filter(s => s.id == shape.from);
let to_shape = shapes.filter(s => s.id == shape.to);
let from_shape_point = shape.from_point;
let to_shape_point = shape.to_point;
ctx.beginPath();
let a = getCoords(from_shape[0],from_shape_point);
ctx.moveTo(a.x,a.y);
let b = getCoords(to_shape[0],to_shape_point);
ctx.lineTo(b.x,b.y);
ctx.lineWidth = 1;
ctx.strokeStyle = shape.color;
ctx.stroke();
break;
}
}
}
draw_shapes();
</script>
</body>
</html>