Laser Writer
How do I make an laser writer?
I've seen several text effect animations lately that inspired me to try it myself.. What is a laser writer? How do you make a laser writer? This script and codes were developed by Johan Karlsson on 26 July 2022, Tuesday.
Laser Writer - Script Codes HTML Codes
<!DOCTYPE html>
<html >
<head> <meta charset="UTF-8"> <title>Laser Writer</title> <link rel="stylesheet" href="css/style.css">
</head>
<body> <canvas id="canvas"></canvas>
<canvas id="canvas2"></canvas>
<a href="http://codepen.io/collection/nWQJKO" class="lowerRight" target="_blank">Show me more!</a> <script src="js/index.js"></script>
</body>
</html>
Laser Writer - Script Codes CSS Codes
body { margin: 0; background-color: #202020;
}
canvas { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); border: 2px solid #272727;
}
.lowerRight { margin: 2px; font-family: serif; font-size: large; color: rgba(20, 255, 70, 1); position: fixed; right: 0; bottom: 0;
}
Laser Writer - Script Codes JS Codes
"use strict";
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/* Johan Karlsson, DonKarlssonSan
*/
var Particle = function () { function Particle(x, y, size) { _classCallCheck(this, Particle); this.speed = 0.6; this.x = x; this.y = y; this.vx = (Math.random() - 0.5) * this.speed; this.vy = (Math.random() - 0.5) * this.speed; this.opacity = 1; this.size = size; } Particle.prototype.draw = function draw(context) { this.opacity -= this.speed / 200; context.fillStyle = this.color(); context.fillRect(this.x, this.y, this.size, this.size); }; Particle.prototype.move = function move() { this.x += this.vx; // y speed is influenced by "gravity" this.y += this.vy + (1 - this.opacity) * this.speed; }; Particle.prototype.color = function color() { return "rgba(0, 255, 0, " + this.opacity + ")"; }; return Particle;
}();
var Laser = function () { function Laser(x, y) { _classCallCheck(this, Laser); this.x = x; this.y = y; this.steps = []; this.particles = []; } Laser.prototype.drawTo = function drawTo(x, y, ctx) { ctx.beginPath(); ctx.moveTo(this.x, this.y); ctx.lineTo(x, y); ctx.stroke(); ctx.fillStyle = "red"; ctx.fillRect(x, y, 5, 5); }; Laser.prototype.drawEnd = function drawEnd(ctx) { var p = this.steps.shift(); if (p !== undefined) { this.drawTo(p[0], p[1], ctx); } else { var index = this.particles.length; // Loop through backwards so we can remove // particles from the array inside the loop. while (index--) { var p = this.particles[index]; p.move(); if (p.opacity < 0 || p.x < 0 || p.x > this.w || p.y < 0 || p.y > this.h) { this.particles.splice(index, 1); } else { p.draw(ctx); } } } }; Laser.prototype.endFrom = function endFrom(x0, y0) { var nrOfSteps = 800; var i = nrOfSteps; while (i--) { var x = this.x + i * (x0 - this.x) / nrOfSteps + Math.cos(i / 10) * i / 4; var y = this.y + i * (y0 - this.y) / nrOfSteps + Math.sin(i / 10) * i / 4; this.steps.push([x, y]); if (i < 100) { this.particles.push(new Particle(this.x, this.y, 2)); } } }; return Laser;
}();
var LaserWriter = function () { function LaserWriter(canvasId, canvas2Id) { _classCallCheck(this, LaserWriter); // The first canvas holds the text being drawn (static). var canvas = document.getElementById(canvasId); // The second canvas holds the laser beam and particles // (animated). var canvas2 = document.getElementById(canvas2Id); this.ctx = canvas.getContext("2d"); this.ctx2 = canvas2.getContext("2d"); this.w = canvas.width = canvas2.width = 900; this.h = canvas.height = canvas2.height = 500; this.tick = 0; this.pointsIndex = 0; this.points = []; this.particles = []; // All the points that make up the whole word this.size = 3; this.startX = 0; this.laserStart = { x: 300, y: 50 }; this.x = 0; this.y = 0; } LaserWriter.prototype.init = function init(text, size) { this.ctx.font = size + "px serif"; // Draw black text on the canvas temporarily this.startX = (this.w - this.ctx.measureText(text).width * 3) * 0.5; this.ctx.fillText(text, 1, 100); var width = 500; var height = 300; var image = this.ctx.getImageData(0, 0, width, height); var buffer32 = new Uint32Array(image.data.buffer); for (var x = 0; x < width; x++) { for (var y = 0; y < height; y++) { // The buffer is linear, y*w+x is a trick // to calculate the linear index. if (buffer32[y * width + x]) { // There is a pixel here, add a point this.points.push([x, y]); } } } // Clear the text once, we will just be adding // to this canvas from now on (no clearing). this.ctx.clearRect(0, 0, this.w, this.h); this.ctx.fillStyle = "rgba(0, 160, 0, 0.34)"; // For the laser this.ctx2.strokeStyle = "rgba(20, 255, 70, 1)"; this.ctx2.lineCap = "round"; this.ctx2.lineWidth = 4; this.laser = new Laser(this.laserStart.x, this.laserStart.y); }; LaserWriter.prototype.draw = function draw() { var _this = this; this.ctx2.clearRect(0, 0, this.w, this.h); // Continue drawing text? if (this.pointsIndex < this.points.length) { // Ok, we are not done // Draw the text, one point at a time var p = this.points[this.pointsIndex]; this.x = p[0] * this.size + this.startX; this.y = p[1] * this.size + 80; this.drawPointAt(this.x, this.y); //this.drawLaserTo(x, y); this.laser.drawTo(this.x, this.y, this.ctx2); // Just add a particle every other tick if (this.tick % 2 === 0) { var particle = new Particle(this.x, this.y, this.size); this.particles.push(particle); } } else if (this.pointsIndex === this.points.length) { this.laser.endFrom(this.x, this.y); } else { this.laser.drawEnd(this.ctx2); } this.drawParticles(); this.pointsIndex++; this.tick++; // Keep the animation going a while after we have // drawn all the text to let the last particles // fall off the screen and the laser end animation // run. if (this.pointsIndex < this.points.length + 10000) { // Draw three steps (ticks) then redraw screen if (this.tick % 3 === 0) { requestAnimationFrame(function () { return _this.draw(); }); } else { this.draw(); } } }; LaserWriter.prototype.drawPointAt = function drawPointAt(x, y) { this.ctx.beginPath(); this.ctx.arc(x, y, this.size * 2, 0, Math.PI * 2, false); this.ctx.fill(); }; LaserWriter.prototype.drawParticles = function drawParticles() { var index = this.particles.length; // Loop through backwards so we can remove // particles from the array inside the loop. while (index--) { var p = this.particles[index]; p.move(); if (p.opacity < 0 || p.x < 0 || p.x > this.w || p.y < 0 || p.y > this.h) { this.particles.splice(index, 1); } else { p.draw(this.ctx2); } } }; return LaserWriter;
}();
var laserWriter = new LaserWriter("canvas", "canvas2");
laserWriter.init("Sweet!", 100);
laserWriter.draw();
Developer | Johan Karlsson |
Username | DonKarlssonSan |
Uploaded | July 26, 2022 |
Rating | 4.5 |
Size | 6,065 Kb |
Views | 36,432 |
Find the perfect freelance services for your business! Fiverr's mission is to change how the world works together. Fiverr connects businesses with freelancers offering digital services in 500+ categories. Find Developer!
Name | Size |
Circuit Board Warper | 4,057 Kb |
Particle Text | 5,685 Kb |
Moss by Brownian Motion | 2,792 Kb |
In Tribute to Simon Plouffe | 2,376 Kb |
The Rainbow Spirograph | 4,016 Kb |
Rotating Neon Curves | 3,770 Kb |
Photobooth - Webcam with realtime CSS filters. | 4,390 Kb |
SoundCloud Music Visualizer | 4,211 Kb |
Random Fractal | 2,751 Kb |
Apply Filter Effects to Music | 4,027 Kb |
Jasper is the AI Content Generator that helps you and your team break through creative blocks to create amazing, original content 10X faster. Discover all the ways the Jasper AI Content Platform can help streamline your creative workflows. Start For Free!
Name | Username | Size |
A Pen by utcwebdev | Utcwebdev | 2,856 Kb |
IPhone5S SVG Space Grey | Onlinechris | 75,035 Kb |
Very Simple Slider | Doodlemarks | 2,682 Kb |
NgEasyModal | Lorenzodianni | 4,159 Kb |
Profile box | Daniesy | 2,766 Kb |
About Us | Francescaedits | 1,902 Kb |
Animated Vertical CSS3 Menu Black | MaCeLMp4 | 2,750 Kb |
SlideupBoxes | Gavra | 23,772 Kb |
CSS Piano | Dannystyle | 5,138 Kb |
Basic HTML5 Structure | YuvarajTana | 1,289 Kb |
Surf anonymously, prevent hackers from acquiring your IP address, send anonymous email, and encrypt your Internet connection. High speed, ultra secure, and easy to use. Instant setup. Hide Your IP Now!