Home Test Canvas
Post
Cancel

Test Canvas

This is a simple test of an HTML canvas, without JointJS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
<style>
  #canvas {
    border: 1px solid #000;
  }
</style>
<div class="relative h-[800px] w-[1088px]">
  <canvas id="canvas" class="absolute bottom-0 right-0" width="750" height="750"></canvas>
  <button id="toggleModeButton">Toggle Mode</button>

  <script>
    const toggleModeButton = document.getElementById("toggleModeButton");
    let isNodePlacingMode = true; // Initially, start with node placing mode
    toggleModeButton.addEventListener("click", () => {
        isNodePlacingMode = !isNodePlacingMode; // Toggle the mode
    });
    const canvas = document.getElementById("canvas")
    const ctx = canvas.getContext("2d")
    const ghostCircle = { x: 0, y: 0, radius: 0, color: "#ccc" }
    const circles = []
    let circleCounter = 0
    let selectedNode = null;
    let pathStartPoint = null;
    canvas.addEventListener("mousemove", (e) => {
        if (isNodePlacingMode) {
            const mouseX = e.clientX - canvas.getBoundingClientRect().left
            const mouseY = e.clientY - canvas.getBoundingClientRect().top
            ghostCircle.x = mouseX
            ghostCircle.y = mouseY
            ghostCircle.radius = 30
        } else {
            if (!isNodePlacingMode && selectedNode && pathStartPoint) {
                const mouseX = e.clientX - canvas.getBoundingClientRect().left;
                const mouseY = e.clientY - canvas.getBoundingClientRect().top;
                // Clear the canvas and redraw everything
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                drawCircles();
                drawConnections(); // Draw connections as well
                // Draw the path from the selected node to the mouse position
                ctx.beginPath();
                ctx.moveTo(selectedNode.x, selectedNode.y);
                ctx.lineTo(mouseX, mouseY);
                ctx.strokeStyle = "#000"; // Adjust the path color as needed
                ctx.lineWidth = 2;
                ctx.stroke();
                ctx.closePath();
            }
        }
    });
    canvas.addEventListener("click", (e) => {
        if (isNodePlacingMode) {
            const circleRadius = 30
            const circleColor = `#000`
            const newCircle = { id: ++circleCounter, x: ghostCircle.x, y: ghostCircle.y, radius: circleRadius, color: circleColor }
            circles.push(newCircle)
            ghostCircle.radius = 0
            drawCircles()
            
        } else {
            const mouseX = e.clientX - canvas.getBoundingClientRect().left;
            const mouseY = e.clientY - canvas.getBoundingClientRect().top;
            // Check if the click is inside a node
            for (const circle of circles) {
                const distance = Math.sqrt(
                    (mouseX - circle.x) ** 2 + (mouseY - circle.y) ** 2
                );
                
                if (distance < circle.radius) {
                    // Clicked inside a node, select it
                    selectedNode = circle;
                    return;
                }
            }
            pathStartPoint = { x: selectedNode.x, y: selectedNode.y };
            console.log(pathStartPoint)
            // If not inside a node, start a path if a node is selected
            if (selectedNode) {
                
                
            }
            
        }
    });
    canvas.addEventListener("mouseup", (e) => {
        if (isNodePlacingMode) {
            // Handle node placing mode
            // ...
        } else {
            if (selectedNode && pathStartPoint) {
                const mouseX = e.clientX - canvas.getBoundingClientRect().left;
                const mouseY = e.clientY - canvas.getBoundingClientRect().top;
                // Check if the release is inside a node
                for (const circle of circles) {
                    const distance = Math.sqrt(
                        (mouseX - circle.x) ** 2 + (mouseY - circle.y) ** 2
                    );
                    if (distance < circle.radius) {
                        // Released inside a node, create a connection
                        const newConnection = {
                            from: selectedNode.id,
                            to: circle.id,
                        };
                        
                        drawConnections()
                        break;
                    }
                }
            }
            // Reset selection and path start point
            selectedNode = null;
            pathStartPoint = null;
            }
    });
    function drawCircle(x, y, radius, color, id) {
        ctx.beginPath()
        ctx.arc(x, y, radius, 0, Math.PI * 2)
        ctx.fillStyle = color
        ctx.fill()
        ctx.closePath()
        ctx.fillStyle = "#fff"
        ctx.font = "25px SFPro-Text-Regular"
        const textWidth = ctx.measureText(id).width;
        const textX = x - textWidth / 2;
        const textY = y + 7;
        ctx.fillText(id, textX, textY);
    }
    function drawCircles() {
        ctx.clearRect(0, 0, canvas.width, canvas.height)
        circles.forEach((circle) => {
            drawCircle(circle.x, circle.y, circle.radius, circle.color, circle.id)
        })
        drawGhostCircle()
    }
    function drawGhostCircle() {
        const { x, y, radius, color } = ghostCircle
        if (radius > 0) {
            ctx.beginPath()
            ctx.arc(x, y, radius, 0, Math.PI * 2)
            ctx.strokeStyle = color
            ctx.lineWidth = 2
            ctx.stroke()
            ctx.closePath()
        }
    }
    function drawConnections() {
        for (const connection of connections) {
            const fromNode = circles.find(circle => circle.id === connection.from);
            const toNode = circles.find(circle => circle.id === connection.to);
            ctx.beginPath();
            ctx.moveTo(fromNode.x, fromNode.y);
            ctx.lineTo(toNode.x, toNode.y);
            ctx.strokeStyle = "#000"; // Adjust the path color as needed
            ctx.lineWidth = 2;
            ctx.stroke();
            ctx.closePath();
        }
    }
    function animate() {
        drawCircles()
        requestAnimationFrame(animate)
    }
    animate()
</script>
</div>
This post is licensed under CC BY 4.0 by the author.

Javascript Object Oriented Programming

Plan 7