Skip to content

Commit e7f36b4

Browse files
fix: adds missing custom-overlay examples
1 parent 6e401a7 commit e7f36b4

File tree

3 files changed

+325
-0
lines changed

3 files changed

+325
-0
lines changed
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/**
2+
* Custom Overlays Implementation for Next.js (TypeScript)
3+
*
4+
* This example demonstrates advanced Nutrient Web SDK features:
5+
* - Custom overlay items that appear on page clicks
6+
* - Interactive overlays with HTML content
7+
* - Event handling for page interactions
8+
* - Dynamic overlay positioning
9+
*/
10+
11+
import type NutrientViewer from "@nutrient-sdk/viewer";
12+
import type { Configuration } from "@nutrient-sdk/viewer";
13+
14+
/**
15+
* Load a PDF viewer with custom overlays functionality
16+
* @param nutrientViewer - The NutrientViewer object (from CDN)
17+
* @param container - The container element to mount the viewer
18+
* @param document - URL to the PDF document
19+
* @returns Promise that resolves when the viewer is loaded
20+
*/
21+
export async function loadCustomOverlaysViewer(
22+
nutrientViewer: typeof NutrientViewer,
23+
container: HTMLElement,
24+
document = "https://www.nutrient.io/downloads/nutrient-web-demo.pdf",
25+
) {
26+
if (!nutrientViewer) {
27+
throw new Error("NutrientViewer is required");
28+
}
29+
30+
// Ensure there's only one NutrientViewer instance
31+
nutrientViewer.unload(container);
32+
33+
// Load the viewer with custom overlays configuration
34+
return load(nutrientViewer, {
35+
container,
36+
document,
37+
});
38+
}
39+
40+
/**
41+
* Internal load function with custom overlays configuration
42+
* @param nutrientViewer - The NutrientViewer object
43+
* @param defaultConfiguration - Base configuration object
44+
*/
45+
function load(
46+
nutrientViewer: NonNullable<typeof window.NutrientViewer>,
47+
defaultConfiguration: Configuration,
48+
) {
49+
return nutrientViewer.load(defaultConfiguration).then((instance) => {
50+
console.log("Nutrient Web SDK successfully loaded!!", instance);
51+
52+
// Every time a user clicks on the page, we show a custom overlay item on
53+
// this page.
54+
instance.addEventListener("page.press", (event) => {
55+
if (event.pageIndex === 0) {
56+
instance.setCustomOverlayItem(getOverlayItemForPage1(nutrientViewer));
57+
}
58+
59+
if (event.pageIndex === 1) {
60+
instance.setCustomOverlayItem(getOverlayItemForPage2(nutrientViewer));
61+
}
62+
});
63+
64+
return instance;
65+
});
66+
}
67+
68+
function getOverlayItemForPage1(
69+
nutrientViewer: NonNullable<typeof window.NutrientViewer>,
70+
) {
71+
// We create a div element with an emoji and a short text.
72+
const overlayElement = document.createElement("div");
73+
74+
overlayElement.style.cssText =
75+
"width: 300px;background: #FFF; border: 1px #333 solid; font-family: sans-serif; font-size: 14px; padding: 20px;";
76+
overlayElement.innerHTML =
77+
"<p>👋 This is an overlay item that appears when clicking on the first page. Find out what happens when you click on the second page.";
78+
79+
// Then we return a NutrientViewer.CustomOverlayItem which uses the overlayElement
80+
// that we created above as a node, the pageIndex we get from our onPress
81+
// event and define the position on the page.
82+
return new nutrientViewer.CustomOverlayItem({
83+
id: "overlay-item-first-page",
84+
node: overlayElement,
85+
pageIndex: 0,
86+
position: new nutrientViewer.Geometry.Point({ x: 300, y: 50 }),
87+
});
88+
}
89+
90+
function getOverlayItemForPage2(
91+
nutrientViewer: NonNullable<typeof window.NutrientViewer>,
92+
) {
93+
const overlayElement = document.createElement("div");
94+
95+
// In this case we embed a video to the page
96+
overlayElement.innerHTML =
97+
'<iframe src="https://player.vimeo.com/video/227250697" width="500" height="360" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>';
98+
99+
// Then we return a NutrientViewer.CustomOverlayItem which uses the overlayElement
100+
// that we created above as a node, the pageIndex we get from our onPress
101+
// event and define the position on the page.
102+
return new nutrientViewer.CustomOverlayItem({
103+
id: "overlay-item-second-page",
104+
node: overlayElement,
105+
pageIndex: 1,
106+
position: new nutrientViewer.Geometry.Point({ x: 55, y: 220 }),
107+
});
108+
}
109+
110+
/**
111+
* Unload the custom overlays viewer from a container
112+
* @param nutrientViewer - The NutrientViewer object (from CDN)
113+
* @param container - The container element
114+
*/
115+
export async function unloadCustomOverlaysViewer(
116+
nutrientViewer: typeof NutrientViewer,
117+
container: HTMLElement,
118+
) {
119+
if (nutrientViewer) {
120+
nutrientViewer.unload(container);
121+
}
122+
}
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/**
2+
* Custom Overlays Implementation (TypeScript)
3+
*
4+
* This example demonstrates advanced Nutrient Web SDK features:
5+
* - Custom overlay items that appear on page clicks
6+
* - Interactive overlays with HTML content
7+
* - Event handling for page interactions
8+
* - Dynamic overlay positioning
9+
* Framework implementations should import this and call loadCustomOverlaysViewer() with their container element.
10+
*/
11+
12+
import type NutrientViewer from "@nutrient-sdk/viewer";
13+
import type { Configuration } from "@nutrient-sdk/viewer";
14+
15+
/**
16+
* Load a PDF viewer with custom overlays functionality
17+
* @param nutrientViewer - The NutrientViewer object (from CDN)
18+
* @param container - The container element to mount the viewer
19+
* @param document - URL to the PDF document
20+
* @returns Promise that resolves when the viewer is loaded
21+
*/
22+
export async function loadCustomOverlaysViewer(
23+
nutrientViewer: typeof NutrientViewer,
24+
container: HTMLElement,
25+
document = "https://www.nutrient.io/downloads/nutrient-web-demo.pdf",
26+
) {
27+
if (!nutrientViewer) {
28+
throw new Error("NutrientViewer is required");
29+
}
30+
31+
// Ensure there's only one NutrientViewer instance
32+
nutrientViewer.unload(container);
33+
34+
// Load the viewer with custom overlays configuration
35+
return load(nutrientViewer, {
36+
container,
37+
document,
38+
});
39+
}
40+
41+
/**
42+
* Internal load function with custom overlays configuration
43+
* @param nutrientViewer - The NutrientViewer object
44+
* @param defaultConfiguration - Base configuration object
45+
*/
46+
function load(
47+
nutrientViewer: NonNullable<typeof window.NutrientViewer>,
48+
defaultConfiguration: Configuration,
49+
) {
50+
return nutrientViewer.load(defaultConfiguration).then((instance) => {
51+
console.log("Nutrient Web SDK successfully loaded!!", instance);
52+
53+
// Every time a user clicks on the page, we show a custom overlay item on
54+
// this page.
55+
instance.addEventListener("page.press", (event) => {
56+
if (event.pageIndex === 0) {
57+
instance.setCustomOverlayItem(getOverlayItemForPage1(nutrientViewer));
58+
}
59+
60+
if (event.pageIndex === 1) {
61+
instance.setCustomOverlayItem(getOverlayItemForPage2(nutrientViewer));
62+
}
63+
});
64+
65+
return instance;
66+
});
67+
}
68+
69+
function getOverlayItemForPage1(
70+
nutrientViewer: NonNullable<typeof window.NutrientViewer>,
71+
) {
72+
// We create a div element with an emoji and a short text.
73+
const overlayElement = document.createElement("div");
74+
75+
overlayElement.style.cssText =
76+
"width: 300px;background: #FFF; border: 1px #333 solid; font-family: sans-serif; font-size: 14px; padding: 20px;";
77+
overlayElement.innerHTML =
78+
"<p>👋 This is an overlay item that appears when clicking on the first page. Find out what happens when you click on the second page.";
79+
80+
// Then we return a NutrientViewer.CustomOverlayItem which uses the overlayElement
81+
// that we created above as a node, the pageIndex we get from our onPress
82+
// event and define the position on the page.
83+
return new nutrientViewer.CustomOverlayItem({
84+
id: "overlay-item-first-page",
85+
node: overlayElement,
86+
pageIndex: 0,
87+
position: new nutrientViewer.Geometry.Point({ x: 300, y: 50 }),
88+
});
89+
}
90+
91+
function getOverlayItemForPage2(
92+
nutrientViewer: NonNullable<typeof window.NutrientViewer>,
93+
) {
94+
const overlayElement = document.createElement("div");
95+
96+
// In this case we embed a video to the page
97+
overlayElement.innerHTML =
98+
'<iframe src="https://player.vimeo.com/video/227250697" width="500" height="360" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>';
99+
100+
// Then we return a NutrientViewer.CustomOverlayItem which uses the overlayElement
101+
// that we created above as a node, the pageIndex we get from our onPress
102+
// event and define the position on the page.
103+
return new nutrientViewer.CustomOverlayItem({
104+
id: "overlay-item-second-page",
105+
node: overlayElement,
106+
pageIndex: 1,
107+
position: new nutrientViewer.Geometry.Point({ x: 55, y: 220 }),
108+
});
109+
}
110+
111+
/**
112+
* Unload the custom overlays viewer from a container
113+
* @param nutrientViewer - The NutrientViewer object (from CDN)
114+
* @param container - The container element
115+
*/
116+
export async function unloadCustomOverlaysViewer(
117+
nutrientViewer: typeof NutrientViewer,
118+
container: HTMLElement,
119+
) {
120+
if (nutrientViewer) {
121+
nutrientViewer.unload(container);
122+
}
123+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<template>
2+
<div class="page-container">
3+
<nav class="nav-bar">
4+
<NuxtLink to="/" class="back-link">
5+
← Back to Examples
6+
</NuxtLink>
7+
<h2 class="page-title">Custom Overlays</h2>
8+
<span class="page-description">
9+
Interactive overlays that appear on page clicks
10+
</span>
11+
</nav>
12+
13+
<div ref="containerRef" class="viewer-container" />
14+
</div>
15+
</template>
16+
17+
<script setup lang="ts">
18+
import {
19+
loadCustomOverlaysViewer,
20+
unloadCustomOverlaysViewer,
21+
} from "~/examples/custom-overlays/implementation";
22+
23+
const containerRef = ref<HTMLDivElement | null>(null);
24+
25+
onMounted(() => {
26+
const container = containerRef.value;
27+
const { NutrientViewer } = window;
28+
29+
if (container && NutrientViewer) {
30+
loadCustomOverlaysViewer(NutrientViewer, container);
31+
}
32+
});
33+
34+
onUnmounted(() => {
35+
const container = containerRef.value;
36+
const { NutrientViewer } = window;
37+
38+
if (NutrientViewer && container) {
39+
unloadCustomOverlaysViewer(NutrientViewer, container);
40+
}
41+
});
42+
</script>
43+
44+
<style scoped>
45+
.page-container {
46+
height: 100vh;
47+
display: flex;
48+
flex-direction: column;
49+
}
50+
51+
.nav-bar {
52+
padding: 1rem;
53+
background-color: #f5f5f5;
54+
border-bottom: 1px solid #ddd;
55+
display: flex;
56+
align-items: center;
57+
gap: 1rem;
58+
}
59+
60+
.back-link {
61+
text-decoration: none;
62+
color: #4a8fed;
63+
font-size: 0.9rem;
64+
}
65+
66+
.page-title {
67+
margin: 0;
68+
font-size: 1.1rem;
69+
}
70+
71+
.page-description {
72+
font-size: 0.9rem;
73+
color: #666;
74+
}
75+
76+
.viewer-container {
77+
flex: 1;
78+
width: 100%;
79+
}
80+
</style>

0 commit comments

Comments
 (0)