diff --git a/index.html b/index.html index 7d97ae2..826a77f 100644 --- a/index.html +++ b/index.html @@ -32,6 +32,23 @@ on GitHub. +
+
+
+
+ Rainbow+ to your site +
+ +
+
+
+
+
diff --git a/index.js b/index.js index 9f0edeb..fa00d1f 100644 --- a/index.js +++ b/index.js @@ -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") }) diff --git a/package.json b/package.json index 55f0599..276e444 100644 --- a/package.json +++ b/package.json @@ -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": { diff --git a/readme.md b/readme.md index de4d92c..9a5b449 100644 --- a/readme.md +++ b/readme.md @@ -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. diff --git a/src/index.js b/src/index.js index 27c6507..f98c4ad 100644 --- a/src/index.js +++ b/src/index.js @@ -5,4 +5,5 @@ export * from './trailingCursor.js'; export * from './followingDotCursor.js' export * from './bubbleCursor.js'; export * from './emojiCursor.js'; -export * from './ghostCursor.js'; \ No newline at end of file +export * from './ghostCursor.js'; +export * from './rainbowCursor.js'; \ No newline at end of file diff --git a/src/rainbowCursor.js b/src/rainbowCursor.js new file mode 100644 index 0000000..6fe4a08 --- /dev/null +++ b/src/rainbowCursor.js @@ -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(); +}