בניתם אתר ייחודי? בואו נוסיף לו טאצ' מיוחד עם אפקט מגניב לסמן העכבר!
כל מה שצריך לעשות זה להוסיף את הקוד בטאב "ניהול קודים" באלמנטור, לבחור שהקוד יוצג אחרי תגית ה-Body,
ולשמור את ההגדרות, בשלב הבא נגדיר שהקוד יוצג בכל האתר — וזהו!
העכבר שלכם הפך מאלמנט משעמם לאחד מיוחד שנותן לאתר נגיעה עיצובית ייחודית ומקורית ✨
<script>
/**
* Enhanced Mouse Trail Effect for WordPress and Elementor
* Developed by Twist | https://twist-digital.co.il/
*/
document.addEventListener('DOMContentLoaded', function() {
// User configuration - change these settings to customize the effect
const CONFIG = {
// Appearance
cursorColor: '99, 102, 241', // Cursor dot color (RGB)
cursorGlowColor: '99, 102, 241', // Cursor glow color (RGB)
outlineColor: '99, 102, 241', // Outline circle color (RGB)
outlineOpacity: 0.5, // Outline opacity (0-1)
trailColor: '99, 102, 241', // Trail color (RGB)
trailOpacity: 0.5, // Trail opacity (0-1)
rippleColor: '99, 102, 241', // Click ripple color (RGB)
rippleOpacity: 0.8, // Click ripple opacity (0-1)
// Sizes
cursorSize: 1, // Size of the cursor dot in pixels
outlineSize: 30, // Diameter of outline circle in pixels
outlineWidth: 1, // Width of the outline in pixels
trailSize: 7, // Size of trail dots in pixels
rippleSize: 20, // Size of click ripple in pixels
// Performance & Behavior
trailDensity: 5, // Lower = more dots (distance between dots in pixels)
trailFadeSpeed: 0.2, // How quickly trail dots fade (seconds)
rippleSpeed: 0.1, // Ripple expansion speed
trailDuration: 500, // How long trail dots remain (ms)
rippleDuration: 800, // How long ripples remain (ms)
disableOnLinks: true, // Keeps normal cursor on clickable elements
hideOriginalCursor: true, // Whether to hide the original cursor
mobileBreakpoint: 768, // Width to disable effect on mobile (px)
outlineHoverScale: 1.5 // Scale factor for outline when hovering over links
};
// Create the CSS
const style = document.createElement('style');
style.innerHTML = `
/* Custom mouse cursor effect - CSS */
/* Cursor dot group container */
.cursor-container {
position: fixed;
pointer-events: none;
z-index: 999999;
transform: translate(-50%, -50%);
transition: transform 0.1s ease;
}
/* Cursor dot settings */
.cursor-dot {
width: ${CONFIG.cursorSize}px;
height: ${CONFIG.cursorSize}px;
background-color: rgb(${CONFIG.cursorColor});
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
box-shadow: 0 0 2px 1px rgba(${CONFIG.cursorGlowColor}, 0.8);
transition: opacity 0.2s ease;
}
/* Cursor outline circle */
.cursor-outline {
width: ${CONFIG.outlineSize}px;
height: ${CONFIG.outlineSize}px;
border: ${CONFIG.outlineWidth}px solid rgba(${CONFIG.outlineColor}, ${CONFIG.outlineOpacity});
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
transition: transform 0.15s ease, width 0.2s ease, height 0.2s ease;
}
/* Trail dots settings */
.cursor-trail {
width: ${CONFIG.trailSize}px;
height: ${CONFIG.trailSize}px;
background-color: rgba(${CONFIG.trailColor}, ${CONFIG.trailOpacity});
border-radius: 50%;
position: fixed;
pointer-events: none;
z-index: 999998;
transform: translate(-50%, -50%);
transition: opacity ${CONFIG.trailFadeSpeed}s ease-out;
}
/* Click ripple effect settings */
.cursor-ripple {
width: ${CONFIG.rippleSize}px;
height: ${CONFIG.rippleSize}px;
border: 2px solid rgba(${CONFIG.rippleColor}, ${CONFIG.rippleOpacity});
border-radius: 50%;
position: fixed;
pointer-events: none;
z-index: 999997;
transform: translate(-50%, -50%) scale(0);
}
/* Show regular cursor on clickable elements */
a:hover, button:hover, input:hover, [role="button"]:hover,
select:hover, textarea:hover, .clickable:hover {
cursor: pointer !important;
}
/* Hide effect on small screens */
@media (max-width: ${CONFIG.mobileBreakpoint}px) {
.cursor-container, .cursor-trail, .cursor-ripple {
display: none !important;
}
body {
cursor: auto !important;
}
}
`;
document.head.appendChild(style);
// Create cursor container with dot and outline
const cursorContainer = document.createElement('div');
cursorContainer.className = 'cursor-container';
const cursorOutline = document.createElement('div');
cursorOutline.className = 'cursor-outline';
const cursorDot = document.createElement('div');
cursorDot.className = 'cursor-dot';
cursorContainer.appendChild(cursorOutline);
cursorContainer.appendChild(cursorDot);
document.body.appendChild(cursorContainer);
// Arrays for tracking elements
let trail = [];
let ripples = [];
let isOverClickable = false;
let shouldCreateTrail = true; // Flag to control trail creation
// Variables for smooth trail
let lastMouseX = 0;
let lastMouseY = 0;
let mouseX = 0;
let mouseY = 0;
let distanceMoved = 0;
// Mouse movement handler
document.addEventListener('mousemove', function(e) {
// Update mouse position
mouseX = e.clientX;
mouseY = e.clientY;
// Update cursor container position
cursorContainer.style.left = mouseX + 'px';
cursorContainer.style.top = mouseY + 'px';
// Check if mouse is over any element with cursor:pointer
const target = e.target;
const targetStyle = window.getComputedStyle(target);
const cursorStyle = targetStyle.cursor;
isOverClickable = cursorStyle === 'pointer' || (
CONFIG.disableOnLinks && (
target.tagName === 'A' ||
target.tagName === 'BUTTON' ||
target.tagName === 'INPUT' ||
target.tagName === 'SELECT' ||
target.tagName === 'TEXTAREA' ||
target.getAttribute('role') === 'button' ||
target.classList.contains('clickable')
)
);
// Special handling when over clickable elements
if (isOverClickable) {
// Hide the cursor dot
cursorDot.style.opacity = '0';
// Increase the outline size
const newSize = CONFIG.outlineSize * CONFIG.outlineHoverScale;
cursorOutline.style.width = newSize + 'px';
cursorOutline.style.height = newSize + 'px';
// Stop creating trail
shouldCreateTrail = false;
// Don't modify the body cursor style here, let the browser handle it
} else {
// Restore normal cursor dot
cursorDot.style.opacity = '1';
// Restore original outline size
cursorOutline.style.width = CONFIG.outlineSize + 'px';
cursorOutline.style.height = CONFIG.outlineSize + 'px';
// Resume creating trail
shouldCreateTrail = true;
// Reset cursor only when not over clickable elements
if (CONFIG.hideOriginalCursor) {
document.body.style.cursor = 'none';
}
}
});
// Click effect handler
document.addEventListener('mousedown', function(e) {
// Don't show ripple if over clickable element (optional)
if (isOverClickable) return;
// Create and add ripple
const ripple = document.createElement('div');
ripple.className = 'cursor-ripple';
ripple.style.left = e.clientX + 'px';
ripple.style.top = e.clientY + 'px';
document.body.appendChild(ripple);
// Track ripple
ripples.push({
element: ripple,
createdAt: Date.now(),
scale: 0
});
// Add click effect on cursor outline
cursorOutline.style.transform = 'translate(-50%, -50%) scale(0.9)';
setTimeout(() => {
cursorOutline.style.transform = 'translate(-50%, -50%) scale(1)';
}, 150);
});
// Create trail dots more consistently based on mouse movement
function updateTrail() {
// Only create trail if not over clickable element and trail creation is enabled
if (!shouldCreateTrail) return;
// Calculate distance moved since last frame
const dx = mouseX - lastMouseX;
const dy = mouseY - lastMouseY;
distanceMoved += Math.sqrt(dx * dx + dy * dy);
// Create trail dots based on distance moved, not just on frames
if (distanceMoved >= CONFIG.trailDensity) {
// Create and add new trail dot
const trailDot = document.createElement('div');
trailDot.className = 'cursor-trail';
trailDot.style.left = mouseX + 'px';
trailDot.style.top = mouseY + 'px';
trailDot.style.opacity = '1';
document.body.appendChild(trailDot);
// Add to trail array
trail.push({
element: trailDot,
createdAt: Date.now()
});
// Reset distance counter
distanceMoved = 0;
}
// Update last position
lastMouseX = mouseX;
lastMouseY = mouseY;
}
// Animation loop
function animate() {
// Update trail
updateTrail();
const now = Date.now();
// Clean up old trail dots
trail = trail.filter(dot => {
if (now - dot.createdAt > CONFIG.trailDuration) {
dot.element.style.opacity = '0';
// Remove element after fade completes
setTimeout(() => {
if (dot.element.parentNode) {
dot.element.remove();
}
}, CONFIG.trailFadeSpeed * 1000);
return false;
}
return true;
});
// Animate ripples
ripples.forEach(ripple => {
const age = now - ripple.createdAt;
// Expand
ripple.scale += CONFIG.rippleSpeed;
ripple.element.style.transform = `translate(-50%, -50%) scale(${ripple.scale})`;
// Fade
const opacity = 1 - (age / CONFIG.rippleDuration);
ripple.element.style.opacity = opacity > 0 ? opacity : 0;
});
// Clean up old ripples
ripples = ripples.filter(ripple => {
if (now - ripple.createdAt > CONFIG.rippleDuration) {
ripple.element.remove();
return false;
}
return true;
});
requestAnimationFrame(animate);
}
// Start animation
animate();
// Reset cursor state when mouse leaves clickable elements
document.addEventListener('mouseleave', function(event) {
const target = event.target;
const targetStyle = window.getComputedStyle(target);
// Check if we're leaving a pointer element
if (targetStyle.cursor === 'pointer') {
// Make sure we're not immediately over another pointer element
const elementUnderCursor = document.elementFromPoint(mouseX, mouseY);
if (elementUnderCursor) {
const newElementStyle = window.getComputedStyle(elementUnderCursor);
if (newElementStyle.cursor !== 'pointer') {
// Reset cursor state
cursorDot.style.opacity = '1';
cursorOutline.style.width = CONFIG.outlineSize + 'px';
cursorOutline.style.height = CONFIG.outlineSize + 'px';
shouldCreateTrail = true;
if (CONFIG.hideOriginalCursor) {
document.body.style.cursor = 'none';
}
}
}
}
}, true);
// Hide original cursor if configured
if (CONFIG.hideOriginalCursor) {
document.body.style.cursor = 'none';
}
});
</script>Expand
אם תרצו להתאים את הצבעים של אפקט העכבר לעיצוב האתר שלכם, אני ממליץ פשוט להשתמש באחת מהתוכנות של הבינה המלאכותית, היא תעשה לכם את זה בקלות.
מחפשים חברה לבניית אתרים שתבנה לכם אתר וואו? אני כאן כדי לגרום לזה לקרות.
בואו נבנה לכם אתר מדויק, מרשים – וכזה שמביא תוצאות אמיתיות, שלחו לי הודעה עכשיו, ונהפוך את האתר שלכם לנכס הכי חזק של העסק.

