Completed
Pull Request — master (#1868)
by Basil
22:35
created

LazyLoad   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 149
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
wmc 10
lcom 1
cbo 5
dl 0
loc 149
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
B init() 0 72 3
B run() 0 25 7
1
<?php
2
3
namespace luya\lazyload;
4
5
use luya\base\Widget;
6
use yii\base\InvalidConfigException;
7
use yii\helpers\Html;
8
use luya\web\View;
9
10
/**
11
 * Image Lazy Loader.
12
 *
13
 * ```php
14
 * <?= LazyLoad::widget(['src' => 'http://www.zephir.ch/img/zephir-logo.png']); ?>
15
 * ```
16
 *
17
 * In order to read more visit the [[concept-lazyload.md]] guide section.
18
 *
19
 * @author Basil Suter <[email protected]>
20
 * @author Marc Stampfli <[email protected]>
21
 * @since 1.0.0
22
 */
23
class LazyLoad extends Widget
24
{
25
    const JS_ASSET_KEY = 'lazyload.js.register';
26
27
    const CSS_ASSET_KEY = 'lazyload.css.register';
28
    const CSS_ASSET_KEY_PLACEHOLDER = 'lazyload.placeholder.css.register';
29
30
    /**
31
     * @var string The path to the image you want to lazy load.
32
     */
33
    public $src;
34
35
    /**
36
     * @var string Path for the placeholder image that will be base64 encoded.
37
     * @since 1.0.13
38
     */
39
    public $placeholderSrc;
40
41
    /**
42
     * @var boolean Inline the placeholder source as base64 encoded string
43
     * @since 1.0.13
44
     */
45
    public $placeholderAsBase64 = false;
46
47
    /**
48
     * @var integer The width of the image, this information should be provided in order to display a placeholder.
49
     */
50
    public $width;
51
52
    /**
53
     * @var integer The height of the image, this information should be provided in order to display a placeholder.
54
     */
55
    public $height;
56
57
    /**
58
     * @var boolean Define whether a full image tag should be return or only the attributes. This can be applied when using the lazy loader in background images.
59
     */
60
    public $attributesOnly = false;
61
62
    /**
63
     * @var string Additional classes for the lazy load image.
64
     */
65
    public $extraClass;
66
67
    /**
68
     * @inheritdoc
69
     */
70
    public function init()
71
    {
72
        parent::init();
73
74
        if ($this->src === null) {
75
            throw new InvalidConfigException("The parameter src is required by the lazyload widget.");
76
        }
77
78
        // register the asset file
79
        LazyLoadAsset::register($this->view);
80
81
        // register js and css code with keys in order to ensure the registration is done only once
82
        $this->view->registerJs("$('.lazy-image').lazyLoad();", View::POS_READY, self::JS_ASSET_KEY);
83
84
        if ($this->placeholderSrc) {
85
            $this->view->registerCss("
86
                .lazyimage-wrapper {
87
                    display: block;
88
                    width: 100%;
89
                    position: relative;
90
                    overflow: hidden;
91
                }
92
                .lazyimage {
93
                    position: absolute;
94
                    top: 50%;
95
                    left: 50%;
96
                    bottom: 0;
97
                    right: 0;
98
                    opacity: 0;
99
                    height: 100%;
100
                    width: 100%;
101
                    -webkit-transition: 1s ease-in-out opacity;
102
                    transition: 1s ease-in-out opacity;
103
                    -webkit-transform: translate(-50%,-50%);
104
                    transform: translate(-50%,-50%);
105
                    -o-object-fit: cover;
106
                    object-fit: cover;
107
                    -o-object-position: center center;
108
                    object-position: center center;
109
                    z-index: 20;
110
                }
111
                .lazyimage.loaded {
112
                    opacity: 1;
113
                }
114
                .lazyimage-placeholder-image {
115
                    display: block;
116
                    width: 100%;
117
                    height: auto;
118
                }
119
                .nojs .lazyimage,
120
                .nojs .lazyimage-placeholder-image,
121
                .no-js .lazyimage,
122
                .no-js .lazyimage-placeholder-image {
123
                    display: none;
124
                }
125
            ", [], self::CSS_ASSET_KEY_PLACEHOLDER);
126
        } else {
127
            $this->view->registerCss("
128
                .lazy-image {
129
                    display: none;
130
                }
131
                .lazy-image.loaded {
132
                    display: block;
133
                }
134
                .lazy-placeholder {
135
                    background-color: #f2f2f2;
136
                    position: relative;
137
                    display: block;
138
                }
139
            ", [], self::CSS_ASSET_KEY);
140
        }
141
    }
142
143
    /**
144
     * @inheritdoc
145
     */
146
    public function run()
147
    {
148
        $class = ($this->placeholderSrc ? 'lazyimage-wrapper' : 'lazy-image') . ' ' . $this->extraClass;
149
150
        if ($this->placeholderSrc && $this->placeholderAsBase64) {
151
            $this->placeholderSrc = 'data:image/jpg;base64,' . base64_encode(file_get_contents($this->placeholderSrc));
152
        }
153
154
        if ($this->attributesOnly && !$this->placeholderSrc) {
155
            return "class=\"{$class}\" data-src=\"$this->src\" data-width=\"$this->width\" data-height=\"$this->height\" data-as-background=\"1\"";
156
        }
157
158
        if ($this->placeholderSrc) {
159
            $tag = '<div class="' . $class . '">';
160
            $tag .= Html::tag('img', '', ['class' => 'lazy-image lazyimage', 'data-src' => $this->src]);
161
            $tag .= Html::tag('img', '', ['class' => 'lazyimage-placeholder-image', 'src' => $this->placeholderSrc]);
162
            $tag .= '<noscript><img class="lazyimage-image" src="' . $this->src . '" /></noscript>';
163
            $tag .= '</div>';
164
        } else {
165
            $tag = Html::tag('img', '', ['class' => $class, 'data-src' => $this->src, 'data-width' => $this->width, 'data-height' => $this->height]);
166
            $tag .= '<noscript><img class="'.$class.'" src="'.$this->src.'" /></noscript>';
167
        }
168
169
        return $tag;
170
    }
171
}
172