|
1
|
|
|
<?php |
|
2
|
|
|
namespace nstdio\svg\filter; |
|
3
|
|
|
use nstdio\svg\container\ContainerInterface; |
|
4
|
|
|
use nstdio\svg\ElementInterface; |
|
5
|
|
|
use nstdio\svg\light\PointLight; |
|
6
|
|
|
|
|
7
|
|
|
/** |
|
8
|
|
|
* Class DiffuseLighting |
|
9
|
|
|
* This filter primitive lights an image using the alpha channel as a bump map. The resulting image is an RGBA opaque |
|
10
|
|
|
* image based on the light color with alpha = 1.0 everywhere. The lighting calculation follows the standard diffuse |
|
11
|
|
|
* component of the Phong lighting model. The resulting image depends on the light color, light position and surface |
|
12
|
|
|
* geometry of the input bump map. |
|
13
|
|
|
* |
|
14
|
|
|
* The light map produced by this filter primitive can be combined with a texture image using the multiply term of the |
|
15
|
|
|
* arithmetic ‘feComposite’ compositing method. Multiple light sources can be simulated by adding several of these |
|
16
|
|
|
* light maps together before applying it to the texture image. |
|
17
|
|
|
* |
|
18
|
|
|
* The light source is defined by one of the child elements ‘feDistantLight’, ‘fePointLight’ or ‘feSpotLight’. The |
|
19
|
|
|
* light color is specified by property ‘lighting-color’. |
|
20
|
|
|
* |
|
21
|
|
|
* @link https://www.w3.org/TR/SVG11/filters.html#feDiffuseLightingElement |
|
22
|
|
|
* @property float $surfaceScale = "<number>" height of surface when Ain = 1. If the attribute is not specified, |
|
23
|
|
|
* then |
|
24
|
|
|
* the effect is as if a value of 1 were specified. |
|
25
|
|
|
* @property float $diffuseConstant = "<number>" kd in Phong lighting model. In SVG, this can be any non-negative |
|
26
|
|
|
* number. If the attribute is not specified, then the effect is as if a value of 1 were specified. |
|
27
|
|
|
* @property float $kernelUnitLength = "<number-optional-number>" The first number is the <dx> value. The second number |
|
28
|
|
|
* is the <dy> value. If the <dy> value is not specified, it defaults to the same value as <dx>. Indicates |
|
29
|
|
|
* the intended distance in current filter units (i.e., units as determined by the value of attribute |
|
30
|
|
|
* ‘primitiveUnits’) for dx and dy, respectively, in the surface normal calculation formulas. By specifying |
|
31
|
|
|
* value(s) for ‘kernelUnitLength’, the kernel becomes defined in a scalable, abstract coordinate system. If |
|
32
|
|
|
* ‘kernelUnitLength’ is not specified, the dx and dy values should represent very small deltas relative to a |
|
33
|
|
|
* given (x,y) position, which might be implemented in some cases as one pixel in the intermediate image |
|
34
|
|
|
* offscreen bitmap, which is a pixel-based coordinate system, and thus potentially not scalable. For some |
|
35
|
|
|
* level of consistency across display media and user agents, it is necessary that a value be provided for at |
|
36
|
|
|
* least one of ‘filterRes’ and ‘kernelUnitLength’. Discussion of intermediate images are in the Introduction |
|
37
|
|
|
* and in the description of attribute ‘filterRes’. |
|
38
|
|
|
* @package nstdio\svg\filter |
|
39
|
|
|
* @author Edgar Asatryan <[email protected]> |
|
40
|
|
|
*/ |
|
41
|
|
|
class DiffuseLighting extends BaseFilter |
|
42
|
|
|
{ |
|
43
|
2 |
|
public function __construct(ElementInterface $parent) |
|
44
|
|
|
{ |
|
45
|
2 |
|
parent::__construct($parent); |
|
46
|
2 |
|
$this->apply([ |
|
47
|
2 |
|
'in' => 'SourceGraphic', |
|
48
|
2 |
|
'result' => 'light', |
|
49
|
|
|
'lighting-color' => 'white' |
|
50
|
2 |
|
]); |
|
51
|
2 |
|
} |
|
52
|
|
|
|
|
53
|
|
|
/** |
|
54
|
|
|
* @inheritdoc |
|
55
|
|
|
*/ |
|
56
|
2 |
|
public function getName() |
|
57
|
|
|
{ |
|
58
|
2 |
|
return "feDiffuseLighting"; |
|
59
|
|
|
} |
|
60
|
|
|
|
|
61
|
1 |
|
public static function diffusePointLight(ContainerInterface $container, array $pointLightConfig, array $diffuseLightingConfig = [], $filterId = null) |
|
62
|
|
|
{ |
|
63
|
1 |
|
$filter = self::filterWithOptions($container, ['id' => $filterId]); |
|
64
|
|
|
|
|
65
|
1 |
|
$diffLight = (new DiffuseLighting($filter))->apply($diffuseLightingConfig); |
|
66
|
1 |
|
(new PointLight($diffLight))->apply($pointLightConfig); |
|
67
|
1 |
|
(new Composite($filter))->apply(['in2' => $diffLight->result, 'operator' => 'arithmetic', 'k1' => 1]); |
|
|
|
|
|
|
68
|
|
|
|
|
69
|
1 |
|
return $filter; |
|
70
|
|
|
} |
|
71
|
|
|
} |
If you access a property on an interface, you most likely code against a concrete implementation of the interface.
Available Fixes
Adding an additional type check:
Changing the type hint: