// Viewer instance: Represents the PDF viewer instance used for document rendering and interaction.
var viewer;
// Initialize an array to store search results: Keeps track of search results for further processing or display.
var searchResults = [];
// Execute code when the window has fully loaded:
window.onload = async function () {
//DsPdfViewer.LicenseKey = "***key***";
viewer = new DsPdfViewer('#viewer', { restoreViewStateOnLoad: false });
viewer.addDefaultPanels();
var pdf = "/document-solutions/javascript-pdf-viewer/demos/product-bundles/assets/pdf/wetlands.pdf";
// Open the document and set the zoom mode to 1 (Fit Width):
await viewer.open(pdf);
viewer.zoom = { mode: 1 };
// Specify search options to find the text 'wetlands' with case sensitivity:
var findOptions = { Text: 'wetlands', MatchCase: true };
// Perform the search using the Search API:
var searchIterator = await viewer.searcher.search(findOptions);
// Iterate through search results and populate the searchResults array:
var searchResult = await searchIterator.next();
while (!searchResult.done) {
searchResults.push(searchResult);
searchResult = await searchIterator.next();
}
// Call the paintPopups function to render popups above search results:
paintPopups();
viewer.scrollView.addEventListener("pointerdown", paintPopups);
viewer.scrollView.addEventListener("pointerup", () => setTimeout(paintPopups));
viewer.scrollView.addEventListener("scroll", paintPopups);
window.addEventListener("resize", () => setTimeout(paintPopups));
}
// Function to render popup elements above search results.
function paintPopups() {
removeAllRectangles();
for (let i = 0; i < searchResults.length; i++) {
const searchResultValue = searchResults[i].value;
createRectangle(viewer.convertPdfRectToWindowCoordinates(searchResultValue.PageIndex, searchResultValue.ItemArea), searchResultValue.DisplayText);
}
}
// Function to create a rectangle with a wavy border
function createRectangle(rect, displayText) {
const waveBorder = document.createElement('div');
const animatedWave = document.createElement('div');
waveBorder.className = 'wave-border';
animatedWave.className = 'animated-wave';
const [x1, y1, x2, y2] = rect;
const width = x2 - x1;
const height = y2 - y1;
waveBorder.style.left = x1 + 'px';
waveBorder.style.top = y1 + 'px';
waveBorder.style.width = width + 'px';
waveBorder.style.height = height + 'px';
waveBorder.title = "Display text: " + displayText;
document.body.appendChild(waveBorder);
waveBorder.appendChild(animatedWave);
}
// Function to remove all previously added rectangles
function removeAllRectangles() {
const waveBorders = document.querySelectorAll('.wave-border');
waveBorders.forEach((waveBorder) => {
waveBorder.remove();
});
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Using Search API from Code</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./src/styles.css">
<script src="/document-solutions/javascript-pdf-viewer/demos/product-bundles/build/dspdfviewer.js"></script>
<script src="/document-solutions/javascript-pdf-viewer/demos/product-bundles/build/wasmSupportApi.js"></script>
<script src="/document-solutions/javascript-pdf-viewer/demos/resource/js/init.js"></script>
<script src="./src/app.js"></script>
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
</head>
<body>
<div id="viewer"></div>
</body>
</html>
#viewer {
height: 100%;
}
.wave-border {
position: absolute;
overflow: hidden;
background-color: orange;
border: 1px solid rgb(219, 127, 6);
opacity: 0.2;
cursor: pointer;
}
.animated-wave {
position: absolute;
width: 100%;
height: 100%;
clip-path: inset(0 75% 0 0);
animation: wave-animation 1s infinite ease-in-out;
background: yellow;
opacity: 0.7;
z-index: 0;
}
@keyframes wave-animation {
0% { clip-path: inset(0 75% 0 0); }
to { clip-path: inset(0 0 0 75%); }
}
body {
overflow: hidden;
}