< html > < body style =' background - color : black '> < canvas id =' myCanvas ' width =' 600 ' height =' 800 '></ canvas > < script > const text = ' old school sine scroller another cool javascript tutorial '; const fontWidth = 54 ; const fontHeight = 71 ; const letters = 12 ; let x = []; let char = []; let wiggle = 0 ; let counter = 0 ; let position = letters ; let bitmap = new Image (); bitmap . src = ' font . png '; let canvas = document . getElementById (' myCanvas '); let context = canvas . getContext ('2d'); for ( let n = 0 ; n < letters ; n ++) { char [ n ] = text . charCodeAt ( n ) - 97 ; x [ n ] = n * fontWidth ; } window . requestAnimationFrame ( scroll ); function scroll () { context . clearRect ( 0 , 0 , canvas . width , canvas . height ); for ( let n = 0 ; n < letters ; n ++) { let y = 100 + wiggle * Math . sin ( n + counter / 6 . 28 ); context . drawImage ( bitmap , char [ n ] * fontWidth , 0 , fontWidth , fontHeight , x [ n ], y , fontWidth , fontHeight ); x [ n ]--; if ( x [ n ] < - fontWidth ) { x [ n ] = ( letters - 1 ) * fontWidth ; char [ n ] = text . charCodeAt ( position ) - 97 ; position ++; if ( position > text . length ) position = 0 ; } } if ( counter > 200 && wiggle < 30 ) wiggle = wiggle + . 1 ; counter ++; window . requestAnimationFrame ( scroll ); } </ script > </ body ></ html >

Remember the sine scroller effect from 8-bit demos and intros in the 90's?They were done in hundreds of lines of machine code, with hardware interrupts and pre-calculated sine tables. Here is an example in about 30 lines of pure JavaScript.We need a bitmap image with a fixed-width font (also called mono-spaced or non-proportional). That means that each letter has the same width in pixels, which will greatly simplify our calculations. This paragraph uses a proportional font, so 'w' is wider than 'i'. The code example in the table uses a non-proportional font.The font above was ripped from some intro for the legendary Commodore 64 (I found it in the C-64 logo generator , but you can also just type in the alphabet in another font in an image editor and save it as a bitmap).Now we're ready for the code:The main program just initializes the variables:Lines 1-3: The HTML5 setup5: The text of of our scroll. A couple of spaces in front so that it starts on the right hand side of the screen.6-7: width and height of the font, in pixels8: the number of letters to be scrolled9: the array of the x coordinate of the letters10: the character at a given position11: the wiggle (amplitude) factor - we start with a flat line12: time counter13: the current position in the text14-15: source image (not visible on the screen)16-17: target canvas18-21: set the first set of characters and their x coordinates22: start the scroll animationAll the real action is in the scroll function:25: clear the previous frame26: for each letter:27: calculate the y coordinate using the sine function28: copy the character from the bitmap to the canvas.This line is a little complicated, so let's look at the arguments in detail:bitmap - source bitmapchar[n] * fontWidth, 0 - top-left corner coordinates of the source image of the n-th characterfontWidth, fontHeight - size of the source image (one character)x[n], y - coordinates of the target location on the canvasfontWidth, fontHeight - size of the copy (also one character)29: move the letter to the left30-33: if the letter moved off of the screen to the left, put it back on the right hand side and assign the next character from the scroll text32: convert the JavaScript (ASCII) character to the 0-23 range: a is 0, b is 1 and so on.34: restart if end of text reached37: the wiggle factor determines the amplitude of the sine wave. We started with zero - flat line. When the counter reaches 200, we start increasing the amplitutde, until we reach the maximum value of 30.38: increase the counter in each animation frame39: request another frameThere is a lot of things you can add to this code:- non-alpha character handling (numbers, comma, period etc.)- control the speed of the scroll with the text (eg. speed up when the next letter is '@', slow down if it's '#')- control the amplitude with the text- calculate individual y coordinate for each vertical line of pixels (instead of each letter)Enjoy!Check out these programming tutorials: