A lightweight, fully responsive, and customizable Android-style pattern lock component for Angular. Built with SVG for crisp rendering on any device, with zero external dependencies.
Note: It supports both mouse and touch interactions seamlessly.
- Lightweight: Zero external dependencies.
- Mobile Ready: Full touch support with no "ghost drag" effects.
- SVG Based: Sharp rendering on retina/high-DPI screens.
- High Performance: Smooth animations and interactions.
- Fully Customizable: Easily change colors and sizes via CSS variables.
- Standalone Ready: Compatible with modern Angular (17+) standalone components.
Run the following command in your project:
npm install ngx-pattern-lockImport NgxPatternLockComponent in your standalone component (or Module).
import { Component } from '@angular/core';
import { NgxPatternLockComponent } from 'ngx-pattern-lock'; // <--- Import the correct class name
@Component({
selector: 'app-root',
standalone: true,
imports: [ NgxPatternLockComponent ], // <--- Add to imports array
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
// The library emits the pattern as an array of numbers (IDs 1-9)
onPatternComplete(pattern: number[]) {
console.log('Pattern captured:', pattern);
// Example output: [1, 2, 5, 9]
if (this.isPatternCorrect(pattern)) {
console.log('Unlocked! 🎉');
} else {
console.log('Wrong pattern ❌');
}
}
// Example validation logic
isPatternCorrect(pattern: number[]): boolean {
const correctPattern = [1, 2, 3, 6, 9]; // Your secret password
return JSON.stringify(pattern) === JSON.stringify(correctPattern);
}
} <ngx-pattern-lock
label="Draw your pattern"
refreshButtonLabel="Reset"
(patternChange)="onPatternComplete($event)">
</ngx-pattern-lock>You can use the component to display a previously saved pattern without allowing user interaction. The component intelligently handles native touch scrolling in this mode.
<ngx-pattern-lock
[readonly]="true"
[preloadedPattern]="[1, 2, 5, 9]">
</ngx-pattern-lock>| Name | Type | Description |
|---|---|---|
@Input() label |
string |
Optional text displayed above the pattern grid (e.g., "Draw pattern"). |
@Input() refreshButtonLabel |
string |
Text for the reset button. If provided, the button will appear below the grid. |
@Input() readonly |
boolean |
Default: false. If true, drawing is disabled and native touch scrolling is enabled over the component. |
@Input() preloadedPattern |
number[] |
An array of IDs (e.g., [1, 2, 5]) to render a static pattern on the grid. |
@Output() patternChange |
EventEmitter<number[]> |
Emits an array of selected point IDs (e.g., [1, 2]) when the user completes a pattern. |
@Output() patternCleared |
EventEmitter<void> |
Emits an event when the pattern is reset or the refresh button is clicked. |
| Name | Description |
|---|---|
clear() |
Resets the pattern programmatically (e.g., after an invalid attempt). Access it via @ViewChild. |
The component is designed to be styled easily using CSS Variables. You can define these in your global styles (styles.scss) or within the parent component.
/* Example Customization */
ngx-pattern-lock {
/* --- MAIN COLORS --- */
--pattern-color: #3b82f6; /* Lines & Active dots (Default: Blue) */
--pattern-bg: #ffffff; /* Card background (Default: White) */
--pattern-inactive: #cbd5e1; /* Inactive dots (Default: Gray) */
/* --- DIMENSIONS --- */
--pattern-size: 300px; /* Max width. Set to 100% to let parent control size. */
--pattern-border: 1px solid #e2e8f0;
--pattern-radius: 16px;
/* --- REFRESH BUTTON --- */
--pattern-btn-color: #64748b; /* Default text color (Default: Slate Gray) */
--pattern-error: #ef4444; /* Hover text color (Default: Red) */
--pattern-error-bg: #fee2e2; /* Hover background color (Default: Light Red) */
}- Angular: v17+ (Ivy compatible / Standalone)
- Browsers: Chrome, Firefox, Safari, Edge, Mobile Browsers (iOS & Android).
MIT © Nicolas Toledo
Made with ❤️