Elastic String
How do I make an elastic string?
Inspired by http://codepen.io/tholman/pen/qCnfB. What is a elastic string? How do you make a elastic string? This script and codes were developed by Akimitsu Hamamuro on 13 June 2022, Monday.
Elastic String - Script Codes HTML Codes
<!DOCTYPE html>
<html >
<head> <meta charset="UTF-8"> <title>Elastic String</title> <link rel="stylesheet" href="css/style.css">
</head>
<body> <canvas id='c'></canvas> <script src='js/kzymdn.js'></script> <script src="js/index.js"></script>
</body>
</html>
Elastic String - Script Codes CSS Codes
html, body { height: 100%;
}
body { font-family: sans-serif; padding: 0; margin: 0; background-repeat: no-repeat; background-attachment: fixed; background-color: #f9f9f2; background-image: -webkit-radial-gradient(center, circle farthest-side, #F9F9F2 0%, #D6D6D0 100%); background-image: -moz-radial-gradient(center, circle farthest-side, #F9F9F2 0%, #D6D6D0 100%); background-image: -ms-radial-gradient(center, circle farthest-side, #F9F9F2 0%, #D6D6D0 100%); background-image: -o-radial-gradient(center, circle farthest-side, #F9F9F2 0%, #D6D6D0 100%); background-image: radial-gradient(center, circle farthest-side, #F9F9F2 0%, #D6D6D0 100%);
}
canvas { position: absolute; top: 0; left: 0;
}
Elastic String - Script Codes JS Codes
/** * requestAnimationFrame */
window.requestAnimationFrame = (function(){ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) { window.setTimeout(callback, 1000 / 60); };
})();
/** * ElasticString */
var ElasticString = (function(document) { 'use strict'; /** * @constructor */ function ElasticString(fontSize, fontFamily, friction, spring) { this._fontSize = fontSize; this.points = []; this.fontFamily = fontFamily || 'serif'; if (friction !== undefined) this.friction = friction; if (spring !== undefined) this.spring = spring; // 最後のテキストポイントの補完ポイント this._endPoint = new Point(); // フォントサイズ this._ctx = document.createElement('canvas').getContext('2d'); } ElasticString.prototype = { points: null, fontFamily: 'serif', friction: 0.02, spring: 0.6, _text: '', _fontSize: 1, _endPoint: null, setFontSize: function(fontSize) { this._fontSize = fontSize; this.setText(this._text); }, getFontSize: function() { return this._fontSize; }, setText: function(text, positions) { var points = this.points, p, letter, between, i, len; if (text.length < points.length) { points = points.slice(0, text.length); } this._ctx.font = this._fontSize + 'px ' + this.fontFamily; for (i = 0, len = text.length; i < len; i++) { letter = text.charAt(i); between = this._ctx.measureText(letter).width; p = points[i]; if (p) { p.letter = letter; p.between = between; } else { p = new Point(letter, between); points[i] = p; } if (positions && positions.length) { p.x = p.px = positions[i][0]; p.y = p.py = positions[i][1]; } } this.points = points; this._text = text; }, getText: function() { return this._text; }, render: function(ctx) { var points = this.points, pointBetween = this._fontSize, spring = this.spring, text = this.text, dx, dy, dist, scale, p0, p1, size, angle, i, len; points.push(this._endPoint); this._updatePoint(points[0]); for (i = 0, len = points.length - 1; i < len; i++) { p0 = points[i]; p1 = points[i + 1]; this._updatePoint(p1); dx = p0.x - p1.x; dy = p0.y - p1.y; dist = Math.sqrt(dx * dx + dy * dy); scale = dist ? (p0.between - dist) / dist * 0.5 * spring : 0; dx *= scale; dy *= scale; p0.x += dx; p0.y += dy; p1.x -= dx; p1.y -= dy; } for (i = 0; i < len; i++) { p0 = points[i]; p1 = points[i + 1]; dx = p1.x - p0.x; dy = p1.y - p0.y; dist = Math.sqrt(dx * dx + dy * dy); angle = Math.atan2(dy, dx); ctx.save(); size = pointBetween > dist ? pointBetween : dist; ctx.font = size + 'px ' + this.fontFamily; ctx.translate(p0.x, p0.y); ctx.rotate(angle); ctx.fillText(p0.letter, 0, 0); ctx.restore(); } points.pop(); }, _updatePoint: function(p) { var friction = 1 - this.friction, px = p.px, py = p.py; p.px = p.x; p.py = p.y; if (p.fixed) return; p.x += (p.x - px) * friction; p.y += (p.y - py) * friction; } }; /** * Point */ function Point(letter, between, x, y) { this.letter = letter || ''; this.between = between || 0; this.x = this.px = x || 0; this.y = this.py = y || 0; } Point.prototype = { letter: '', between: 1, x: 0, y: 0 }; return ElasticString;
})(document);
(function(window, document) { 'use strict'; // Configs var TEXT = 'The quick brown fox jumps over the lazy dog.', FONT_SIZE = 25; // Vars var canvas, context, elasticString, mouse = { x: 0, y: 0 }, drag = null, gui, guiOptions; // Init function init() { var pos = [], i, len; canvas = document.getElementById('c'); context = canvas.getContext('2d'); resize(null); elasticString = new ElasticString(FONT_SIZE, 'Georgia, serif'); for (i = 0, len = TEXT.length; i < len; i++) { if (i === 0) pos.push([100, 100]); else pos.push([canvas.width * Math.random(), canvas.height * Math.random()]); } elasticString.setText(TEXT, pos); window.addEventListener('resize', resize, false); canvas.addEventListener('mousemove', mouseMove, false); canvas.addEventListener('mousedown', mouseDown, false); document.body.addEventListener('mouseup', mouseUp, false); // GUI guiOptions = { text: elasticString.getText(), fontSize: elasticString.getFontSize() }; gui = new dat.GUI(); gui.add(guiOptions, 'text').onFinishChange(function() { elasticString.setText(guiOptions.text); }); gui.add(guiOptions, 'fontSize', 1, 50).onChange(function() { elasticString.setFontSize(guiOptions.fontSize); }); gui.add(elasticString, 'friction', 0, 1); gui.add(elasticString, 'spring', 0, 1); gui.close(); update(); } // Event Listeners function resize(e) { canvas.width = window.innerWidth; canvas.height = window.innerHeight; context.fillStyle = '#3a3a2c'; } function mouseMove(e) { mouse.x = e.clientX; mouse.y = e.clientY; } function mouseDown(e) { var points = elasticString.points, p, hit = null, rangeSq = FONT_SIZE * FONT_SIZE, hitNear = FONT_SIZE * FONT_SIZE, mx = e.clientX, my = e.clientY, dx, dy, distSq, i, len; for (i = 0, len = points.length; i < len; i++) { p = points[i]; dx = mx - p.x; dy = my - p.y; distSq = dx * dx + dy * dy; if (distSq < rangeSq && distSq < hitNear) { hitNear = distSq; hit = points[i]; } } drag = hit; } function mouseUp(e) { drag = null; } // Update function update() { var points = elasticString.points, p, w = canvas.width, h = canvas.height, i, len; if (drag) { drag.x = mouse.x; drag.y = mouse.y; } for (i = 0, len = points.length; i < len; i++) { p = points[i]; if (0 > p.x) p.x = 0; if (w < p.x) p.x = w; if (0 > p.y) p.y = 0; if (h < p.y) p.y = h; } context.clearRect(0, 0, canvas.width, canvas.height); elasticString.render(context); requestAnimationFrame(update); } // Run init();
})(window, document);

Developer | Akimitsu Hamamuro |
Username | akm2 |
Uploaded | June 13, 2022 |
Rating | 4 |
Size | 17,622 Kb |
Views | 60,690 |
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 |
Lightning | 19,150 Kb |
WonderHTML5Wall | 8,439 Kb |
Abstriangulation | 5,794 Kb |
Painting | 18,358 Kb |
Dat.GUI | 14,895 Kb |
Duotone Sketch | 56,080 Kb |
Gravity Points | 5,148 Kb |
Noise Abstraction | 16,664 Kb |
Kira Kira Particle Effects | 4,616 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 |
CSS3 Snow Animation | NickyCDK | 1,695 Kb |
LBCA - Mail canvas | Emnbdx | 3,856 Kb |
This in constructor context | _shree33 | 1,718 Kb |
Google Maps API Ground Overlay | Boycetrus | 2,961 Kb |
Toggle menu | Seyedi | 2,279 Kb |
Formations | Cantelope | 5,731 Kb |
Wikipedia viewer | Chpecson | 2,865 Kb |
Owl Carousel - jumpTo | OwlFonk | 2,553 Kb |
404 Error Page | WebSonick | 3,203 Kb |
SCSS Simple Animated Drop-In | Danwarfel | 2,175 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!