public function render($placeholder = '.')
    {
        // Ensure that at least $this->interval microseconds have passed since
        // the last frame.
        if ($this->lastFrameTime !== null) {
            $timeSince = (microtime(true) - $this->lastFrameTime) * 1000000;
            if ($timeSince < $this->interval) {
                usleep($this->interval - $timeSince);
            }
        }

        if ($this->lastFrame !== null) {
            // If overwriting is not possible, just output the placeholder.
            if (!$this->output->isDecorated()) {
                $this->output->write($placeholder);
                $this->lastFrameTime = microtime(true);
                return;
            }

            // Move the cursor up to overwrite the previous frame.
            $lastFrameHeight = substr_count($this->frames[$this->lastFrame], "\n") + 1;
            $this->output->write(sprintf("\033[%dA", $lastFrameHeight));
        }

        // Display the current frame.
        $this->output->writeln($this->frames[$this->currentFrame]);

        // Set up the next frame.
        $this->lastFrame = $this->currentFrame;
        $this->lastFrameTime = microtime(true);
        $this->currentFrame++;
        if (!isset($this->frames[$this->currentFrame])) {
            $this->currentFrame = 0;
        }
    }