Animation   A
last analyzed

Coupling/Cohesion

Components 1
Dependencies 8

Complexity

Total Complexity 22

Size/Duplication

Total Lines 205
Duplicated Lines 0 %

Test Coverage

Coverage 95%

Importance

Changes 0
Metric Value
wmc 22
lcom 1
cbo 8
dl 0
loc 205
ccs 76
cts 80
cp 0.95
rs 10
c 0
b 0
f 0

14 Methods

Rating   Name   Duplication   Size   Complexity  
A run() 0 11 2
A speed() 0 6 1
A __construct() 0 10 1
A scroll() 0 16 2
A exitTo() 0 6 1
A enterFrom() 0 6 1
A getScrollDirectionMapping() 0 11 1
A getLines() 0 4 1
A setSleeper() 0 4 2
A setKeyFrames() 0 4 2
A setupKeyframes() 0 5 1
A animate() 0 10 2
A writeKeyFrame() 0 7 2
A getLineFormatted() 0 21 3
1
<?php
2
3
namespace League\CLImate\TerminalObject\Dynamic;
4
5
use League\CLImate\TerminalObject\Dynamic\Animation\Keyframe;
6
use League\CLImate\TerminalObject\Helper\Art;
7
use League\CLImate\TerminalObject\Helper\Sleeper;
8
9
class Animation extends DynamicTerminalObject
10
{
11
    use Art;
12
13
    /**
14
     * @var \League\CLImate\TerminalObject\Helper\Sleeper $sleeper
15
     */
16
    protected $sleeper;
17
18
    /**
19
     * @var \League\CLImate\TerminalObject\Dynamic\Animation\Keyframe $keyframes
20
     */
21
    protected $keyframes;
22
23 60
    public function __construct($art, Sleeper $sleeper = null, Keyframe $keyframes = null)
24
    {
25
        // Add the default art directory
26 60
        $this->addDir(__DIR__ . '/../../ASCII');
27
28 60
        $this->setSleeper($sleeper);
29 60
        $this->setKeyFrames($keyframes);
30
31 60
        $this->art = $art;
32 60
    }
33
34
    /**
35
     * Run a basic animation
36
     */
37 4
    public function run()
38
    {
39 4
        $files     = $this->artDir($this->art);
40 4
        $animation = [];
41
42 4
        foreach ($files as $file) {
43 4
            $animation[] = $this->parse($file);
44 4
        }
45
46 4
        $this->animate($animation);
47 4
    }
48
49
    /**
50
     * Set the speed of the animation based on a percentage
51
     * (50% slower, 200% faster, etc)
52
     *
53
     * @param int|float $percentage
54
     *
55
     * @return \League\CLImate\TerminalObject\Dynamic\Animation
56
     */
57
    public function speed($percentage)
58
    {
59
        $this->sleeper->speed($percentage);
60
61
        return $this;
62
    }
63
64
    /**
65
     * Scroll the art
66
     *
67
     * @param string $direction
68
     * @return bool
69
     */
70 20
    public function scroll($direction = 'right')
71
    {
72 20
        $this->setupKeyframes();
73
74 20
        $mapping = $this->getScrollDirectionMapping();
75
76 20
        if (!array_key_exists($direction, $mapping)) {
77
            return false;
78
        }
79
80 20
        $lines       = $this->getLines();
81 20
        $enter_from  = $mapping[$direction];
82 20
        $exit_to     = $mapping[$enter_from];
83
84 20
        $this->animate($this->keyframes->scroll($lines, $enter_from, $exit_to));
85 20
    }
86
87
    /**
88
     * Animate the art exiting the screen
89
     *
90
     * @param string $direction top|bottom|right|left
91
     */
92 16
    public function exitTo($direction)
93
    {
94 16
        $this->setupKeyframes();
95
96 16
        $this->animate($this->keyframes->exitTo($this->getLines(), $direction));
97 16
    }
98
99
    /**
100
     * Animate the art entering the screen
101
     *
102
     * @param string $direction top|bottom|right|left
103
     */
104 20
    public function enterFrom($direction)
105
    {
106 20
        $this->setupKeyframes();
107
108 20
        $this->animate($this->keyframes->enterFrom($this->getLines(), $direction));
109 20
    }
110
111 20
    protected function getScrollDirectionMapping()
112
    {
113
        return [
114 20
            'left'   => 'right',
115 20
            'right'  => 'left',
116 20
            'top'    => 'bottom',
117 20
            'bottom' => 'top',
118 20
            'up'     => 'bottom',
119 20
            'down'   => 'top',
120 20
        ];
121
    }
122
123 56
    protected function getLines()
124
    {
125 56
        return $this->parse($this->artFile($this->art));
126
    }
127
128
    /**
129
     * @param \League\CLImate\TerminalObject\Helper\Sleeper $sleeper
130
     */
131 60
    protected function setSleeper($sleeper = null)
132
    {
133 60
        $this->sleeper = $sleeper ?: new Sleeper();
134 60
    }
135
136
    /**
137
     * @param League\CLImate\TerminalObject\Dynamic\Animation\Keyframe $keyframes
138
     */
139 60
    protected function setKeyFrames($keyframes)
140
    {
141 60
        $this->keyframes = $keyframes ?: new Keyframe;
142 60
    }
143
144
    /**
145
     * Set up the necessary properties on the Keyframe class
146
     */
147 56
    protected function setupKeyframes()
148
    {
149 56
        $this->keyframes->parser($this->parser);
150 56
        $this->keyframes->util($this->util);
151 56
    }
152
153
    /**
154
     * Animate the given keyframes
155
     *
156
     * @param array $keyframes Array of arrays
157
     */
158 60
    protected function animate(array $keyframes)
159
    {
160 60
        $count = 0;
161
162 60
        foreach ($keyframes as $lines) {
163 60
            $this->writeKeyFrame($lines, $count);
164 60
            $this->sleeper->sleep();
165 60
            $count = count($lines);
166 60
        }
167 60
    }
168
169
    /**
170
     * Write the current keyframe to the terminal, line by line
171
     *
172
     * @param array $lines
173
     * @param integer $count
174
     */
175 60
    protected function writeKeyFrame(array $lines, $count)
176
    {
177 60
        foreach ($lines as $key => $line) {
178 60
            $content = $this->getLineFormatted($line, $key, $count);
179 60
            $this->output->write($this->parser->apply($content));
180 60
        }
181 60
    }
182
183
    /**
184
     * Format the line to re-write previous lines, if necessary
185
     *
186
     * @param string $line
187
     * @param integer $key
188
     * @param integer $last_frame_count
189
     *
190
     * @return string
191
     */
192 60
    protected function getLineFormatted($line, $key, $last_frame_count)
193
    {
194
        // If this is the first thing we're writing, just return the line
195 60
        if ($last_frame_count == 0) {
196 60
            return $line;
197
        }
198
199 60
        $content = '';
200
201
        // If this is the first line of the frame,
202
        // move the cursor up the total number of previous lines from the previous frame
203 60
        if ($key == 0) {
204 60
            $content .= $this->util->cursor->up($last_frame_count);
205 60
        }
206
207 60
        $content .= $this->util->cursor->startOfCurrentLine();
208 60
        $content .= $this->util->cursor->deleteCurrentLine();
209 60
        $content .= $line;
210
211 60
        return $content;
212
    }
213
}
214