Shake Effect
Quick attention/error shake animation. Perfect for form validation feedback and drawing attention to important elements.
Domma.effects.shake()
The shake() effect applies a quick shake animation to draw attention or signal an error. Supports horizontal, vertical, and both directions with configurable intensity and iterations.
// Shake an invalid input
Domma.effects.shake('#email-input');
// Vertical shake with callback
Domma.effects.shake('.alert', {
direction: 'vertical',
intensity: 4,
iterations: 2,
onComplete: () => console.log('Shake done')
});
// Intense shake
Domma.effects.shake('.error-box', {
intensity: 12,
duration: 800,
direction: 'both'
});
Demo: Shake Directions
Three shake directions: horizontal, vertical, and both axes simultaneously.
Horizontal
Vertical
Both
<div class="shake-target bg-primary text-white" id="shake-h">Horizontal</div>
<div class="shake-target bg-success text-white" id="shake-v">Vertical</div>
<div class="shake-target bg-danger text-white" id="shake-both">Both</div>
<button type="button" class="btn btn-primary" id="shake-start-h">Shake Horizontal</button>
<button type="button" class="btn btn-success" id="shake-start-v">Shake Vertical</button>
<button type="button" class="btn btn-danger" id="shake-start-both">Shake Both</button>/**
* Demo: Shake Directions - from public/showcase/effects/shake.
*/
export function mount(root) {
// Demo 1: Directions
$(root).find('#shake-start-h').on('click', () => {
Domma.effects.shake('#shake-h', {
direction: 'horizontal',
respectMotionPreference: false
});
});
$(root).find('#shake-start-v').on('click', () => {
Domma.effects.shake('#shake-v', {
direction: 'vertical',
respectMotionPreference: false
});
});
$(root).find('#shake-start-both').on('click', () => {
Domma.effects.shake('#shake-both', {
direction: 'both',
respectMotionPreference: false
});
});
}Domma.effects.shake('#el', { direction: 'horizontal' }); // Default
Domma.effects.shake('#el', { direction: 'vertical' });
Domma.effects.shake('#el', { direction: 'both' });
Demo: Intensity Levels
Different shake intensities from subtle to extreme.
Subtle (2px)
Normal (6px)
Intense (12px)
<div class="shake-target" id="shake-subtle" style="background: #e3f2fd; color: #1565c0;">Subtle (2px)</div>
<div class="shake-target" id="shake-normal" style="background: #fff3e0; color: #8c2d00;">Normal (6px)</div>
<div class="shake-target" id="shake-intense" style="background: #fce4ec; color: #c62828;">Intense (12px)</div>
<button type="button" class="btn btn-primary" id="shake-start-subtle">Subtle</button>
<button type="button" class="btn btn-warning" id="shake-start-normal">Normal</button>
<button type="button" class="btn btn-danger" id="shake-start-intense">Intense</button>/**
* Demo: Intensity Levels - from public/showcase/effects/shake.
*/
export function mount(root) {
// Demo 2: Intensity
$(root).find('#shake-start-subtle').on('click', () => {
Domma.effects.shake('#shake-subtle', {
intensity: 2,
respectMotionPreference: false
});
});
$(root).find('#shake-start-normal').on('click', () => {
Domma.effects.shake('#shake-normal', {
intensity: 6,
respectMotionPreference: false
});
});
$(root).find('#shake-start-intense').on('click', () => {
Domma.effects.shake('#shake-intense', {
intensity: 12,
respectMotionPreference: false
});
});
}Domma.effects.shake('#el', { intensity: 2 }); // Subtle
Domma.effects.shake('#el', { intensity: 6 }); // Normal (default)
Domma.effects.shake('#el', { intensity: 12 }); // Intense
Demo: Form Validation
Shake invalid form inputs to draw attention. Try submitting with an empty or invalid email.
<label class="d-block mb-2 font-semibold">Email Address</label>
<input type="email" class="shake-input mb-2" id="shake-email" placeholder="Enter your email">
<div class="text-danger mb-3" id="shake-error" style="display: none; font-size: 0.9rem;">Please enter a valid email address.</div>
<button type="button" class="btn btn-primary" id="shake-validate">Submit</button>/**
* Demo: Form Validation - from public/showcase/effects/shake.
*/
export function mount(root) {
// Demo 3: Form Validation
$(root).find('#shake-validate').on('click', () => {
const email = $(root).find('#shake-email').val();
const isValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
if (!isValid) {
$(root).find('#shake-email').addClass('invalid');
$(root).find('#shake-error').show();
Domma.effects.shake('#shake-email', {
intensity: 4,
duration: 400,
respectMotionPreference: false,
onComplete: () => {
setTimeout(() => {
$(root).find('#shake-email').removeClass('invalid');
$(root).find('#shake-error').hide();
}, 2000);
}
});
} else {
$(root).find('#shake-email').removeClass('invalid');
$(root).find('#shake-error').hide();
E.toast('Valid email!', { type: 'success' });
}
});
}$('#submit').on('click', () => {
const email = $('#email').val();
const isValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
if (!isValid) {
$('#email').addClass('invalid');
Domma.effects.shake('#email', {
intensity: 4,
duration: 400,
onComplete: () => {
// Remove invalid state after delay
setTimeout(() => $('#email').removeClass('invalid'), 2000);
}
});
}
});
Demo: Multiple Iterations
Repeat the shake cycle multiple times for persistent emphasis.
Shake Me!
<div class="shake-target bg-warning text-dark" id="shake-iter">Shake Me!</div>
<button type="button" class="btn btn-primary" id="shake-1x">1x</button>
<button type="button" class="btn btn-primary" id="shake-2x">2x</button>
<button type="button" class="btn btn-primary" id="shake-3x">3x</button>/**
* Demo: Multiple Iterations - from public/showcase/effects/shake.
*/
export function mount(root) {
// Demo 4: Iterations
$(root).find('#shake-1x').on('click', () => {
Domma.effects.shake('#shake-iter', {
iterations: 1,
respectMotionPreference: false
});
});
$(root).find('#shake-2x').on('click', () => {
Domma.effects.shake('#shake-iter', {
iterations: 2,
respectMotionPreference: false
});
});
$(root).find('#shake-3x').on('click', () => {
Domma.effects.shake('#shake-iter', {
iterations: 3,
respectMotionPreference: false
});
});
}Domma.effects.shake('#el', { iterations: 1 }); // Default
Domma.effects.shake('#el', { iterations: 2 });
Domma.effects.shake('#el', { iterations: 3 });
Demo: Staggered Shake
Shake multiple elements with a cascading delay.
Item 1
Item 2
Item 3
Item 4
<div class="shake-target shake-stagger" style="background: #e8eaf6; color: #283593;">Item 1</div>
<div class="shake-target shake-stagger" style="background: #e8eaf6; color: #283593;">Item 2</div>
<div class="shake-target shake-stagger" style="background: #e8eaf6; color: #283593;">Item 3</div>
<div class="shake-target shake-stagger" style="background: #e8eaf6; color: #283593;">Item 4</div>
<button type="button" class="btn btn-primary mt-3" id="shake-start-stagger">Shake All (Staggered)</button>/**
* Demo: Staggered Shake - from public/showcase/effects/shake.
*/
export function mount(root) {
// Demo 5: Stagger
$(root).find('#shake-start-stagger').on('click', () => {
Domma.effects.shake('.shake-stagger', {
stagger: 100,
intensity: 5,
direction: 'horizontal',
respectMotionPreference: false
});
});
}Domma.effects.shake('.item', {
stagger: 100,
intensity: 5,
direction: 'horizontal'
});
Options Reference
| Option | Type | Default | Description |
|---|---|---|---|
intensity |
number | 6 | Shake distance in pixels |
duration |
number | 500 | Total shake duration in ms |
direction |
string | 'horizontal' | 'horizontal', 'vertical', 'both' |
easing |
string | 'ease-in-out' | CSS easing function |
iterations |
number | 1 | Number of shake cycles |
stagger |
number | 0 | Delay between elements (ms) |
respectMotionPreference |
boolean | true | Honour prefers-reduced-motion |
onComplete |
function | null | Callback when shake completes |