This is definitely not smooth on iOS, on a brand new iPhone that’s arguably way faster than whatever system played the original DVD screensaver.
On a technical note, not that there’s much you can do about this, but because you’re reading clientWidth and clientHeight each frame, you’re forcing reflow. A performant implementation would probably require avoiding the DOM altogether within the draw loop, so that would mean using canvas/webgl.