mirror of
https://github.com/QL-Win/QuickLook.git
synced 2025-09-12 02:09:05 +00:00
Add JSDoc comments and clarify SvgViewer usage
This commit is contained in:
@@ -1,12 +1,23 @@
|
|||||||
// SvgViewer: Provides SVG preview with the following features:
|
/**
|
||||||
// - Fit SVG to window with no upscaling
|
* SvgViewer: Provides SVG preview with the following features.
|
||||||
// - Mouse wheel zoom in/out (with smooth animation)
|
*
|
||||||
// - Double-click to fit SVG to window
|
* Requirements:
|
||||||
// - Mouse drag to pan (only when SVG is larger than the container)
|
* - Requires the following HTML structure:
|
||||||
// - Pan is limited to visible overflow area
|
* <div id="svgContainer">
|
||||||
// - Handles SVGs with or without width/height/viewBox attributes
|
* <div id="svgWrapper"></div>
|
||||||
// - Resets pan on zoom or fit
|
* </div>
|
||||||
// - No animation during pan, smooth animation during zoom/fit
|
* - SVG content is obtained via chrome.webview.hostObjects.external.GetSvgContent()
|
||||||
|
*
|
||||||
|
* Features:
|
||||||
|
* - Fit SVG to window with no upscaling
|
||||||
|
* - Mouse wheel zoom in/out (with smooth animation)
|
||||||
|
* - Double-click to fit SVG to window
|
||||||
|
* - Mouse drag to pan (only when SVG is larger than the container)
|
||||||
|
* - Pan is limited to visible overflow area
|
||||||
|
* - Handles SVGs with or without width/height/viewBox attributes
|
||||||
|
* - Resets pan on zoom or fit
|
||||||
|
* - No animation during pan, smooth animation during zoom/fit
|
||||||
|
*/
|
||||||
class SvgViewer {
|
class SvgViewer {
|
||||||
constructor() {
|
constructor() {
|
||||||
// Initial scale and scale limits
|
// Initial scale and scale limits
|
||||||
@@ -33,7 +44,10 @@ class SvgViewer {
|
|||||||
this.lastMouseY = 0;
|
this.lastMouseY = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure SVG has proper size attributes and extract viewBox dimensions
|
/**
|
||||||
|
* Ensure SVG has proper size attributes and extract viewBox dimensions.
|
||||||
|
* @param {SVGElement} svgElement The SVG element to fix.
|
||||||
|
*/
|
||||||
fixSvgSize(svgElement) {
|
fixSvgSize(svgElement) {
|
||||||
let widthAttr = svgElement.getAttribute('width');
|
let widthAttr = svgElement.getAttribute('width');
|
||||||
let heightAttr = svgElement.getAttribute('height');
|
let heightAttr = svgElement.getAttribute('height');
|
||||||
@@ -71,7 +85,10 @@ class SvgViewer {
|
|||||||
this.viewBoxHeight = viewBoxHeight;
|
this.viewBoxHeight = viewBoxHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the base scale to fit SVG into the container
|
/**
|
||||||
|
* Calculate the base scale to fit SVG into the container.
|
||||||
|
* @returns {number} The base scale factor.
|
||||||
|
*/
|
||||||
computeBaseScale() {
|
computeBaseScale() {
|
||||||
if (!this.viewBoxWidth || !this.viewBoxHeight) return 1;
|
if (!this.viewBoxWidth || !this.viewBoxHeight) return 1;
|
||||||
|
|
||||||
@@ -82,7 +99,9 @@ class SvgViewer {
|
|||||||
return Math.min(scaleX, scaleY, 1); // Never upscale by default
|
return Math.min(scaleX, scaleY, 1); // Never upscale by default
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update SVG transform for scale and pan
|
/**
|
||||||
|
* Update SVG transform for scale and pan.
|
||||||
|
*/
|
||||||
updateTransform() {
|
updateTransform() {
|
||||||
// Calculate actual SVG display size
|
// Calculate actual SVG display size
|
||||||
const container = document.getElementById('svgContainer');
|
const container = document.getElementById('svgContainer');
|
||||||
@@ -103,19 +122,25 @@ class SvgViewer {
|
|||||||
this.svgElement.style.transformOrigin = 'center center';
|
this.svgElement.style.transformOrigin = 'center center';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable transform transition (for zoom)
|
/**
|
||||||
|
* Enable transform transition (for zoom).
|
||||||
|
*/
|
||||||
enableTransition() {
|
enableTransition() {
|
||||||
this.svgElement.style.transition = 'transform 0.1s ease-out';
|
this.svgElement.style.transition = 'transform 0.1s ease-out';
|
||||||
this.transitionEnabled = true;
|
this.transitionEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable transform transition (for pan)
|
/**
|
||||||
|
* Disable transform transition (for pan).
|
||||||
|
*/
|
||||||
disableTransition() {
|
disableTransition() {
|
||||||
this.svgElement.style.transition = '';
|
this.svgElement.style.transition = '';
|
||||||
this.transitionEnabled = false;
|
this.transitionEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fit SVG to window and reset pan
|
/**
|
||||||
|
* Fit SVG to window and reset pan.
|
||||||
|
*/
|
||||||
fitToWindow() {
|
fitToWindow() {
|
||||||
this.baseScale = this.computeBaseScale();
|
this.baseScale = this.computeBaseScale();
|
||||||
this.scale = this.baseScale;
|
this.scale = this.baseScale;
|
||||||
@@ -124,7 +149,9 @@ class SvgViewer {
|
|||||||
this.updateTransform();
|
this.updateTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bind mouse and wheel events for zoom and pan
|
/**
|
||||||
|
* Bind mouse and wheel events for zoom and pan.
|
||||||
|
*/
|
||||||
bindEvents() {
|
bindEvents() {
|
||||||
// Zoom with mouse wheel
|
// Zoom with mouse wheel
|
||||||
this.wrapper.addEventListener("wheel", (e) => {
|
this.wrapper.addEventListener("wheel", (e) => {
|
||||||
@@ -167,6 +194,7 @@ class SvgViewer {
|
|||||||
this.disableTransition(); // Disable animation while panning
|
this.disableTransition(); // Disable animation while panning
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Pan on mouse move
|
// Pan on mouse move
|
||||||
window.addEventListener('mousemove', (e) => {
|
window.addEventListener('mousemove', (e) => {
|
||||||
if (!this.isDragging) return;
|
if (!this.isDragging) return;
|
||||||
@@ -192,6 +220,7 @@ class SvgViewer {
|
|||||||
this.updateTransform();
|
this.updateTransform();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// End pan on mouse up
|
// End pan on mouse up
|
||||||
window.addEventListener('mouseup', () => {
|
window.addEventListener('mouseup', () => {
|
||||||
if (this.isDragging) {
|
if (this.isDragging) {
|
||||||
@@ -201,7 +230,10 @@ class SvgViewer {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize SVG viewer
|
/**
|
||||||
|
* Initialize SVG viewer.
|
||||||
|
* @async
|
||||||
|
*/
|
||||||
async init() {
|
async init() {
|
||||||
const rawSvg = await chrome.webview.hostObjects.external.GetSvgContent();
|
const rawSvg = await chrome.webview.hostObjects.external.GetSvgContent();
|
||||||
const parser = new DOMParser();
|
const parser = new DOMParser();
|
||||||
|
Reference in New Issue
Block a user