|
3 | 3 | <head> |
4 | 4 | <title>Overlay WebPage</title> |
5 | 5 | <style> |
6 | | - body { |
7 | | - background: transparent; |
| 6 | + .film-overlay { |
| 7 | + position: fixed; |
| 8 | + top: 10px; |
| 9 | + left: 10px; |
| 10 | + display: flex; |
| 11 | + flex-direction: row; |
| 12 | + align-items: center; |
| 13 | + justify-content: space-between; |
| 14 | + padding: 10px; |
| 15 | + background-color: rgba(0, 0, 0, 0.5); |
| 16 | + } |
| 17 | + .overlay-text { |
| 18 | + color: white; |
| 19 | + font-family: Arial, sans-serif; |
| 20 | + font-size: 1vw; |
| 21 | + flex-grow: 1; |
| 22 | + white-space: pre-wrap; |
| 23 | + overflow: hidden; |
| 24 | + word-break: break-all; |
| 25 | + } |
| 26 | + .overlay-resizer { |
| 27 | + width: 10px; |
| 28 | + height: 10px; |
| 29 | + background: red; |
| 30 | + position: absolute; |
| 31 | + top: 0; |
| 32 | + left: 0; |
| 33 | + cursor: se-resize; |
| 34 | + } |
| 35 | + .detach-button { |
| 36 | + position: absolute; |
| 37 | + top: 0px; |
| 38 | + right: 0px; |
| 39 | + padding: 2px 5px; |
| 40 | + background-color: white; |
| 41 | + color: black; |
| 42 | + border: none; |
| 43 | + cursor: pointer; |
8 | 44 | } |
9 | 45 | </style> |
10 | 46 | </head> |
11 | 47 | <body> |
12 | | - |
| 48 | + |
| 49 | + <button id="toggle-button" style="position: fixed; top: 10px; right: 10px; z-index: 9999;">Overlay</button> |
| 50 | + |
13 | 51 | <script> |
14 | | -// Create overlay element |
15 | | -const filmOverlay = document.createElement('div'); |
16 | | -filmOverlay.classList.add('film-overlay'); |
17 | | -filmOverlay.style.position = 'fixed'; |
18 | | -filmOverlay.style.top = '10px'; |
19 | | -filmOverlay.style.left = '10px'; |
20 | | -filmOverlay.style.display = 'none'; |
21 | | -filmOverlay.style.flexDirection = 'row'; |
22 | | -filmOverlay.style.alignItems = 'center'; |
23 | | -filmOverlay.style.justifyContent = 'space-between'; |
24 | | -filmOverlay.style.padding = '10px'; |
25 | | -filmOverlay.style.backgroundColor = 'rgba(0, 0, 0, 0.5)'; |
26 | | - |
27 | | -// Create resizer element |
28 | | -const resizer = document.createElement('div'); |
29 | | -resizer.style.width = '10px'; |
30 | | -resizer.style.height = '10px'; |
31 | | -resizer.style.background = 'red'; |
32 | | -resizer.style.position = 'absolute'; |
33 | | -resizer.style.top = '0'; |
34 | | -resizer.style.left = '0'; |
35 | | -resizer.style.cursor = 'se-resize'; |
36 | | - |
37 | | -// Create green dot element |
38 | | -const dot = document.createElement('div'); |
39 | | -dot.style.width = '10px'; |
40 | | -dot.style.height = '10px'; |
41 | | -dot.style.backgroundColor = 'green'; |
42 | | -dot.style.borderRadius = '50%'; |
43 | | -dot.style.marginRight = '5px'; |
44 | | - |
45 | | -// Create text element |
46 | | -const text = document.createElement('pre'); |
47 | | -text.style.color = 'white'; |
48 | | -text.style.fontFamily = 'Arial, sans-serif'; |
49 | | -text.style.fontSize = '1vw'; // The font size is 1% of the viewport's width |
50 | | -text.style.flexGrow = '1'; |
51 | | -text.style.whiteSpace = 'pre-wrap'; // Preserve whitespace and line breaks |
52 | | -text.style.overflow = 'hidden'; // Hide overflowing content |
53 | | -text.style.wordBreak = 'break-all'; // Break long words |
54 | | - |
55 | | -// Create toggle button |
56 | | -const toggleButton = document.createElement('button'); |
57 | | -toggleButton.textContent = 'Overlay'; |
58 | | -toggleButton.style.marginLeft = '10px'; |
59 | | -toggleButton.style.padding = '5px 10px'; |
60 | | -toggleButton.style.backgroundColor = 'gray'; |
61 | | -toggleButton.style.color = 'white'; |
62 | | -toggleButton.style.border = 'none'; |
63 | | -toggleButton.style.borderRadius = '4px'; |
64 | | -toggleButton.style.position = 'fixed'; |
65 | | -toggleButton.style.top = '10px'; |
66 | | -toggleButton.style.right = '10px'; |
67 | | -toggleButton.style.zIndex = '9999'; |
68 | | - |
69 | | -// Create fit button |
70 | | -const fitButton = document.createElement('button'); |
71 | | -fitButton.textContent = 'Fit to Tab'; |
72 | | -fitButton.style.marginLeft = '10px'; |
73 | | -fitButton.style.padding = '5px 10px'; |
74 | | -fitButton.style.backgroundColor = 'gray'; |
75 | | -fitButton.style.color = 'white'; |
76 | | -fitButton.style.border = 'none'; |
77 | | -fitButton.style.borderRadius = '4px'; |
78 | | -fitButton.style.position = 'fixed'; |
79 | | -fitButton.style.top = '50px'; |
80 | | -fitButton.style.right = '10px'; |
81 | | -fitButton.style.zIndex = '9999'; |
82 | | - |
83 | | -// Variables for storing the current position and the mouse offset |
84 | | -let drag = false; |
85 | | -let currentX; |
86 | | -let currentY; |
87 | | -let offsetX; |
88 | | -let offsetY; |
89 | | -let isResizing = false; |
90 | | -let scale = 1; |
91 | | - |
92 | | -// mousedown event for dragging |
93 | | -filmOverlay.addEventListener('mousedown', function (e) { |
94 | | - if (e.shiftKey) { |
95 | | - offsetX = e.clientX - parseInt(window.getComputedStyle(this).left); |
96 | | - offsetY = e.clientY - parseInt(window.getComputedStyle(this).top); |
97 | | - drag = true; |
98 | | - } |
99 | | -}); |
100 | | - |
101 | | -// mousedown event for resizing |
102 | | -resizer.addEventListener('mousedown', function (e) { |
103 | | - isResizing = true; |
104 | | -}); |
105 | | - |
106 | | -// mousemove event for dragging and resizing |
107 | | -window.addEventListener('mousemove', function (e) { |
108 | | - e.preventDefault(); |
109 | | - if (drag) { |
110 | | - currentX = e.clientX - offsetX; |
111 | | - currentY = e.clientY - offsetY; |
112 | | - filmOverlay.style.left = currentX + 'px'; |
113 | | - filmOverlay.style.top = currentY + 'px'; |
114 | | - } else if (isResizing) { |
115 | | - let newWidth = e.pageX - filmOverlay.offsetLeft; |
116 | | - let newHeight = e.pageY - filmOverlay.offsetTop; |
117 | | - filmOverlay.style.width = newWidth + 'px'; |
118 | | - filmOverlay.style.height = newHeight + 'px'; |
119 | | - text.style.transform = `scale(${scale})`; |
120 | | - adjustTextSize(); |
121 | | - } |
122 | | -}); |
123 | | - |
124 | | -// mouseup event for dragging and resizing |
125 | | -window.addEventListener('mouseup', function () { |
126 | | - drag = false; |
127 | | - isResizing = false; |
128 | | -}); |
129 | | - |
130 | | -// mousewheel event for zooming |
131 | | -filmOverlay.addEventListener('mousewheel', function (e) { |
132 | | - e.preventDefault(); |
133 | | - const zoomSpeed = 0.1; |
134 | | - scale += e.deltaY > 0 ? -zoomSpeed : zoomSpeed; |
135 | | - scale = Math.max(scale, 0.1); // Minimum scale |
136 | | - filmOverlay.style.transform = `scale(${scale})`; |
137 | | - adjustTextSize(); |
138 | | -}); |
139 | | - |
140 | | -// fit button click event |
141 | | -fitButton.addEventListener('click', function () { |
142 | | - const tabWidth = window.innerWidth; |
143 | | - const tabHeight = window.innerHeight; |
144 | | - filmOverlay.style.width = tabWidth + 'px'; |
145 | | - filmOverlay.style.height = tabHeight + 'px'; |
146 | | - text.style.transform = `scale(${scale})`; |
147 | | - adjustTextSize(); |
148 | | -}); |
149 | | - |
150 | | -// Append elements |
151 | | -filmOverlay.appendChild(dot); |
152 | | -filmOverlay.appendChild(text); |
153 | | -filmOverlay.appendChild(resizer); |
154 | | -toggleButton.addEventListener('click', async function toggleOverlay() { |
155 | | - if (filmOverlay.style.display === 'none') { |
156 | | - try { |
157 | | - const copiedCode = await navigator.clipboard.readText(); |
158 | | - text.textContent = copiedCode; |
159 | | - filmOverlay.style.display = 'flex'; |
160 | | - adjustTextSize(); |
161 | | - } catch (error) { |
162 | | - console.log('Failed to read clipboard:', error); |
| 52 | + const toggleButton = document.querySelector('#toggle-button'); |
| 53 | + let pinnedOverlays = []; |
| 54 | + |
| 55 | + toggleButton.addEventListener('click', async function () { |
| 56 | + try { |
| 57 | + const copiedCode = await navigator.clipboard.readText(); |
| 58 | + |
| 59 | + // Create overlay for each click |
| 60 | + const filmOverlay = createOverlay(); |
| 61 | + const text = filmOverlay.querySelector('.overlay-text'); |
| 62 | + const resizer = filmOverlay.querySelector('.overlay-resizer'); |
| 63 | + const detachButton = filmOverlay.querySelector('.detach-button'); |
| 64 | + |
| 65 | + // Add text |
| 66 | + text.textContent = copiedCode; |
| 67 | + |
| 68 | + // Add listeners to the overlay |
| 69 | + addOverlayListeners(filmOverlay, text, resizer); |
| 70 | + |
| 71 | + // Append to parent container |
| 72 | + document.body.appendChild(filmOverlay); |
| 73 | + |
| 74 | + detachButton.addEventListener('click', function () { |
| 75 | + detachOverlay(filmOverlay); |
| 76 | + }); |
| 77 | + } catch (error) { |
| 78 | + console.log('Failed to read clipboard:', error); |
| 79 | + } |
| 80 | + }); |
| 81 | + |
| 82 | + function createOverlay() { |
| 83 | + // Create overlay element |
| 84 | + const filmOverlay = document.createElement('div'); |
| 85 | + filmOverlay.classList.add('film-overlay'); |
| 86 | + |
| 87 | + // Create text element |
| 88 | + const text = document.createElement('pre'); |
| 89 | + text.classList.add('overlay-text'); |
| 90 | + |
| 91 | + // Create resizer element |
| 92 | + const resizer = document.createElement('div'); |
| 93 | + resizer.classList.add('overlay-resizer'); |
| 94 | + |
| 95 | + // Create detach button |
| 96 | + const detachButton = document.createElement('button'); |
| 97 | + detachButton.textContent = 'Pin'; |
| 98 | + detachButton.classList.add('detach-button'); |
| 99 | + |
| 100 | + // Append elements |
| 101 | + filmOverlay.appendChild(text); |
| 102 | + filmOverlay.appendChild(resizer); |
| 103 | + filmOverlay.appendChild(detachButton); |
| 104 | + |
| 105 | + return filmOverlay; |
163 | 106 | } |
164 | | - } else { |
165 | | - filmOverlay.style.display = 'none'; |
166 | | - } |
167 | | -}); |
168 | | - |
169 | | -// Append to body |
170 | | -const parentContainer = document.querySelector('body'); |
171 | | -parentContainer.appendChild(filmOverlay); |
172 | | -parentContainer.appendChild(toggleButton); |
173 | | -parentContainer.appendChild(fitButton); |
174 | | - |
175 | | -// Adjust text size to fit container |
176 | | -function adjustTextSize() { |
177 | | - const containerWidth = filmOverlay.offsetWidth; |
178 | | - const containerHeight = filmOverlay.offsetHeight; |
179 | | - const textWidth = text.offsetWidth; |
180 | | - const textHeight = text.offsetHeight; |
181 | | - const scaleX = containerWidth / textWidth; |
182 | | - const scaleY = containerHeight / textHeight; |
183 | | - const finalScale = Math.min(scaleX, scaleY); |
184 | | - text.style.transform = `scale(${finalScale})`; |
185 | | -} |
186 | | - |
187 | | -// Scale the font size initially and whenever the window is resized |
188 | | -adjustTextSize(); |
189 | | -window.addEventListener('resize', adjustTextSize); |
190 | 107 |
|
| 108 | + function addOverlayListeners(filmOverlay, text, resizer) { |
| 109 | + // Variables for storing the current position and the mouse offset |
| 110 | + let drag = false; |
| 111 | + let currentX; |
| 112 | + let currentY; |
| 113 | + let offsetX; |
| 114 | + let offsetY; |
| 115 | + let isResizing = false; |
| 116 | + let scale = 1; |
| 117 | + |
| 118 | + // mousedown event for dragging |
| 119 | + filmOverlay.addEventListener('mousedown', function (e) { |
| 120 | + if (e.shiftKey) { |
| 121 | + offsetX = e.clientX - parseInt(window.getComputedStyle(this).left); |
| 122 | + offsetY = e.clientY - parseInt(window.getComputedStyle(this).top); |
| 123 | + drag = true; |
| 124 | + } |
| 125 | + }); |
| 126 | + |
| 127 | + // mousedown event for resizing |
| 128 | + resizer.addEventListener('mousedown', function (e) { |
| 129 | + isResizing = true; |
| 130 | + }); |
| 131 | + |
| 132 | + // mousemove event for dragging and resizing |
| 133 | + window.addEventListener('mousemove', function (e) { |
| 134 | + e.preventDefault(); |
| 135 | + if (drag) { |
| 136 | + currentX = e.clientX - offsetX; |
| 137 | + currentY = e.clientY - offsetY; |
| 138 | + filmOverlay.style.left = currentX + 'px'; |
| 139 | + filmOverlay.style.top = currentY + 'px'; |
| 140 | + } else if (isResizing) { |
| 141 | + let newWidth = e.pageX - filmOverlay.offsetLeft; |
| 142 | + let newHeight = e.pageY - filmOverlay.offsetTop; |
| 143 | + filmOverlay.style.width = newWidth + 'px'; |
| 144 | + filmOverlay.style.height = newHeight + 'px'; |
| 145 | + text.style.transform = `scale(${scale})`; |
| 146 | + adjustTextSize(filmOverlay, text); |
| 147 | + } |
| 148 | + }); |
| 149 | + |
| 150 | + // mouseup event for dragging and resizing |
| 151 | + window.addEventListener('mouseup', function () { |
| 152 | + drag = false; |
| 153 | + isResizing = false; |
| 154 | + }); |
| 155 | + |
| 156 | + // mousewheel event for zooming |
| 157 | + filmOverlay.addEventListener('mousewheel', function (e) { |
| 158 | + e.preventDefault(); |
| 159 | + const zoomSpeed = 0.1; |
| 160 | + scale += e.deltaY > 0 ? -zoomSpeed : zoomSpeed; |
| 161 | + scale = Math.max(scale, 0.1); // Minimum scale |
| 162 | + filmOverlay.style.transform = `scale(${scale})`; |
| 163 | + adjustTextSize(filmOverlay, text); |
| 164 | + }); |
| 165 | + |
| 166 | + // Adjust text size initially and whenever the window is resized |
| 167 | + adjustTextSize(filmOverlay, text); |
| 168 | + window.addEventListener('resize', () => adjustTextSize(filmOverlay, text)); |
| 169 | + } |
191 | 170 |
|
| 171 | + function adjustTextSize(filmOverlay, text) { |
| 172 | + const containerWidth = filmOverlay.offsetWidth; |
| 173 | + const containerHeight = filmOverlay.offsetHeight; |
| 174 | + const textWidth = text.offsetWidth; |
| 175 | + const textHeight = text.offsetHeight; |
| 176 | + const scaleX = containerWidth / textWidth; |
| 177 | + const scaleY = containerHeight / textHeight; |
| 178 | + const finalScale = Math.min(scaleX, scaleY); |
| 179 | + text.style.transform = `scale(${finalScale})`; |
| 180 | + } |
| 181 | + |
| 182 | + function detachOverlay(filmOverlay) { |
| 183 | + // Remove event listeners |
| 184 | + filmOverlay.removeEventListener('mousedown'); |
| 185 | + filmOverlay.removeEventListener('mouseup'); |
| 186 | + window.removeEventListener('mousemove'); |
| 187 | + filmOverlay.removeEventListener('mousewheel'); |
| 188 | + window.removeEventListener('resize'); |
| 189 | + |
| 190 | + // Remove detach button |
| 191 | + const detachButton = filmOverlay.querySelector('.detach-button'); |
| 192 | + detachButton.parentNode.removeChild(detachButton); |
| 193 | + |
| 194 | + // Add overlay to pinnedOverlays array |
| 195 | + pinnedOverlays.push(filmOverlay); |
| 196 | + } |
192 | 197 | </script> |
193 | 198 | </body> |
194 | 199 | </html> |
|
0 commit comments