Skip to content

Instantly share code, notes, and snippets.

@akashraj9828
Created May 17, 2020 19:41
Show Gist options
  • Save akashraj9828/e27325a6e7edac7d71adc5e4b8f416a5 to your computer and use it in GitHub Desktop.
Save akashraj9828/e27325a6e7edac7d71adc5e4b8f416a5 to your computer and use it in GitHub Desktop.
SVG TEXT ANIMATION GENERATOR
<h1 class="msg">SVG TEXT ANIMATION GENERATOR</h1>
<div class="settings">
<div>
<label>Font:<select id="font-select"></select></label>
<label>Variant:<select id="font-variant"></select></label>
</div>
<div>
<label>Text: <input type="text" id="input-text" value="AKASH"></label>
<label>Size: <input type="number" id="input-size" value="100"></label>
</div>
<div>
<label class="hidden">Union: <input type="checkbox" id="input-union"></label>
<label>Bezier accuracy: <input type="text" id="input-bezier-accuracy" placeholder="auto"></label>
<label>Delay(s): <input type="text" checked id="input-delay" value="0.1"></label>
</div>
<div>
<label>Animation duration(s): <input type="text" id="input-duration" placeholder="auto"></label>
<label>Separate characters: <input type="checkbox" checked id="input-separate"></label>
</div>
</div>
<div id="svg-container"></div>
<div class="code">
<div class="svg-js">
<div id="svg">
<h4>SVG</h4>
<textarea rows=4 id="output-svg" spellcheck="false"></textarea>
</div>
<div id="js">
<h4>JS</h4>
<pre id="output-js"></pre>
</div>
</div>
<div id="css">
<h4>CSS</h4>
<pre id="output-css"></pre>
</div>
</div>
<footer><span>With <span class="heart">❤</span>
by <a href="https://akashraj.tech">Akash Raj</a></span></footer>
var makerjs = require('makerjs');
function setAnimation(del = 0.1, dur = 'auto') {
let paths = document.querySelectorAll("path");
let i = 0;
let delay = del == 'auto' || del === '' ? 0.2 : parseFloat(del);
let duration = dur == 'auto' || dur == '' ? paths.length * delay + 1 : parseFloat(dur);
let strokeWidth = 2;
for (path of paths) {
let length = path.getTotalLength();
path.style["stroke-dashoffset"] = `${length}px`;
path.style["stroke-dasharray"] = `${length}px`;
path.style["stroke-width"] = `${strokeWidth}px`;
path.style["animation"] = `${duration}s reveal infinite linear`;
path.style["animation-delay"] = `${i * delay}s`;
i++;
}
//delete this
setOutput()
}
function setOutput(){
document.getElementById("output-js").innerText=setAnimation.toString()
document.getElementById("output-css").innerText=`#svg-container svg g path {
animation: reveal infinite 3s;
}
@keyframes reveal {
50% {
stroke-dashoffset: 0;
fill: transparent;
}
100% {
stroke-dashoffset: 0;
fill: yellow;
}
}
`
}
var App = /** @class */ (function () {
function App() {
var _this = this;
this.renderCurrent = function () {
var size = _this.sizeInput.valueAsNumber;
if (!size)
size = parseFloat(_this.sizeInput.value);
if (!size)
size = 100;
_this.render(_this.selectFamily.selectedIndex, _this.selectVariant.selectedIndex, _this.textInput.value, size, _this.unionCheckbox.checked, _this.separateCheckbox.checked, parseFloat(_this.bezierAccuracy.value) || undefined);
};
this.loadVariants = function () {
_this.selectVariant.options.length = 0;
var f = _this.fontList.items[_this.selectFamily.selectedIndex];
var v = f.variants.forEach(function (v) { return _this.addOption(_this.selectVariant, v); });
_this.renderCurrent();
};
}
App.prototype.init = function () {
this.selectFamily = this.$('#font-select');
this.selectVariant = this.$('#font-variant');
this.unionCheckbox = this.$('#input-union');
this.separateCheckbox = this.$('#input-separate');
this.textInput = this.$('#input-text');
this.bezierAccuracy = this.$('#input-bezier-accuracy');
this.sizeInput = this.$('#input-size');
this.inputDelay = this.$('#input-delay');
this.inputDuration = this.$('#input-duration');
this.renderDiv = this.$('#svg-container');
this.outputTextarea = this.$('#output-svg');
};
App.prototype.handleEvents = function () {
this.selectFamily.onchange = this.loadVariants;
this.selectVariant.onchange = this.renderCurrent;
this.textInput.onchange = this.renderCurrent;
this.textInput.onkeyup = this.renderCurrent;
this.sizeInput.onchange = this.renderCurrent;
this.unionCheckbox.onchange = this.renderCurrent;
this.separateCheckbox.onchange = this.renderCurrent;
this.bezierAccuracy.onchange = this.renderCurrent;
this.inputDelay.onchange = this.renderCurrent;
this.inputDuration.onchange = this.renderCurrent;
};
App.prototype.$ = function (selector) {
return document.querySelector(selector);
};
App.prototype.addOption = function (select, optionText) {
var option = document.createElement('option');
option.text = optionText;
select.options.add(option);
};
App.prototype.getGoogleFonts = function (apiKey) {
var _this = this;
var xhr = new XMLHttpRequest();
xhr.open('get', 'https://www.googleapis.com/webfonts/v1/webfonts?key=' + apiKey, true);
xhr.onloadend = function () {
_this.fontList = JSON.parse(xhr.responseText);
_this.fontList.items.forEach(function (font) { return _this.addOption(_this.selectFamily, font.family); });
_this.loadVariants();
_this.handleEvents();
};
xhr.send();
};
App.prototype.render = function (fontIndex, variantIndex, text, size, union, separate, bezierAccuracy) {
var _this = this;
var f = this.fontList.items[fontIndex];
var v = f.variants[variantIndex];
var url = f.files[v].substring(5); //remove http:
opentype.load(url, function (err, font) {
//generate the text using a font
var textModel = new makerjs.models.Text(font, text, size, union, false, bezierAccuracy);
if (separate) {
for (var i in textModel.models) {
textModel.models[i].layer = i;
}
}
var svg = makerjs.exporter.toSVG(textModel);
_this.renderDiv.innerHTML = svg;
_this.outputTextarea.value = svg;
setAnimation(_this.inputDelay.value,_this.inputDuration.value);
});
};
return App;
}());
var app = new App();
window.onload = function () {
app.init();
app.getGoogleFonts('AIzaSyAOES8EmKhuJEnsn9kS1XKBpxxp-TgN8Jc');
setAnimation()
};
<script src="https://maker.js.org/target/js/browser.maker.js"></script>
<script src="https://pomax.github.io/bezierjs/bezier.js"></script>
<script src="https://danmarshall.github.io/google-font-to-svg-path/opentype.js"></script>
::-webkit-scrollbar {
display: none;
}
*{
margin:0;
padding:0;
box-sizing:border-box;
}
body {
background: pink;
display: flex;
flex-direction: column;
margin: 0;
padding: 0;
align-items: center;
justify-content: center;
min-height: 100vh;
box-sizing: border-box;
}
.msg {
color: rgba(0, 0, 0, 0.2);
text-align:center;
}
footer {
position: fixed;
bottom: 0;
right: 0;
padding: 0.5rem;
color: yellow;
transition: 0.5s;
background: darkgrey;
border-radius: 3px;
.heart {
transition: 0.5s;
}
&:hover {
.heart,
a {
color: pink;
}
}
a {
color: yellow;
text-decoration: none;
transition: 0.5s;
&:hover {
text-decoration: none;
}
}
}
#svg-container {
margin: 1rem;
padding:1rem;
svg {
g {
path {
animation: reveal infinite 3s;
}
}
}
}
@keyframes reveal {
50% {
stroke-dashoffset: 0;
fill: transparent;
}
100% {
stroke-dashoffset: 0;
fill: yellow;
}
}
.code {
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 10px;
padding: 10px;
}
#output-css,
#output-js,#output-svg {
padding: 10px;
border-radius:5px;
}
#output-js {
background: yellow;
}
#output-svg {
width: 100%;
background: lightblue;
}
#output-css {
background: lightblue;
}
.settings{
display:flex;
label{
font-weight:bold;
display:block;
margin:1rem .5rem;
}
input,select{
padding:.2rem .5rem;
border:0;
border-radius:5px;
width:100%;
&:focus,&:hover,&:active{
outline:none;
border-bottom:2px solid blue;
}
}
}
.hidden{
display:none!important;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment