docs: Add comprehensive click-to-zoom documentation
Add real-world implementation example of click-to-zoom feature to maintainer documentation: **IMPLEMENTATION_GUIDE.md:** - Complete step-by-step implementation guide showing how click-to-zoom was added - Explains each component (input signals, IvyPinch method, template, CSS) - Includes code snippets from actual implementation - Shows real-world usage for anomaly detection use case - Provides testing checklist **docs/README.md:** - Added click-to-zoom to "Where do I find...?" quick reference table - Added to "How do I...?" task guide - Helps maintainers quickly locate click-to-zoom documentation This serves as a template for future feature additions and helps maintainers understand how to add similar interactive features to the library.
This commit is contained in:
parent
1b7ed5adff
commit
dcc0f95818
2 changed files with 179 additions and 0 deletions
|
|
@ -473,6 +473,183 @@ ngOnDestroy(): void {
|
|||
6. Compare snapshots
|
||||
7. Verify no PinchZoomComponent instances retained
|
||||
|
||||
### Feature: Click-to-Zoom (Real-World Example)
|
||||
|
||||
This is a complete, real implementation added to the library for anomaly detection and defect inspection use cases.
|
||||
|
||||
**Goal**: Allow users to click any point on the image to zoom to that exact location, perfect for quickly examining suspicious areas in images.
|
||||
|
||||
#### Step 1: Add Input Signals
|
||||
|
||||
**File: `pinch-zoom.component.ts`**
|
||||
|
||||
```typescript
|
||||
export class PinchZoomComponent implements OnInit, OnDestroy {
|
||||
// ... existing inputs
|
||||
|
||||
// Click-to-zoom inputs
|
||||
enableClickToZoom = input<boolean>(false);
|
||||
clickToZoomScale = input<number>(2.5);
|
||||
|
||||
// ... rest of class
|
||||
}
|
||||
```
|
||||
|
||||
**Why this works**:
|
||||
|
||||
- `enableClickToZoom` - Feature flag to avoid interfering with existing functionality
|
||||
- `clickToZoomScale` - Configurable zoom level (default 2.5x is good for defect inspection)
|
||||
|
||||
#### Step 2: Add zoomToPoint Method to IvyPinch
|
||||
|
||||
**File: `ivypinch.ts`**
|
||||
|
||||
```typescript
|
||||
export class IvyPinch {
|
||||
// Add after zoomOut() method
|
||||
|
||||
public zoomToPoint(clientX: number, clientY: number, targetScale: number): void {
|
||||
// Update element position
|
||||
this.getElementPosition();
|
||||
|
||||
// Calculate the click point relative to the element
|
||||
const xRelativeToElement = clientX - this.elementPosition.left;
|
||||
const yRelativeToElement = clientY - this.elementPosition.top;
|
||||
|
||||
// Clamp target scale to limits
|
||||
let newScale = targetScale;
|
||||
if (newScale > this.maxScale) {
|
||||
newScale = this.maxScale;
|
||||
}
|
||||
if (newScale < (this.properties.minScale || 0)) {
|
||||
newScale = this.properties.minScale || 0;
|
||||
}
|
||||
|
||||
// If already at target scale or zoomed in, reset zoom
|
||||
if (this.scale >= targetScale || this.scale > 1) {
|
||||
this.resetScale();
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate the new position to keep the clicked point centered
|
||||
this.scale = newScale;
|
||||
this.zoomChanged(this.scale);
|
||||
|
||||
// Calculate the zoom offset to keep clicked point under cursor
|
||||
const scaleRatio = newScale / this.initialScale;
|
||||
this.moveX = this.initialMoveX - xRelativeToElement * (scaleRatio - 1);
|
||||
this.moveY = this.initialMoveY - yRelativeToElement * (scaleRatio - 1);
|
||||
|
||||
this.centeringImage();
|
||||
this.updateInitialValues();
|
||||
this.transformElement(this.properties.transitionDuration || 200);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Key points**:
|
||||
|
||||
- Uses `getElementPosition()` to get fresh position (element may have moved)
|
||||
- Calculates click position relative to element bounds
|
||||
- Applies zoom offset to keep clicked point under cursor
|
||||
- Respects min/max scale limits
|
||||
- Smooth animation using existing transition duration
|
||||
|
||||
#### Step 3: Add Component Wrapper Method
|
||||
|
||||
**File: `pinch-zoom.component.ts`**
|
||||
|
||||
```typescript
|
||||
export class PinchZoomComponent implements OnInit, OnDestroy {
|
||||
// ... existing methods
|
||||
|
||||
zoomToPoint(event: MouseEvent): void {
|
||||
if (!this.enableClickToZoom() || this.isDisabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Prevent default to avoid conflicts
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
// Get click coordinates
|
||||
const clientX = event.clientX;
|
||||
const clientY = event.clientY;
|
||||
|
||||
// Call IvyPinch method with target scale
|
||||
this.pinchZoom?.zoomToPoint(clientX, clientY, this.clickToZoomScale());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Why this works**:
|
||||
|
||||
- Checks feature flag and disabled state
|
||||
- Prevents event propagation to avoid conflicts with other gestures
|
||||
- Delegates to IvyPinch for actual zoom logic
|
||||
|
||||
#### Step 4: Add Click Handler to Template
|
||||
|
||||
**File: `pinch-zoom.component.html`**
|
||||
|
||||
```html
|
||||
<div
|
||||
class="pinch-zoom-content"
|
||||
[class.pz-dragging]="isDragging()"
|
||||
[class.pz-click-to-zoom]="enableClickToZoom()"
|
||||
(click)="enableClickToZoom() ? zoomToPoint($event) : null"
|
||||
>
|
||||
<ng-content></ng-content>
|
||||
</div>
|
||||
```
|
||||
|
||||
**Key points**:
|
||||
|
||||
- Conditional click handler (only active when enabled)
|
||||
- CSS class for visual feedback (cursor changes)
|
||||
- Works alongside existing touch/pan gestures
|
||||
|
||||
#### Step 5: Add CSS Cursor Feedback
|
||||
|
||||
**File: `pinch-zoom.component.sass`**
|
||||
|
||||
```sass
|
||||
.pz-click-to-zoom
|
||||
cursor: zoom-in
|
||||
|
||||
.pz-click-to-zoom.pz-dragging
|
||||
cursor: all-scroll // Dragging takes priority
|
||||
```
|
||||
|
||||
**UX improvement**: User knows they can click to zoom when cursor changes
|
||||
|
||||
#### Result
|
||||
|
||||
Users can now:
|
||||
|
||||
1. Enable click-to-zoom with `[enableClickToZoom]="true"`
|
||||
2. Click any suspicious area on the image
|
||||
3. Image zooms to 2.5x with clicked point centered
|
||||
4. Click again to zoom out
|
||||
5. Works perfectly with brightness control for defect inspection
|
||||
|
||||
**Real-world usage**:
|
||||
|
||||
```html
|
||||
<pinch-zoom [enableClickToZoom]="true" [clickToZoomScale]="2.5" [enableBrightnessControl]="true">
|
||||
<img src="product-defect-scan.jpg" />
|
||||
</pinch-zoom>
|
||||
```
|
||||
|
||||
**Testing checklist**:
|
||||
|
||||
- ✅ Click to zoom in to point
|
||||
- ✅ Click again to zoom out
|
||||
- ✅ Respects max zoom limit
|
||||
- ✅ Works with pan gesture
|
||||
- ✅ Cursor shows zoom-in icon
|
||||
- ✅ Disabled when `disabled=true`
|
||||
|
||||
## Common Customizations
|
||||
|
||||
### Custom: Programmatic Zoom to Specific Point
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ docs/
|
|||
| Why isn't pan working? | QUICK_REFERENCE.md → "Debugging Checklist" |
|
||||
| What is `transformElement()`? | ARCHITECTURE.md → "Transform Mathematics" |
|
||||
| How to add rotation? | IMPLEMENTATION_GUIDE.md → "Feature: Add Rotation Support" |
|
||||
| How click-to-zoom works? | IMPLEMENTATION_GUIDE.md → "Feature: Click-to-Zoom" |
|
||||
| Performance best practices? | QUICK_REFERENCE.md → "Performance Tips" |
|
||||
| Event flow diagram? | ARCHITECTURE.md → "Event System" |
|
||||
|
||||
|
|
@ -77,6 +78,7 @@ docs/
|
|||
| Task | Document |
|
||||
| ------------------------ | ----------------------------------------------------------------------- |
|
||||
| Fix image jumping | IMPLEMENTATION_GUIDE.md → "Bug: Image Jumps on First Touch" |
|
||||
| Add click-to-zoom | IMPLEMENTATION_GUIDE.md → "Feature: Click-to-Zoom" |
|
||||
| Add custom zoom behavior | IMPLEMENTATION_GUIDE.md → "Custom: Programmatic Zoom to Specific Point" |
|
||||
| Debug transforms | IMPLEMENTATION_GUIDE.md → "Technique 1: Visual Transform Debugging" |
|
||||
| Improve performance | IMPLEMENTATION_GUIDE.md → "Performance Optimization" |
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue