Anotace

Přidejte podporu anotací do prohlížeče

Anotace v Doconut fungují ve dvou směrech: uživatelé je kreslí v prohlížečovém widgetu a server je ukládá po stránkách, nebo váš kód je vytváří programově a načítá je do otevřené relace. V obou případech se vykreslují na stránkách a mohou být vkládány do exportů PDF/PNG.

Podpora anotací je řízena licenční schopností Annotation (automaticky udělena při aktivní dočasné licenci).

Povolení uživatelského rozhraní anotací

Anotace jsou modul Viewer, nikoli samostatná lišta nástrojů. Celá stránka musí zahrnovat zdroje Vieweru, lištu nástrojů Vieweru, místo pro připojení Vieweru a inicializovaný objViewer; poté je Ribbon anotací připojen a připojen k téže instanci.

Vystavte balíčky anotací spolu s balíčky vieweru — jsou licencovaně omezené, takže značky se objeví jen když je schopnost dostupná:

html
@Html.Raw(Viewer.ReferenceCss(new CssConfig
{
    IncludeViewerCss     = true,
    IncludeAnnotationCss = true   // jquery-ui.min.css + annotationBar.css
}))

@Html.Raw(Viewer.ReferenceScripts(new ScriptConfig
{
    IncludeJQuery             = true,
    IncludeViewerScripts      = true,
    IncludeAnnotationScripts  = true, // jquery-ui, raphael.js, annotation.js
    IncludeAnnotationBar      = true  // the embedded annotation ribbon
}))

Udržujte kompletní kompozici Vieweru viditelnou v markupu:

html
<nav id="toolbar" aria-label="Document viewer controls">
    <!-- Ovládací prvky prohlížeče, včetně tlačítka, které otevírá Anotaci -->
</nav>
<div id="annBarMount"></div>
<div id="divDocViewer"><div id="div_ctlDoc"></div></div>

Balíček anotací generuje Ribbon DOM uvnitř annBarMount; není nutné kopírovat jeho tlačítka nebo markup dialogu. Nejprve inicializujte docViewer, pak vytvořte Ribbon pouze když server potvrdí, že anotace jsou licencovány:

html
<script>
    let annBar = null;
    let currentToken = '';

    const objViewer = $('#div_ctlDoc').docViewer({
        BasePath: 'doconut',
        ResPath: 'doconut-res/images',
        onAnnLoaded:    () => annBar?.handleAnnLoaded(),
        onAnnSaved:     () => annBar?.handleAnnSaved(),
        onAnnSaveError: () => annBar?.handleAnnSaveError(),
        onAnnClosed:    () => annBar?.handleAnnClosed(),
        onError:        (message) => console.error('Viewer error:', message)
    });

    @if (Viewer.IsAnnotationEnabled)
    {
        <text>
    annBar = $('#annBarMount').doconutAnnotationBar({
        docId: 'ctlDoc',
        getRequestParams: () => ({ token: currentToken }),
        onStatus: (message) => console.log(message),
        onToast: (message, type) => console.log(type, message),
        onLayout: () => requestAnimationFrame(() => objViewer.Refit())
    });
    annBar.attach(objViewer);
        </text>
    }
</script>

Ukládání z Ribbonu odesílá data přes middleware (AnnSave), který je ukládá do relace dokumentu po stránkách. Načítání (AnnLoad) probíhá automaticky, když se stránka s anotacemi vykreslí. Čtyři zpětné volání onAnn* udržují Ribbon synchronizovaný s životním cyklem vieweru.

Otevřete a zavřete jej z libovolné hostitelské lišty Vieweru:

javascript
annBar.open();
annBar.close();

Veřejné API Ribbonu je:

MetodaÚčel
attach(objViewer)Připojí pásku k inicializovanému prohlížeči; vyžadováno jednou
open() / close()Zahájí nebo ukončí úpravy anotací
reset()Vrátí pásku do uzavřeného, needitačního stavu
isOpen() / annotating()Přečte stav pásky / stav úprav anotací v prohlížeči
reopenEditable()Znovu načte anotace aktuální stránky jako editovatelné objekty
updateActionState()Obnoví dostupnost ovládacích prvků uložit/smazat po změnách hosta
headerSlot()Získá volitelný slot pro rozšíření hlavičky pro ovládací prvky hosta

onStatus, onToast, onLayout, onEditStart a onEditEnd jsou volitelné hostitelské zpětné volání. Objekt endpoints může navíc poskytovat exportPdf, exportPng, imageUpload a imageList; ovládací prvky bez nastaveného koncového bodu zůstávají skryté. Pro sekvenci spuštění kombinovaného Vieweru, Search a Annotation viz Quick Start.

Balíček anotací přidává nástroje pro autorování v prohlížeči, ale data stále patří serverové relaci dokumentu identifikované tokenem. Znovuotevření zdroje vytvoří novou relaci; pokud anotace musí přežít po skončení relace, uložte XML nebo zakódovanou obálku anotací ve své aplikaci.

Vytvoření anotací v C#

Získejte správce vázaného na otevřenou relaci, přidejte anotace a načtěte je (s using Doconut.Annotations; pro typy a using System.Drawing; pro Rectangle/Color):

csharp
app.MapPost("/api/annotations/load-sample", (string token, Viewer viewer) =>
{
    // Vázáno na rozměry stránky otevřené relace
    var manager = viewer.GetAnnotationManager(token);
    var pageCount = viewer.GetPageCount(token);

    // Jeden razítko na stránku
    for (int page = 1; page <= pageCount; page++)
    {
        manager.Add(new StampAnnotation(page, new Rectangle(30, 20, 240, 90),
            $"PAGE {page}", 28, 4, Color.Maroon)
        {
            Opacity = 60,
            Rotate  = -8
        });
    }

    manager.Add(new NoteAnnotation(1, new Rectangle(420, 150, 220, 120),
        "Loaded from C# code.", Color.FromArgb(255, 255, 255, 170), 14));

    // Načíst do relace — widget je načte pomocí AnnLoad a
    // renderér je vloží do exportů obrázku/PDF.
    viewer.LoadAnnotationData(token, manager);
    return Results.Ok();
});

Typy anotací

Všechny typy jsou v Doconut.Annotations a dědí z BaseAnnotation (číslo stránky + ohraničující Rectangle):

TypPoznámky
StampAnnotationTextové razítko s velikostí písma, okrajem, barvou; podporuje Opacity, Rotate
NoteAnnotationLepící poznámka s textem, barvou pozadí, velikostí písma, TitleColor
RectangleAnnotationBarvy okraje a výplně, Title/ShowTitle
CircleAnnotationOkraj + výplň, ShowBorder
EllipseAnnotationOkraj + výplň, ShowBorder
TriangleAnnotationBarva okraje, BackColor, ShowBorder
LineAnnotationPřímá čára s šířkou a barvou
ArrowAnnotationČára s šipkou; nastavitelný Direction (typ ArrowDirection, směry kompasu, výchozí E)
FreehandAnnotationVolný tah z kódovaných bodů FreehandData
ImageAnnotationObrázek z URL. Relativní URL je rozřešena vůči hostiteli požadavku, když je anotace přidána (při vypalování se stahuje jen obrázek) — musí být přístupná ze serveru (např. soubor pod wwwroot servírovaný UseStaticFiles)

API třídy AnnotationManager

ČlenÚčel
Add(BaseAnnotation)Zařadí anotaci do fronty
GetAnnotations() / GetAnnotations(int page)Prohlédne, co manager obsahuje
ClearAnnotations() / ClearAnnotations(int page)Odstraní vše / podle stránky
GetAnnotationData() / GetAnnotationData(int page)Kódovaný řetězec dat anotací — Base64 obálka (co widget konzumuje)
GetAnnotationXml()XML forma

Viewer zrcadlí operace načítání/čtení vůči relaci: LoadAnnotationData(token, manager) nebo LoadAnnotationData(token, encodedData) (Base64 obálka z GetAnnotationData()), LoadAnnotationXML(token, xml), GetAnnotationXML(token).

Export s vypálenými anotacemi

csharp
// PDF všech stránek s vykreslenými anotacemi
app.MapGet("/api/annotations/export-pdf", async (string token, Viewer viewer) =>
{
    byte[] pdf = await viewer.ExportAnnotationsToPdfAsync(token, zoom: 100);
    return Results.File(pdf, "application/pdf", "export.pdf");
});

// Nebo ZIP s PNG soubory po stránkách
app.MapGet("/api/annotations/export-png-zip", async (string token, Viewer viewer) =>
{
    byte[] zip = await viewer.ExportAnnotationsToPngZipAsync(token, zoom: 100);
    return Results.File(zip, "application/zip", "annotations-png.zip");
});

Exporty používají stejný vypalovač jako vykreslování na obrazovce, takže to, co uživatelé vidí, je to, co soubor obsahuje.

Pracovní postup pro trvalé uložení

  1. Otevřete dokument a získejte jeho token.
  2. Načtěte dříve uložené XML nebo kódovaná data do tohoto tokenu.
  3. Nechte widget přečíst a upravit anotace v relaci.
  4. Získejte XML pomocí GetAnnotationXML(token), když se vaše aplikace rozhodne data uložit.
  5. Exportujte PDF/PNG, když je vyžadován plochý výstup.
  6. Uzavřete relaci dokumentu.

Neužívejte neprůhledný token vieweru jako trvalý identifikátor anotace. Spojte uložená data anotací s vašimi vlastními identifikátory dokumentu a verzí.

Bezpečnostní a vykreslovací poznámky

  • Požadavky na anotace používají stejnou bezpečnost relace/tokenu jako požadavky na stránky.
  • Relativní ImageAnnotation URL je rozpoznáno z hostitele požadavku a musí být během burn čas dosažitelné pro server.
  • Ověřte a kontrolujte jakékoli uživatelem dodané URL obrázku, aby se zabránilo podvržení požadavku na straně serveru.
  • Exporty používají stejné rozhodnutí o licenci/vlastní vodoznaku jako vykreslování stránky na obrazovce.
  • Velké volné ruční payloady a exporty ve vysokém rozlišení zvyšují spotřebu paměti; testujte realistické dokumenty a hodnoty přiblížení.

Odstraňování potíží

PříznakKontrola
Chybí páska anotacíAnnotation schopnost a čtyři příznaky CSS/script anotací
Uložený callback hlásí chybuVypršení tokenu/sesze a middleware BasePath
C# anotace se nezobrazujíČíslování stránek začíná od jedné a data byla načtena do aktivního tokenu
Obrázková anotace se zobrazuje na obrazovce, ale ne v exportuServer může během burn-in dosáhnout na URL obrázku
Znovu otevřený dokument nemá žádné anotaceUložte XML/data mimo relaci prohlížeče, pak je načtěte do nového tokenu

Byla tato stránka užitečná?