Como criar canvas com icones que se conectam e que tem funcionalidades reais com laravel

Criar um sistema semelhante a um “canvas” com ícones que se conectam e possuem funcionalidades reais no Laravel pode ser feito utilizando uma combinação de bibliotecas JavaScript para o frontend (como Konva.js, JointJS, ou GoJS) e Laravel para o backend. Vou descrever uma abordagem para isso.


1. Planejamento Geral

Para criar o sistema, você precisará de:

  • Frontend: Um framework ou biblioteca que permita desenhar o canvas, adicionar ícones, conectar elementos e manipular as conexões.
  • Backend (Laravel): Para salvar os dados do canvas (posições, conexões, tipos de elementos) e executar as funcionalidades associadas aos nós.

2. Ferramentas Necessárias

  • Laravel (backend): Para gerenciar a API, armazenamento e lógica.
  • Biblioteca de Canvas:
    • Konva.js: Para criar elementos gráficos interativos (mais leve e fácil de integrar).
    • JointJS: Ideal para criar fluxogramas e diagramas complexos.
    • GoJS: Muito poderoso, mas pago.
  • Banco de Dados: MySQL/PostgreSQL para salvar a estrutura dos nós e conexões.
  • Frontend Frameworks (opcional): React/Vue.js (opcional, mas facilita a interação com bibliotecas como Konva.js).

3. Estrutura do Banco de Dados

Você precisará de tabelas para armazenar:

  1. Nó/Bloco (Node): Representa os elementos no canvas (ícones).
  2. Conexões (Edges): Representa as conexões entre os nós.

Exemplo de tabelas:

Tabela nodes

CREATE TABLE nodes (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    type VARCHAR(50) NOT NULL,
    position_x FLOAT NOT NULL,
    position_y FLOAT NOT NULL,
    data JSON NULL,
    created_at TIMESTAMP NULL,
    updated_at TIMESTAMP NULL
);

Tabela edges

CREATE TABLE edges (
    id INT AUTO_INCREMENT PRIMARY KEY,
    source_node_id INT NOT NULL,
    target_node_id INT NOT NULL,
    data JSON NULL,
    created_at TIMESTAMP NULL,
    updated_at TIMESTAMP NULL,
    FOREIGN KEY (source_node_id) REFERENCES nodes(id) ON DELETE CASCADE,
    FOREIGN KEY (target_node_id) REFERENCES nodes(id) ON DELETE CASCADE
);

4. Backend (Laravel)

Criação de Models e Migrations

Crie os modelos e migrations para Node e Edge:

php artisan make:model Node -m
php artisan make:model Edge -m

Edite as migrations geradas (database/migrations/<timestamp>_create_nodes_table.php):

Schema::create('nodes', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('type');
    $table->float('position_x');
    $table->float('position_y');
    $table->json('data')->nullable();
    $table->timestamps();
});

Edite a migration dos edges (database/migrations/<timestamp>_create_edges_table.php):

Schema::create('edges', function (Blueprint $table) {
    $table->id();
    $table->unsignedBigInteger('source_node_id');
    $table->unsignedBigInteger('target_node_id');
    $table->json('data')->nullable();
    $table->timestamps();

    $table->foreign('source_node_id')->references('id')->on('nodes')->onDelete('cascade');
    $table->foreign('target_node_id')->references('id')->on('nodes')->onDelete('cascade');
});

Rode as migrations:

php artisan migrate

Controladores e Rotas

Crie um controlador para manipular os nós e conexões:

php artisan make:controller CanvasController

Exemplo de controlador (CanvasController.php):

namespace App\Http\Controllers;

use App\Models\Node;
use App\Models\Edge;
use Illuminate\Http\Request;

class CanvasController extends Controller
{
    public function getCanvasData()
    {
        $nodes = Node::all();
        $edges = Edge::all();
        return response()->json(['nodes' => $nodes, 'edges' => $edges]);
    }

    public function saveNode(Request $request)
    {
        $node = Node::create($request->all());
        return response()->json($node, 201);
    }

    public function saveEdge(Request $request)
    {
        $edge = Edge::create($request->all());
        return response()->json($edge, 201);
    }

    public function deleteNode($id)
    {
        Node::destroy($id);
        return response()->json(['message' => 'Node deleted']);
    }

    public function deleteEdge($id)
    {
        Edge::destroy($id);
        return response()->json(['message' => 'Edge deleted']);
    }
}

Defina as rotas em routes/api.php:

use App\Http\Controllers\CanvasController;

Route::get('/canvas', [CanvasController::class, 'getCanvasData']);
Route::post('/canvas/node', [CanvasController::class, 'saveNode']);
Route::post('/canvas/edge', [CanvasController::class, 'saveEdge']);
Route::delete('/canvas/node/{id}', [CanvasController::class, 'deleteNode']);
Route::delete('/canvas/edge/{id}', [CanvasController::class, 'deleteEdge']);

5. Frontend (Konva.js)

Instale Konva.js

No seu projeto frontend (ou mesmo no Laravel Blade), inclua a biblioteca Konva.js:

npm install konva

Ou inclua via CDN no arquivo Blade:

<script src="https://cdn.jsdelivr.net/npm/konva@8.4.3/konva.min.js"></script>

Código de Exemplo no Frontend

Adicione o canvas interativo ao seu frontend (resources/views/canvas.blade.php):

<!DOCTYPE html>
<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Canvas Interativo</title>
    <script src="https://cdn.jsdelivr.net/npm/konva@8.4.3/konva.min.js"></script>
</head>
<body>
    <h1>Canvas Interativo</h1>
    <div id="container"></div>

    <script>
        const stage = new Konva.Stage({
            container: 'container', // ID do div
            width: window.innerWidth,
            height: window.innerHeight,
        });

        const layer = new Konva.Layer();
        stage.add(layer);

        // Exemplo de nó
        const node = new Konva.Rect({
            x: 100,
            y: 100,
            width: 100,
            height: 50,
            fill: 'blue',
            draggable: true,
        });

        node.on('dragend', () => {
            console.log('Nova posição:', node.x(), node.y());
        });

        layer.add(node);
        layer.draw();
    </script>
</body>
</html>

6. Salvando Dados no Backend

  • Quando o usuário cria um nó ou uma conexão, envie os dados para o backend via AJAX/Fetch.
  • Exemplo:
fetch('/api/canvas/node', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        name: 'Meu Nó',
        type: 'rect',
        position_x: node.x(),
        position_y: node.y(),
        data: { color: 'blue' },
    }),
})
.then((response) => response.json())
.then((data) => console.log('Nó salvo:', data));

7. Funcionalidades Reais

  • Execução de Funcionalidades: Cada nó pode ter um “tipo” (ex.: API call, cálculo, etc.). Ao salvar ou conectar nós, o backend pode processar os dados e executar as ações necessárias.
  • Renderização Dinâmica: Os nós e conexões salvos no banco podem ser renderizados no canvas ao carregar a página.

Resultado Final

  • Você terá um canvas interativo no frontend que permite criar, mover e conectar elementos.
  • Laravel gerenciará o backend, salvando a posição dos nós, conexões e executando as funcionalidades associadas.

Se precisar de algo mais detalhado, é só pedir!

Posts Similares