TextSearch.ts 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. type TextSearchResult = {
  2. content: string
  3. quads: quad[]
  4. pageNum: number
  5. pageSearchIndex: number
  6. searchValue: string
  7. }
  8. type quad = {
  9. bottom: number
  10. left: number
  11. right: number
  12. top: number
  13. }
  14. export default class TextSearch {
  15. searchContainer: HTMLDivElement | null = null
  16. activeIndex = 0
  17. container: HTMLDivElement | null = null
  18. viewport: any
  19. scale: number = 0
  20. pageIndex: number = 0
  21. _searchResults: TextSearchResult[] = []
  22. constructor({
  23. container,
  24. viewport,
  25. scale,
  26. pageIndex,
  27. results,
  28. }: {
  29. container: HTMLDivElement,
  30. viewport: any,
  31. scale: number,
  32. pageIndex: number,
  33. results: TextSearchResult[]
  34. }) {
  35. this.container = container
  36. this.viewport = viewport
  37. this.scale = scale
  38. this.pageIndex = pageIndex
  39. this._searchResults = results
  40. if (results && results.length) {
  41. this.renderSearchResults()
  42. }
  43. }
  44. get searchResults() {
  45. return this._searchResults
  46. }
  47. set searchResults(results) {
  48. this._searchResults = results
  49. this.renderSearchResults()
  50. }
  51. setActiveSearchResult(search: TextSearchResult) {
  52. const { pageNum } = search
  53. if (search) {
  54. if (this.searchContainer) {
  55. const searchEles = this.searchContainer.querySelectorAll('.searchItems')
  56. searchEles[search.pageSearchIndex].classList.add('selected')
  57. }
  58. this.activeIndex = pageNum - 1
  59. }
  60. }
  61. clearActiveSearchResult(result: TextSearchResult) {
  62. if (this.searchContainer) {
  63. const index = result.pageSearchIndex
  64. const searchEle = this.searchContainer.querySelectorAll('.searchItems')[index]
  65. searchEle.classList.remove('selected')
  66. }
  67. }
  68. renderSearchResults() {
  69. const scale = this.scale
  70. if (!this.searchContainer) {
  71. const searchContainer = document.createElement('div')
  72. searchContainer.className = 'searchContainer'
  73. this.container!.appendChild(searchContainer)
  74. this.searchContainer = searchContainer
  75. }
  76. this.searchContainer.textContent = ''
  77. for (let i = 0; i < this.searchResults.length; i++) {
  78. if (this.searchResults[i].pageNum !== this.pageIndex + 1) {
  79. continue
  80. }
  81. const result = this.searchResults[i]
  82. const searchItems = document.createElement('div')
  83. searchItems.className = 'searchItems'
  84. for (let j = 0; j < result.quads.length; j++) {
  85. const { left, top, right, bottom } = result.quads[j]
  86. const bounds = {
  87. left: left * scale,
  88. top: top * scale,
  89. width: right * scale - left * scale,
  90. height: bottom * scale - top * scale
  91. }
  92. const div = document.createElement('div')
  93. div.className = 'highlight'
  94. div.style.position = 'absolute'
  95. div.style.left = `${bounds.left}px`
  96. div.style.top = `${bounds.top}px`
  97. div.style.width = `${bounds.width}px`
  98. div.style.height = `${bounds.height}px`
  99. searchItems.appendChild(div)
  100. }
  101. this.searchContainer!.appendChild(searchItems)
  102. }
  103. }
  104. destroy() {
  105. if (this.searchContainer) {
  106. this.searchContainer.parentNode!.removeChild(this.searchContainer)
  107. this.searchContainer = null
  108. }
  109. }
  110. }