Skip to content

Commit

Permalink
add rainbow cursor
Browse files Browse the repository at this point in the history
  • Loading branch information
tholman committed Jul 7, 2022
1 parent 528947e commit 677fd06
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 2 deletions.
17 changes: 17 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,23 @@
<a href="https://github.com/tholman/cursor-effects">on GitHub.</a>
</div>

<div class="cursor">
<div class="box">
<div class="info">
<div class="name">
<span>Rainbow</span
><a href="https://github.com/tholman/cursor-effects"
>+ to your site</a
>
</div>
<div class="byline">
A little color never hurt anyone
</div>
</div>
<div id="rainbow" class="effect"></div>
</div>
</div>

<div class="cursor">
<div class="box">
<div class="info">
Expand Down
1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
new cursoreffects.rainbowCursor({ element: document.querySelector("#rainbow") })
new cursoreffects.fairyDustCursor({ element: document.querySelector("#fairyDust") })
new cursoreffects.ghostCursor({ element: document.querySelector("#ghost") })
new cursoreffects.trailingCursor({ element: document.querySelector("#trailing") })
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "cursor-effects",
"type": "module",
"description": "Old-school cursor effects for your browser built in modern JavaScript.",
"version": "1.0.2",
"version": "1.0.3",
"main": "./dist/cjs.cjs",
"module": "./dist/esm.js",
"exports": {
Expand Down
8 changes: 8 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ new emojiCursor({ emoji: ["🔥", "🐬", "🦆"] });

A few of these have custom options as well (if you are interested in more options, opening an issue or PR is the way to go).

### rainbowCursor

You can change the colors, size and length in `rainbowCursor`

```js
new cursoreffects.rainbowCursor({length: 3, colors: ['red', 'blue'], size: 4});
```

### springyEmojiCursor

You can change the emoji in `springyEmojiCursor`'s emoji with the `emoji` a single string emoji.
Expand Down
3 changes: 2 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export * from './trailingCursor.js';
export * from './followingDotCursor.js'
export * from './bubbleCursor.js';
export * from './emojiCursor.js';
export * from './ghostCursor.js';
export * from './ghostCursor.js';
export * from './rainbowCursor.js';
142 changes: 142 additions & 0 deletions src/rainbowCursor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
export function rainbowCursor(options) {
let hasWrapperEl = options && options.element;
let element = hasWrapperEl || document.body;

let width = window.innerWidth;
let height = window.innerHeight;
let cursor = { x: width / 2, y: width / 2 };
let particles = [];
let canvas, context;

const totalParticles = options?.length || 20;
const colors = options?.colors || [
"#FE0000",
"#FD8C00",
"#FFE500",
"#119F0B",
"#0644B3",
"#C22EDC",
]
const size = options.size || 3

let cursorsInitted = false;

function init() {
canvas = document.createElement("canvas");
context = canvas.getContext("2d");
canvas.style.top = "0px";
canvas.style.left = "0px";
canvas.style.pointerEvents = "none";

if (hasWrapperEl) {
canvas.style.position = "absolute";
element.appendChild(canvas);
canvas.width = element.clientWidth;
canvas.height = element.clientHeight;
} else {
canvas.style.position = "fixed";
document.body.appendChild(canvas);
canvas.width = width;
canvas.height = height;
}

bindEvents();
loop();
}

// Bind events that are needed
function bindEvents() {
element.addEventListener("mousemove", onMouseMove);
window.addEventListener("resize", onWindowResize);
}

function onWindowResize(e) {
width = window.innerWidth;
height = window.innerHeight;

if (hasWrapperEl) {
canvas.width = element.clientWidth;
canvas.height = element.clientHeight;
} else {
canvas.width = width;
canvas.height = height;
}
}

function onMouseMove(e) {
if (hasWrapperEl) {
const boundingRect = element.getBoundingClientRect();
cursor.x = e.clientX - boundingRect.left;
cursor.y = e.clientY - boundingRect.top;
} else {
cursor.x = e.clientX;
cursor.y = e.clientY;
}

if (cursorsInitted === false) {
cursorsInitted = true;
for (let i = 0; i < totalParticles; i++) {
addParticle(cursor.x, cursor.y);
}
}
}

function addParticle(x, y, image) {
particles.push(new Particle(x, y, image));
}

function updateParticles() {
context.clearRect(0, 0, width, height);
context.lineJoin = "round";

let particleSets = [];

let x = cursor.x;
let y = cursor.y;

particles.forEach(function (particle, index, particles) {
let nextParticle = particles[index + 1] || particles[0];

particle.position.x = x;
particle.position.y = y;

particleSets.push({ x: x, y: y });

x += (nextParticle.position.x - particle.position.x) * 0.4;
y += (nextParticle.position.y - particle.position.y) * 0.4;
});

colors.forEach((color, index) => {
context.beginPath();
context.strokeStyle = color;

if (particleSets.length) {
context.moveTo(
particleSets[0].x,
particleSets[0].y + index * (size - 1)
);
}

particleSets.forEach((set, particleIndex) => {
if (particleIndex !== 0) {
context.lineTo(set.x, set.y + index * size);
}
});

context.lineWidth = size;
context.lineCap = "round";
context.stroke();
});
}

function loop() {
updateParticles();
requestAnimationFrame(loop);
}

function Particle(x, y) {
this.position = { x: x, y: y };
}

init();
}

0 comments on commit 677fd06

Please sign in to comment.