JavaScript Page & Image Watermarks – watermark-js-plus

Category: Image , Javascript , Recommended | October 15, 2026
Authorzhensherlock
Last UpdateOctober 15, 2026
LicenseMIT
Views0 views
JavaScript Page & Image Watermarks – watermark-js-plus

watermark-js-plus is a browser-based JavaScript library for placing text or image watermarks on web pages, HTML containers, and images. It also creates faint blind watermarks that can be enhanced from captured screenshots. The library works with vanilla JavaScript and frontend frameworks.

Features

  • Repeating watermark tiles with adjustable dimensions and rotation.
  • Multiline text and rich-text content.
  • Custom grid layouts with per-cell visibility settings.
  • Typography, gradients, image patterns, shadows, and Canvas filters.
  • Background animation and adjustable opacity for visible watermarks.
  • Runtime updates and removal through instance methods.
  • Optional DOM tamper monitoring and watermark recreation.

How To Use It

Basic Usage

For a plain HTML page, load the IIFE build and call WatermarkPlus.Watermark.

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/index.iife.min.js"></script>
<script>
  const watermark = new WatermarkPlus.Watermark({
    content: 'Internal preview',
    width: 240,
    height: 160,
    rotate: 25,
    globalAlpha: 0.16
  });
  watermark.create();
</script>

Installation With npm

Install the package in an application that uses an ES module bundler.

npm install watermark-js-plus
import { Watermark } from 'watermark-js-plus';
const watermark = new Watermark({ content: 'Confidential' });
await watermark.create();

Watermark a Specific Container

Set parent to an element or CSS selector. The container needs a CSS positioning context, for example position: relative.

<section id="report-preview">
  <h2>Quarterly report</h2>
  <p>Confidential draft for internal review.</p>
</section>
#report-preview {
  position: relative;
  min-height: 240px;
}
const reportMark = new Watermark({
  parent: '#report-preview',
  content: 'Internal use only',
  fontColor: '#334155',
  globalAlpha: 0.12
});
await reportMark.create();

Use a Logo as a Watermark

For image content, set contentType to 'image' and pass the logo URL through image. Keep the image on the same origin or configure its host to permit cross-origin loading.

const logoMark = new Watermark({
  contentType: 'image',
  image: '/images/company-logo.png',
  imageWidth: 100,
  width: 240,
  height: 180,
  globalAlpha: 0.2
});
await logoMark.create();

Create a Custom Grid Watermark

The grid layout can position multiple marks inside each repeated tile. Set rows, cols, spacing, and an optional visibility matrix inside gridLayoutOptions.

const gridMark = new Watermark({
  content: 'DRAFT',
  layout: 'grid',
  width: 150,
  height: 100,
  gridLayoutOptions: {
    rows: 2,
    cols: 2,
    gap: [20, 20],
    matrix: [[1, 0], [0, 1]]
  },
  globalAlpha: 0.15
});
await gridMark.create();

Apply a Watermark to an Image

ImageWatermark writes the mark into an existing <img> element as a PNG Data URL. Call decode() after the element exists and before reading its dimensions. For a remote image, set crossorigin="anonymous" before assigning its URL and make sure the image server sends suitable CORS headers.

<img id="preview-photo" src="/images/preview.jpg" alt="Document preview">
import { ImageWatermark } from 'watermark-js-plus';
const photo = document.querySelector('#preview-photo');
await photo.decode();
const imageMark = new ImageWatermark({
  dom: photo,
  content: 'SAMPLE',
  width: photo.width,
  height: photo.height,
  rotate: 0,
  translatePlacement: 'bottom-end',
  fontColor: '#fff',
  fontSize: '28px',
  globalAlpha: 0.6
});
await imageMark.create();

Create and Decode a Blind Watermark

BlindWatermark uses a fixed globalAlpha of 0.005. Its watermark is designed to be difficult to notice at normal viewing size. Decoding increases the visibility of marks in a screenshot or image, subject to the image’s color, scaling, and compression.

import { BlindWatermark } from 'watermark-js-plus';
const blindMark = new BlindWatermark({
  content: 'Review copy 1042',
  width: 220,
  height: 160,
  fontColor: '#000'
});
await blindMark.create();

Give the decoder a same-origin screenshot URL or a Data URL. It returns an enhanced PNG Data URL through onSuccess. Insert an <img id="decoded-preview" alt="Enhanced blind watermark"> element on the page to display the result.

BlindWatermark.decode({
  url: '/images/captured-preview.png',
  compositeOperation: 'color-burn',
  compositeTimes: 3,
  onSuccess: (pngDataUrl) => {
    document.querySelector('#decoded-preview').src = pngDataUrl;
  }
});

Update, Check, and Remove a Watermark

Use changeOptions() to update a displayed watermark. The 'append' mode retains previously configured options that do not appear in the new object.

await watermark.changeOptions({ content: 'Approved preview' }, 'append');
const exists = await watermark.check();
watermark.destroy();

Constructors

  • new Watermark(options): Creates a page or container watermark instance from a WatermarkOptions configuration object.
  • new ImageWatermark(options): Creates an image watermark instance. Set the dom option to an HTMLImageElement before calling create().
  • new BlindWatermark(options): Creates a blind watermark instance. The class overrides globalAlpha and mode.

All Configuration Options

Size, Layout, and Position

  • width (number, default 300): Width of a watermark tile in pixels.
  • height (number, default 300): Height of a tile in pixels.
  • rotate (number, default 45): Rotation angle in degrees.
  • layout ('default' | 'grid', default 'default'): Selects regular tiling or the matrix layout.
  • gridLayoutOptions (GridLayoutOptions | undefined, default undefined): Grid settings used by layout: 'grid'.
    • cols (number, default 1): Number of columns.
    • rows (number, default 1): Number of rows.
    • gap ([number, number], default [0, 0]): Horizontal and vertical spacing.
    • matrix (2D visibility array, default all 1s): Controls which cells draw the watermark.
    • backgroundImage (optional image): Image drawn across the grid. Supply grid width and height when using it.
    • width (number, optional): Grid Canvas width.
    • height (number, optional): Grid Canvas height. These grid dimensions do not independently change the CSS background repetition size.
  • auxiliaryLine (boolean, default false): Displays positioning guidelines.
  • translatePlacement (TranslatePlacementType, default 'middle'): Sets the content anchor and rotation center. Values: 'top', 'top-start', 'top-end', 'bottom', 'bottom-start', 'bottom-end', 'left', 'right', 'middle'.
  • translateX (number | undefined, automatic by default): Horizontal positioning offset in pixels.
  • translateY (number | undefined, automatic by default): Vertical positioning offset in pixels. Explicit coordinates require both translateX and translateY. An explicitly chosen non-middle translatePlacement takes precedence.
  • movable (boolean, default false): Animates the watermark background. Animation behavior depends on backgroundRepeat.
  • zIndex (number, default 2147483647): Stacking order of the watermark overlay.
  • parent (Element | string, default 'body'): DOM element or selector containing the watermark.

Watermark Content

  • contentType ('text' | 'image' | 'multi-line-text' | 'rich-text', default 'text'): Content rendering mode.
  • content (string, default 'hello watermark-js-plus'): Text or HTML used by the text, multiline, and rich-text modes.
  • textType ('fill' | 'stroke', default 'fill'): Filled or outlined Canvas text.

Typography

  • fontSize (string, default '20px'): Font size.
  • fontFamily (string, default 'sans-serif'): Font family.
  • fontStyle (string, default ''): Font style, for example 'italic'.
  • fontVariant (string, default ''): Font variant, for example 'small-caps'.
  • fontWeight (string, default 'normal'): Font weight.
  • fontColor (string, default '#000'): Base text color.
  • textAlign (TextAlignType | undefined, automatic by default): Horizontal text alignment. Values: 'center', 'end', 'left', 'right', 'start'. The default depends on placement and coordinates.
  • textBaseline (TextBaselineType | undefined, automatic by default): Text baseline. Values: 'top', 'bottom', 'middle', 'alphabetic', 'hanging', 'ideographic'.
  • lineHeight (number, default 30): Line height for multiline text.
  • textRowMaxWidth (number | undefined, defaults to width): Canvas maximum text width and multiline wrapping threshold.
  • letterSpacing (string, default '0px'): Character spacing.
  • wordSpacing (string, default '0px'): Space between words.

Image and Rich Text

  • image (string | undefined, default undefined): Image URL when contentType is 'image'. Remote watermark images need CORS permission.
  • imageWidth (number, default 0): Width of a watermark image. Zero permits automatic sizing based on the natural dimensions and imageHeight.
  • imageHeight (number, default 0): Height of a watermark image. Zero permits automatic sizing based on the natural dimensions and imageWidth.
  • richTextWidth (number | undefined, automatic by default): Width constraint for rich-text rendering, with a fallback to width.
  • richTextHeight (number | undefined, automatic by default): Height constraint for rich-text rendering, with a fallback to height.

Effects and Background

  • globalAlpha (number, default 0.5): Overall Canvas transparency from 0 to 1.
  • filter (string, default 'none'): Canvas filter string. Accepts url(), blur(), brightness(), contrast(), drop-shadow(), grayscale(), hue-rotate(), invert(), opacity(), saturate(), and sepia().
  • shadowStyle (Partial<CanvasShadowStyles> | undefined, default undefined): Canvas shadow properties shadowColor (string), shadowBlur (number), shadowOffsetX (number), and shadowOffsetY (number). Set shadowColor to display the shadow.
  • advancedStyle (AdvancedStyleType | undefined, default undefined): Gradient or image-pattern fill, overriding fontColor.
    • type: 'linear', 'radial', 'conic', or 'pattern'.
    • params: { x0, y0, x1, y1 } for linear gradients, { x0, y0, r0, x1, y1, r1 } for radial gradients, { startAngle, x, y } for conic gradients, or { image, repetition } for image patterns. Pattern images must be preloaded.
    • colorStops: Array of { offset, color } objects for gradient stops.
  • backgroundPosition (string, default '0 0'): CSS background position.
  • backgroundRepeat (string, default 'repeat'): CSS background repetition. Animation handling includes 'repeat', 'repeat-x', 'repeat-y', and 'no-repeat'.

Behavior and Security

  • mode ('default' | 'blind', default 'default'): Watermark mode identifier. On a regular Watermark, selecting 'blind' alone does not reduce opacity.
  • mutationObserve (boolean, default true): Watches for modifications to watermark nodes or their direct removal and attempts to recreate the watermark.
  • monitorProtection (boolean, default false): Activates protection against MutationObserver tampering. Once enabled, it cannot be turned off during the current runtime.

Callbacks

  • extraDrawFunc (Function | undefined, default undefined): Performs additional Canvas drawing operations.
  • onSuccess (Function, default () => {}): Runs after the first successful creation. Redrawing does not invoke it again until an instance is destroyed and created again.
  • onBeforeDestroy (Function, default () => {}): Runs before a watermark is removed.
  • onDestroyed (Function, default () => {}): Runs after a watermark is removed.
  • onObserveError (Function, default () => {}): Runs when DOM mutation observation fails.

ImageWatermark-Specific Options

  • dom (HTMLImageElement, required for create()): Image element receiving the generated PNG Data URL. destroy() restores the original image source.
  • crossOrigin (boolean | undefined, default undefined): When truthy, sets the image element’s crossOrigin property to 'anonymous'. The remote server must return appropriate CORS headers.

BlindWatermark-Specific Values

BlindWatermark inherits the public Watermark options and lifecycle methods. It enforces these values even if other values are supplied.

  • globalAlpha (number, fixed 0.005): Opacity for blind watermark rendering.
  • mode (string, fixed 'blind'): Blind watermark mode.

API Methods

  • create(): Creates the watermark. Returns Promise<void>. An existing matching watermark in the parent prevents duplicate creation.
  • destroy(): Removes the watermark and disconnects its observers. Invokes the destroy callbacks.
  • check(): Checks whether the watermark exists in its parent. Returns Promise<boolean>.
  • changeOptions(args = {}, mode = 'overwrite', redraw = true): Updates options and returns Promise<void>. args is Partial<WatermarkOptions>. 'overwrite' replaces previous explicit options, and 'append' merges into them. Set redraw to false to postpone recreation.

Blind Watermark Decoder Options

BlindWatermark.decode(options) processes an image and invokes onSuccess with the enhanced PNG Data URL. Canvas export needs a same-origin image or a Data URL. The decoder does not set the image’s crossOrigin property.

  • url (string, default ''): Source image URL or Data URL.
  • mode ('canvas' | 'html' | 'svg', default 'canvas'): Decoder mode. Only 'canvas' performs decoding. The other typed values are not implemented.
  • fillColor (string, default '#000'): Fill color during compositing.
  • compositeOperation (string, default 'color-burn'): Canvas compositing mode used to reveal the faint mark.
  • compositeTimes (number, default 3): Number of compositing passes. Zero and negative values skip compositing.
  • onSuccess (Function | undefined, default undefined): Callback receiving the generated PNG Data URL.

Alternatives and Related Resources

FAQs

Q: Why isn’t the watermark visible inside a custom container?
A: Check the selector and confirm the container has a positioning context. If the watermark exists but cannot be seen, inspect globalAlpha, the container dimensions, and zIndex.

Q: Why does watermarking an image fail when the image is hosted on another domain?
A: Cross-origin images can taint the Canvas and prevent PNG export. The image must load in anonymous CORS mode, and the remote server must permit the request. Set the attribute before loading the image.

Q: Can a watermark stop screenshots or prevent content theft?
A: No. Watermarks can discourage casual reuse and help identify shared copies, but browser code and DOM protection cannot prevent screenshots or deliberate removal.

Q: What happens if I call create() twice on the same container?
A: Watermark.create() skips creation when it finds a matching watermark in the parent. Call changeOptions() to redraw an existing instance with updated content or styles.

You Might Be Interested In:


Leave a Reply