Hey Folks,
Finishing my first Phoenix/LiveView web app and about to deploy. I’ve got to say I’m really impressed with the DOM patching and LiveView in general. Really excited to see how this tech evolves. I had a few questions regarding Javascript and best practices.
For the most part, LiveView has eliminated the majority of my client side code but there were a few places where I had to write Javascript. I’ve got a reusable LiveComponent that acts as a top navigation on certain pages. The titles are implemented with an SVG animation that utilizes the snapsvg-cjs
npm module. I’ve installed the module, and added the animation code to the bottom of app.js
:
import Snap from "snapsvg-cjs";
function play(title) {
var l = Snap('#logo');
l.clear();
setTimeout( function() {
var logoTitle = title;
var logoRandom = '';
var logoTitleContainer = l.text(0, '98%', '');
var possible = "-+*/|}{[]~\\\":;?/.><=+-_)(*&^%$#@!)}";
logoTitleContainer.attr({
fontSize: 150,
fontFamily: 'Dosis',
fontWeight: '600'
});
function generateRandomTitle(i, logoRandom) {
setTimeout( function() {
logoTitleContainer.attr({ text: logoRandom });
}, i*70 );
}
for( var i=0; i < logoTitle.length+1; i++ ) {
logoRandom = logoTitle.substr(0, i);
for( var j=i; j < logoTitle.length; j++ ) {
logoRandom += possible.charAt(Math.floor(Math.random() * possible.length));
}
generateRandomTitle(i, logoRandom);
logoRandom = '';
}
}, 500 );
}
I then pass the function to the .html.leex
template via window.navAnimation = play('Test Title')
and in a <script>
tag inside the template, I assign it to the window.onload
event. I’ve seen a lot of conversation surrounding Javascript and using npm modules with webpack and inside .html.leex
templates, but all solutions discussed feel just as hacky as the way I’ve done it here. So with that said I have a few questions:
- First and foremost, is there a way to do text animations without javascript? I.e. is there a preexisting LiveView or Phoenix functionality that can do what I’m trying to do without passing things through
window
or even using javascript at all? - If not, is there a cleaner more modular way to do this with javascript?
- If this is the cleanest/best practice/common way to do this, I can’t seem to pass in a method parameter inside the
.html.leex
template. Trying to set the title of theplay(title)
function inside the template results in this client side error:window.onload = window.navAnimation('Test Title');
→Uncaught TypeError: window.play is not a function
. What’s wrong with my syntax, please explain?
Thanks,
Scott