Elastic String

Size
17,622 Kb
Views
60,720

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 Previews

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);
Elastic String - Script Codes
Elastic String - Script Codes
Home Page Home
Developer Akimitsu Hamamuro
Username akm2
Uploaded June 13, 2022
Rating 4
Size 17,622 Kb
Views 60,720
Do you need developer help for Elastic String?

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!

Akimitsu Hamamuro (akm2) Script Codes
Create amazing marketing copy with AI!

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!