npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mlalbuquerque/court-canvas

v1.4.0

Published

Uma library agnóstica para renderização vetorial de prancheta tática.

Readme

Court Canvas Icon Court Canvas

Uma biblioteca agnóstica, modular e focada na renderização vetorial (2D) de pranchetas táticas esportivas baseada em Konva.js.

Court Canvas

O Court Canvas permite criar rapidamente um campo de futebol interativo onde você pode arrastar jogadores, desenhar marcações geométricas (retângulos, elipses, setas directionais) e, mais importante, serializar e extrair esse estado para JSON e Imagens (.png) para salvar tudo num banco de dados.

✨ Funcionalidades (O que o Motor Faz?)

  • 🏟️ Design Preciso: Background matemático renderizando grandes e pequenas áreas perfeitamente dimensionadas.
  • 🖐 Interatividade Completa (Drag & Drop): Padrão State nas ferramentas (clique e arraste jogadores para construir a tática).
  • 🧱 Bounding Box Auto-Ajustável: Suas peças de xadrez não saem para fora da linha do campo; algoritmos matemáticos seguram os elementos nas bordas corretas!
  • 🎨 Toolbar Inteligente: Destaque visual da ferramenta ativa e seletores automáticos de cor. Modifique a cor da equipe, estilos e passes diretamente na barra!
  • 🖱️ Cursores Contextuais: O ponteiro do mouse muda conforme a ferramenta (Mão para seleção, Cruz para desenho, Mira para jogadores), tornando a experiência intuitiva.
  • Viajante do Tempo: Histórico de Estado 100% autônomo. Botões e Teclas de Atalho (CTRL+Z e CTRL+Y) suportados para desfazer e refazer marcações.
  • 📸 Exportação e Importação: Salve sua tática em JSON para carregar num backend, ou renderize uma imagem em HQ (.png) da tática em um instante. Você também pode reimportar payloads JSON para continuar editando táticas salvas!
  • Popups UI Modernos: Prompts de renomeação de jogadores (dblclick), importação de dados e caixas de ajuda alimentadas pelo SweetAlert2 nativamente.
  • ⚛️ Integração Agnóstica: Pode ser executado em Vanilla JS, ReactJS ou VueJS.

🛠 Desenvolvimento e Infraestrutura (Docker)

Para garantir que todos os desenvolvedores usem a mesma versão do Node.js (v24+) e evitar conflitos de sistema, o projeto utiliza uma infraestrutura containerizada. Você não precisa ter o Node instalado na sua máquina, apenas o Docker.

Comandos de Atalho

Use os scripts na pasta infra/ para rodar comandos NPM ou Node dentro do container:

# Instalar dependências
./infra/npm install

# Rodar o servidor de desenvolvimento
./infra/npm run dev

# Rodar qualquer comando NPX
./infra/npx vitest

🚀 Instalação (Uso em Produção)

O pacote está oficialmente distribuído no NPM Registry:

npm install @mlalbuquerque/court-canvas

💻 Exemplos de Uso (Demos)

1. Customização Avançada (Ícones, Emojis e Ferramentas)

Você pode estender a biblioteca com seus próprios ícones (arquivos de imagem) ou usar Emojis/Texto diretamente como avatares.

💡 Dica: A propriedade imageUrl carrega arquivos externos (preferencialmente SVGs), enquanto a propriedade image aceita strings de texto ou emojis.

import { CourtCanvas } from '@mlalbuquerque/court-canvas';

const court = new CourtCanvas('meu-campo', {
  width: 800,
  height: 500,
  customTools: [
    { 
      id: 'ball', 
      type: 'stamp', 
      icon: '⚽', 
      imageUrl: 'https://exemplo.com/bola.svg', // Carrega arquivo de imagem
      label: 'Bola de Futebol'
    },
    {
      id: 'custom-player',
      type: 'player',
      icon: '👤',
      image: '👤', // Usa emoji diretamente como avatar do jogador
      label: 'Jogador Especial',
      numberPosition: 'bottom-right' // 'center' (padrão) ou 'bottom-right'
    }
  ],
  toolbar: {
    // Escolha quais botões exibir e a ordem
    buttons: ['select', 'player-a', 'player-b', 'custom-player', 'ball', 'arrow', 'clear']
  }
});

2. Jogadores e Equipes (Novo v1.4.0)

Agora você pode identificar jogadores por nome e gerenciar elencos completos.

Rótulos Editáveis

Ao dar um duplo-clique em qualquer jogador no campo, um menu abrirá para editar o Número e o Nome. O nome aparecerá centralizado logo abaixo do ícone do jogador.

Ferramenta de Elenco (Team List)

Você pode cadastrar times inteiros com fotos e metadados. Quando a ferramenta é selecionada, o banco de reservas abre para você escolher quem entra em campo.

const court = new CourtCanvas('container', {
  customTools: [
    {
      id: 'meu-time',
      type: 'team',
      label: 'Meu Time',
      icon: 'https://path-to-badge.png', // Escudo do time ou emoji '🛡️'
      teamColor: '#3498db',
      players: [
        { name: 'Jogador 1', number: 10, photo: 'https://path-to-photo.png' },
        { name: 'Jogador 2', number: 7 },
        { name: 'Jogador 3', number: 11 }
      ]
    }
  ]
});

3. Vanilla JavaScript (O HTML puro)

<div id="meu-campo"></div>
<script type="module">
  import { CourtCanvas } from '@mlalbuquerque/court-canvas';

  // Inicialização simples
  const court = new CourtCanvas('meu-campo', { width: 800, height: 500 });

  // Carregando um estado salvo (JSON)
  const savedState = '{"className":"Layer","children":[...]}';
  const courtWithState = new CourtCanvas('outro-campo', { initialState: savedState });
</script>

2. React

import React, { useState } from 'react';
import CourtCanvasReact from '@mlalbuquerque/court-canvas/react';

const TacticalBoard = () => {
  const [court, setCourt] = useState(null);

  const handleExport = () => {
    if (court) {
      const data = court.jsonExporter.export();
      console.log('JSON da tática:', data);
    }
  };

  return (
    <div>
      <CourtCanvasReact 
        onCanvasReady={(instance) => setCourt(instance)}
        width={800}
        height={500}
      />
      <button onClick={handleExport}>Exportar JSON</button>
    </div>
  );
};

3. Vue 3 (Composition API)

<template>
  <div>
    <CourtCanvasVue 
      @ready="onReady"
      :width="800"
      :height="500"
    />
    <button @click="handleExport">Exportar JSON</button>
  </div>
</template>

<script setup>
import CourtCanvasVue from '@mlalbuquerque/court-canvas/vue';
import { ref } from 'vue';

const court = ref(null);

const onReady = (instance) => {
  court.value = instance;
};

const handleExport = () => {
  if (court.value) {
    const data = court.value.jsonExporter.export();
    console.log('JSON da tática:', data);
  }
};
</script>

🧪 Qualidade e Segurança

O projeto possui um fluxo rigoroso de Garantia de Qualidade (QA):

1. Testes Automatizados

  • Unitários (Vitest): Focados na lógica do StateManager, Exporters e Tools.
  • E2E (Playwright): Validam o fluxo completo do usuário no navegador.
./infra/npm run test       # Roda testes unitários
./infra/npm run test:e2e   # Roda testes de ponta a ponta

2. Bloqueio de Push (Husky)

Existe um "Git Hook" configurado que impede o envio de código para o servidor (git push) se os testes não estiverem passando. Isso garante que a main esteja sempre estável.

3. CI/CD (GitHub Actions)

Toda alteração enviada ao GitHub dispara automaticamente o Test Suite na nuvem para uma validação final em ambiente limpo.


🛠 Arquitetura do Pacote

  • src/core/: Núcleo algorítmico agnóstico focado em Konva.js.
  • src/core/Tools/: Ferramentas de interação (PlayerTool, ArrowTool, etc).
  • src/core/Exporters/: Formatadores de saída (JsonExporter e ImageExporter).
  • src/react/ e src/vue/: Wrappers para frameworks UI modernos.