1657599240
Les filtres sont extrêmement populaires en photographie. Vous pouvez les trouver sur presque toutes les applications ou sites Web de retouche photo, et certains appareils photo ont des options de filtre intégrées pour que vous n'ayez pas à éditer les photos plus tard.
CSS a plusieurs filtres qui aident à améliorer les aspects visuels d'un site Web. Vous pouvez les appliquer directement à un élément Web à l'aide de la filter
propriété, ainsi qu'à la zone derrière l'élément avec la backdrop-filter
propriété.
Avec ces filtres, vous pouvez flouter une image, régler le contraste et la saturation, modifier la teinte, réduire l'opacité, et bien plus encore !
Dans cet article, nous allons en savoir plus sur un ensemble d'outils unique et puissant : les filtres SVG. Mais avant de continuer, faisons une petite introduction aux SVG.
Les SVG, ou Scalable Vector Graphics, sont un format d'image vectorielle basé sur XML pour afficher des graphiques en deux dimensions. XML est un autre acronyme sophistiqué qui signifie Extensible Markup Language. XML est utilisé pour stocker et transmettre des données, et définir vos balises.
Retour aux SVG. Un SVG sert à la fois de format d'image et de document. Les formats d'image standard tels que JPEG et PNG sont constitués de pixels qui perdent généralement en qualité lorsqu'ils sont agrandis.
Ce qui rend les SVG différents, c'est qu'ils conservent leur qualité, quel que soit l'ampleur du zoom. C'est possible parce qu'ils sont constitués de formules mathématiques.
Voyons ce qu'il y a sous le capot d'un SVG.
Commencez par ouvrir une image SVG dans un éditeur de code. Voici une capture d'écran de ce que vous pourriez trouver :
Ce code constitue une forme complexe. Nous pouvons contrôler la couleur, la taille et d'autres caractéristiques de l'image dans les lignes de code. Créons une forme plus simple, un cercle :
<body>
<svg width="400" height="400">
<circle cx="200" cy="200" r="100" fill="#553c9a">
</svg>
</body>
Et nous avons un cercle violet !
Nous pouvons transformer ce cercle en anneau en ajoutant une stroke
valeur. Un trait est la bordure et nous pouvons définir la fill
couleur sur transparent
.
<body>
<svg width="400" height="400">
<circle cx="200" cy="200" r="100" fill="transparent"
stroke="#553c9a" stroke-width="20px">
</svg>
</body>
Le résultat est celui-ci :
Des images complexes peuvent être créées en combinant différents SVG. Les SVG sont utilisés pour les icônes, les logos ou comme images d'arrière-plan. Ils peuvent aussi être animés !
Les filtres CSS sont principalement limités aux images et sont assez faciles à utiliser. Les filtres SVG, en revanche, peuvent être appliqués aux images (à la fois SVG et autres formats), au texte et à tous les autres éléments HTML. Les filtres CSS sont en fait un sous-ensemble de filtres SVG.
Les filtres SVG fonctionnent avec l' <filter>
élément et un ensemble de fonctions appelées primitives de filtre. Ces fonctions sont des éléments enfants qui créent des effets.
L' <filter>
élément sera référencé par la filter
propriété CSS via un fichier id
.
Pour commencer, créez un svg
élément avec un filter
élément imbriqué à l'intérieur. Ensuite, ajoutez les primitives avant l'image (ou tout autre élément auquel vous souhaitez appliquer le filtre).
Il y a 17 primitives de filtre, et ce sont :
feGaussianBlur
feDropShadow
feMorphology
feTurbulence
feDisplacementMap
feColorMatrix
feConvolveMatrix
feComponentTransfer
feOffset
feMerge
feFlood
feComposite
feImage
feBlend
feDiffuseLighting
feSpecularLighting
feTile
"fe" signifie effet de filtre. D'après les noms, nous pouvons avoir une idée des effets qu'ils produiront. Examinons une syntaxe de filtre SVG de base :
<svg>
<filter id="">
<!--Filter Primitives go in here-->
</filter>
</svg>
Chaque primitive SVG possède son propre ensemble unique d'attributs utilisés pour créer les effets. Certaines de ces primitives de filtrage fonctionnent bien par elles-mêmes, mais certaines doivent être combinées avec d'autres primitives.
Il y a beaucoup à couvrir, alors commençons.
feGaussianBlur
Les SVG sont basés sur des formules mathématiques, il est donc normal de faire avancer les choses avec un filtre de flou gaussien. Ce filtre porte le nom du regretté mathématicien Carl Friedrich Gauss et applique une fonction mathématique pour brouiller l'image.
Tout d'abord, vous aurez besoin d'une image. En voici un de freepik.com :
Ensuite, nous allons créer la syntaxe SVG dans le fichier HTML :
<svg>
<filter id="blur">
<feGaussianBlur stdDeviation="5" in="SourceGraphic" result="BLUR"></feGaussianBlur>
</filter>
<image
xlink:href="2833.jpg" filter="url(#blur)"></image>
</svg>
Maintenant, nous aurons la primitive de filtre SVG, feGaussianBlur
, dans l' filter
élément. Certains attributs à l'intérieur de la primitive auront un effet sur le flou produit.
Le premier attribut est stdDeviation
, qui régule la quantité de flou.
Vient ensuite in
, pour l'entrée, qui définit où le filtre sera appliqué. Dans ce cas, c'est le SourceGraphic
, qui est notre image. Il SourceGraphic
peut également s'agir de texte.
Le dernier attribut de cet exemple est result
. Nous l'utilisons pour nommer le filtre. Ceci est utile comme référence in
lorsque vous travaillez avec plusieurs filtres.
Voici l'image résultante avec le filtre appliqué :
Comme mentionné précédemment, les filtres SVG peuvent être appliqués en externe en utilisant la filter
propriété et un url
pointant vers un id
:
<svg>
<filter id="blur">
<feGaussianBlur stdDeviation="5"></feGaussianBlur>
</filter>
</svg>
Enfin, appliquez-le avec la filter
propriété CSS :
img{
width: 1000px;
height: auto;
filter: url(#blur);
}
feDropShadow
Ce filtre est assez simple et ajoute une ombre portée derrière un élément.
Commencez par la syntaxe :
<svg >
<filter id="blur">
<feDropShadow in="SourceGraphic" dx="10" dy="10"></feDropShadow>
</filter>
</svg>
Les attributs dx
et dy
définissent la position de l'ombre le long des axes x et y, respectivement. Le résultat est une ombre vraiment sombre derrière l'image :
feMorphology
La morphologie est l'étude de la forme, de la forme et de la structure. La feMorphology
primitive est utilisée pour changer, ou transformer, la forme des éléments.
Il fonctionne avec l' operator
attribut qui accepte l'une des deux valeurs, dilate
ou erode
, et a radius
qui définit la quantité de dilatation ou d'érosion. Pour dilate
, les pixels du SourceGraphic
sont étalés vers l'extérieur. erode
fait le contraire.
Comparons les deux. Tout d'abord c'est dilate
:
<svg>
<filter id="blur">
<feMorphology in="SourceGraphic" operator="dilate" radius="5">
</feMorphology>
</filter>
</svg>
Le résultat:
Voyons maintenant erode
:
<svg>
<filter id="blur">
<feMorphology in="SourceGraphic" operator="erode" radius="5">
</feMorphology>
</filter>
</svg>
Le résultat:
Où sont passées toutes les étoiles ?
D'après ces résultats, nous pouvons voir que dilate
produit une image plus vibrante par rapport à l'image assombrie et atténuée de erode
. La luminosité est due à l'expansion des pixels de l'image et vice versa.
feTurbulence
La seule véritable explication de l'effet de cette primitive de filtre est juste là dans son nom : la turbulence. Il utilise deux attributs : baseFrequency
et numOctaves
.
<feTurbulence in="SourceGRaphic" baseFrequency="0.01 0.02"
numOctaves="1" result="NOISE">
</feTurbulence>
Le résultat est un effet de bruit sur l'image :
Expliquons les attributs.
Le baseFrequency
contrôle la quantité de distorsion, ou de bruit, dans les directions x et y. Une baseFrequency
valeur élevée réduit la taille du motif de distorsion. Il peut contenir deux valeurs, et si une seule valeur est utilisée, elle couvre à la fois les axes x et y.
numOctaves
est également une fonction de bruit et contrôle le nombre d'octaves dans l'effet de filtre. En utilisant un baseFrequency
de "0.01 0.02"
, nous obtenons ce qui suit :
En fin de compte, c'est à vous de décider du nombre d'octaves et de la quantité de fréquence. Jouez avec les valeurs et voyez ce que vous proposez. Gardez à l'esprit qu'ils n'acceptent pas les valeurs négatives.
feDisplacementMap
Une carte de déplacement est une image utilisée pour modifier le contenu d'un autre élément. La texture d'un élément peut être appliquée à un autre.
Pour cette primitive de filtre SVG, nous aurons besoin de deux entrées : in
et in2
. L'un contiendra le graphique original et l'autre sera l'image servant de carte de déplacement.
<svg>
<filter id="turbulence">
<feTurbulence type="turbulence" baseFrequency="0.01 0.02" numOctaves="1" result="NOISE"></feTurbulence>
<feDisplacementMap in="SourceGraphic" in2="NOISE" scale="50">
</feDisplacementMap>
</filter>
</svg>
Maintenant pour le résultat. L'image suit le motif de distorsion créé par le feTurbulence
filtre :
Nous pouvons aller plus loin en ajoutant une animation ondulée pour compléter le look aqueux :
<svg>
<filter id="wavy">
<feTurbulence id="turbulence" type="turbulence" numOctaves="1"
result="NOISE"></feTurbulence>
<feDisplacementMap in="SourceGraphic" in2="NOISE" scale="50">
</feDisplacementMap>
<animate xlink:href="#turbulence" attributeName="baseFrequency" dur="60s" keyTimes="0;0.5;1"
values="0.01 0.02;0.02 0.04;0.01 0.02" repeatCount="indefinite"></animate>
</filter>
</svg>
Notez que la première primitive de filtre a maintenant un id
. C'est ce que nous animons.
Ensuite, nous utiliserons l' <animate>
élément pour définir l'animation. Cet élément contiendra xlink:href
, pointant vers le filtre qui sera animé. Après c'est attributeName
, et l'attribut primitif que nous animons est le baseFrequency
.
Ensuite, nous fixons la durée avec dur
et le keyTimes
. Ce sont essentiellement @keyframes
.
values
contiennent les nouvelles baseFrequency
valeurs des points d'arrêt définis avec keyTimes
.
Enfin, nous avons repeatCount
réglé pour indefinite
que l'effet tourne en boucle.
Et voici le résultat :
Nous pouvons également utiliser les propriétés régulières animation
et transition
CSS ou du JavaScript pour l'animation.
feColorMatrix
Ce filtre SVG permet de modifier la teinte et la saturation d'un élément. Il fonctionne avec un type
attribut et quatre valeurs possibles : matrix
, saturate
, hueRotate
et luminaceToAlpha
.
Pour matrix
, l'effet de filtre est appliqué à l'aide d'une matrice de couleurs RVBA, ou grille, pour son value
.
<svg>
<filter>
<feColorMatrix in="SourceGraphic" type="matrix"
values="1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0">
</filter>
</svg>
La syntaxe ci-dessus ne changera pas la couleur de l'image. Regardons chaque canal de couleur.
Jouez avec les valeurs et voyez quelles teintes, nuances et teintes vous pouvez trouver !
Ensuite, nous avons saturate
. Cela utilise values
entre 0 et 1 pour contrôler la quantité de noir et blanc dans l'image.
<svg>
<filter id="saturate">
<feColorMatrix in="SourceGraphic" type="saturate" values="0.5"/>
</filter>
</svg>
Le résultat:
La prochaine étape est hueRotate
. Cet attribut fait pivoter les couleurs de l'image autour de la roue chromatique selon un angle spécifique. Commençons par vous montrer la roue chromatique :
Utilisons maintenant l'attribut :
<feColorMatrix in="SourceGraphic" type="hueRotate" values="60"/>
Le navigateur détecte toutes les couleurs de l'image et les fait pivoter de 60 degrés le long de la roue chromatique. Ce sera l'image résultante :
La finale type
est luminaceToAlpha
. Cela transforme essentiellement l'image en un négatif translucide en supprimant le canal alpha.
Le matrix
peut obtenir les mêmes effets que les autres si on leur donne les bonnes valeurs pour la grille.
feConvolveMatrix
D'une matrice à l'autre ! Cette primitive de filtre ajoute un effet de convolution, ou noyau, à une image. Il est utilisé pour le flou, la détection des contours, la netteté, le gaufrage et le biseautage à l'aide d'une combinaison de pixels.
Nous pouvons démontrer un subtil effet de pépin en utilisant des valeurs aléatoires dans la grille :
<svg>
<filter id="convolve">
<feConvolveMatrix kernelMatrix
="1 -4 1
1 0 -8
1 0 -4" />
</filter>
</svg>
Le résultat:
Comparons avec l'original pour bien voir les effets :
feComponentTransfer
Cette primitive est similaire à feColorMatrix
, mais, à la place d'une grille, chaque canal de couleur (RGBA) est une fonction distincte. Et tout comme avec la matrice, nous pouvons ajuster le contraste de l'image en manipulant l'intensité de la couleur sur ces canaux.
Voici à quoi cela ressemble :
Et voici comment cela fonctionne en utilisant les valeurs données dans cet exemple :
Dans le canal rouge, par exemple, l'intensité de la couleur varie de 0 à 1. Nous sommes partis avec quatre valeurs, donc 1 est divisé par 4. Nous avons maintenant quatre plages égales de rouge : 0–0,25, 0,25–0,5, 0,5 –0,75 et 0,75–1.
Toute valeur de rouge comprise entre 0 et 0,25 se voit attribuer la première valeur dans tableValues
et ainsi de suite. Le même principe est utilisé jusqu'à 10 valeurs.
Il existe diverses fonctions qui peuvent être utilisées avec cette primitive de filtre, et la première que nous allons examiner est discrete
. Cela réduit la quantité de couleur dans une image.
<svg>
<filter id="discrete">
<feComponentTransfer>
<feFuncR type="discrete" tableValues="0 0.5 0 1"/>
<feFuncG type="discrete" tableValues="0 0.5 0 1"/>
<feFuncB type="discrete" tableValues="0 0.5 0 1"/>
<feFuncA type="discrete" tableValues="0 0.5 0 1"/>
</feComponentTransfer>
</filter>
</svg>
Le résultat:
Le suivant type
est table
, qui apporte des modifications plus subtiles au contraste de l'image. Donc, en utilisant la même chose tableValues
que ci-dessus…
<svg>
<filter id="convolve">
<feComponentTransfer>
<feFuncR type="table" tableValues="0 0.5 0 1" />
<feFuncG type="table" tableValues="0 0.5 0 1" />
<feFuncB type="table" tableValues="0 0.5 0 1" />
<feFuncA type="table" tableValues="0 0.5 0 1" />
</feComponentTransfer>
</filter>
</svg>
… nous obtenons ceci :
Nous pouvons créer un effet de bichromie en utilisant cette primitive. Duo signifie deux, nous utilisons donc deux valeurs de couleur pour chaque canal dans tableValues
.
Nous avons besoin de deux couleurs, allons-y avec #A91C93
et #8EE3FF
. Maintenant, nous avons besoin des valeurs de couleur RVB — #A91C93
est équivalent à (169,28,147)
et #8EE3FF
est équivalent à (255,142,227)
.
Ensuite, nous devons diviser les valeurs des canaux rouge, vert et bleu par 255 pour obtenir une valeur comprise entre 0 et 1. Cela va dans tableValues
.
<svg>
<filter id="duotone">
<feComponentTransfer>
<feFuncR type="table" tableValues="0.662745098 1" />
<feFuncG type="table" tableValues="0.109803922 0.556862745" />
<feFuncB type="table" tableValues="0.576470588 0.890196078" />
</feComponentTransfer>
</filter>
</svg>
Et on obtient ceci :
Il existe une troisième façon de contrôler le contraste de l'image, et c'est le type
, gamma
. Cela vient avec trois autres attributs : exponent
, amplitude
et offset
.
L'augmentation de exponent
rend les zones sombres de l'image encore plus sombres. C'est le contraire avec amplitude
, éclaircissant les zones déjà claires de l'image.
offset
ajoute une teinte blanche à l'image et ses valeurs sont comprises entre 0 et 1.
<svg>
<filter id="amplify">
<feComponentTransfer>
<feFuncR type="gamma" exponent="1.9" amplitude="1.9" offset="0" />
<feFuncG type="gamma" exponent="1.9" amplitude="1.9" offset="0" />
<feFuncB type="gamma" exponent="1.9" amplitude="1.9" offset="0" />
</feComponentTransfer>
</filter>
</svg>
Comparons avec l'image d'origine :
Essayez d'autres valeurs pour trouver d'autres façons de pimenter un élément. Il y a tellement de possibilités à portée de main avec cette primitive de filtre SVG !
feOffset
Cette primitive est assez simple. Nous décalons l'image le long des directions x et y, comme nous l'avons fait avec l'ombre portée.
<svg>
<filter id="convolve">
<feOffset in="SourceGraphic" dx="10" dy="10"></feOffset>
</filter>
</svg>
feMerge
Ce filtre SVG nous permet de superposer deux ou plusieurs éléments. Chaque couche fait partie de la primitive feMergeNode
principale .feMerge
C'est maintenant le moment idéal pour présenter le SourceAlpha
, une copie noire du SourceGraphic
. Donc, en utilisant notre image, le SourceAlpha
est un rectangle noir avec les mêmes dimensions que l'image. Nous pouvons l'utiliser pour créer une meilleure ombre portée.
On commencera par décaler SourceAlpha
:
<svg>
<filter id="drop-shadow">
<feOffset in="SourceAlpha" dx="10" dy="10"></feOffset>
</filter>
</svg>
Ensuite, nous allons appliquer un flou et réduire l'opacité en utilisant feColorMatrix
:
<svg>
<filter id="drop-shadow">
<feOffset in="SourceAlpha" dx="10" dy="10"></feOffset>
<feGaussianBlur stdDeviation="10" result="BLUR"></feGaussianBlur>
<feColorMatrix
type="matrix"
in="BLUR"
result="DROPSHADOW"
values="1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 0.5 0"></feColorMatrix>
</filter>
</svg>
À ce stade, nous avons un rectangle translucide flou :
Maintenant, nous allons superposer notre image au-dessus de cette ombre en utilisant feMerge
. Le premier feMergeNode
sera la couche supérieure et les autres suivront dans cet ordre.
<feMerge>
<feMergeNode in="FINALSHADOW"></feMergeNode>
<feMergeNode in="SourceGraphic"></feMergeNode>
</feMerge>
Maintenant, nous avons une meilleure ombre portée en combinant quatre filtres SVG !
feFlood
Avec cette primitive de filtre, nous inondons simplement la zone de filtre de couleur.
<svg>
<filter id="convolve">
<feflood flood-color="#00c2cb" flood-opacity="0.1" />
</filter>
</svg>
Le résultat:
feComposite
Ce filtre combine une image avec son arrière-plan. Nous allons passer au texte pour démontrer l'effet de cette primitive de filtre.
Nous allons également travailler avec deux autres filtres SVG, feFlood
et feMorphology
, pour créer du texte knock-out.
Voici notre h1
texte :
Et voici la syntaxe SVG :
<body>
<svg>
<filter id="knockout">
<feMorphology operator="dilate" radius="2" in="sourceGraphic"
result="DILATE" />
<feFlood flood-color="#301934" flood-opacity="0.5" result="FLOOD" />
<feComposite operator="out" in="FLOOD" in2="DILATE" />
</filter>
</svg>
<h1>HELLO! I'M A KNOCKOUT...</h1>
</body>
Voici le résultat :
Tout d'abord, nous avons utilisé feMorphology
avec le operator
as dilate
pour étendre le texte. Ensuite, nous avons inondé la zone de texte avec la couleur. Et enfin, nous avons utilisé feComposite
pour mélanger le texte avec le fond blanc.
Nous avons utilisé out
comme valeur pour le composite operator
. Pouvez-vous deviner ce qui se passe lorsque nous utilisons in
?
Voyons voir:
ça fait le contraire ! Cette fois, la couleur d'inondation reste dans les lettres du texte.
feImage
Cette primitive remplit la zone de filtre avec une image. C'est exactement ce que nous avons fait avec feFlood
. Nous nous en tenons à l'exemple de texte, alors voyons comment fonctionne ce filtre SVG.
<feImage xlink:href="2833.jpg" x="0" y="0"
width="100%" height="100%"
preserveAspectRatio="none" result="IMAGE">
</feImage>
Pour l'instant, voici le résultat :
Maintenant, nous pouvons utiliser feComposite
pour ajouter cette image au texte.
<svg>
<filter id="knockout">
<feImage xlink:href="2833.jpg" x="0" y="0"
width="100%" height="100%"
preserveAspectRatio="none" result="IMAGE"></feImage>
<feComposite operator="in" in="IMAGE" in2="SourceGraphic" />
</filter>
</svg>
feBlend
Comme son nom l'indique, cette primitive mélange l'image avec son arrière -plan . Pour le démontrer, nous allons créer un effet de bruit avec feTurbulence
et le combiner avec l'image.
<svg>
<filter id="blend">
<feTurbulence in="SourceGraphic" type="turbulence"
baseFrequency="0.01 0.02" numOctaves="1" result="NOISE">
</feTurbulence>
<feBlend in="SourceGraphic" in2="NOISE" mode="multiply" result="BLEND"> </feBlend>
</filter>
</svg>
Le résultat est une image trouble :
Regardons une démo animée :
feDiffuseLighting
L'éclairage diffus est la lumière provenant d'une grande source extérieure. Il utilise le canal alpha de l'image comme carte en relief. Le bump mapping est une méthode graphique d'ajout de texture à une image.
Trois sources lumineuses fonctionnent avec cette primitive : feDistantLight
, fePointLight
et feSpotLight
.
feDistant
définit une source de lumière qui vient d'une certaine distance.
<svg>
<filter id="knockout">
<feDiffuseLighting in="SourceGraphic" lighting-color="#00c2cb"
diffuseConstant="2">
<feDistantLight azimuth="100" elevation="15" />
</feDiffuseLighting>
<feComposite in="SourceGraphic" operator="arithmetic" k1="1" k2="0"
k3="0" k4="0" />
</filter>
</svg>
À partir de cet extrait, la source de lumière est bleue. diffuseConstant
définit la constante de réflexion de diffusion de la lumière, et c'est ainsi que la lumière se réfléchit sur la surface. Des valeurs inférieures atténueront la lumière.
Pour les feDistantLight
attributs, azimuth
est le sens horaire de la lumière sur le plan xy et elevation
est la direction de l'angle sur l'axe z.
Voici l'effet résultant en utilisant le code ci-dessus :
Ensuite, fePointLight
. Nous pointons essentiellement la lumière sur un point particulier de l'image. En regardant notre image, la lune semble être le meilleur endroit pour éclairer.
Pour obtenir cela, nous déplaçons la lumière le long des axes x, y et z.
<svg>
<filter id="point">
<feDiffuseLighting in="SourceGraphic" lighting-color="#00c2cb" diffuseConstant="2">
<fePointLight x="580" y="100" z="40"/>
</feDiffuseLighting>
<feComposite in="SourceGraphic" operator="arithmetic" k1="1" k2="0"
k3="0" k4="0" />
</filter>
</svg>
Maintenant, nous avons une belle lune bleue dans le ciel étoilé :
Enfin, pour ce filtre SVG, nous avons feSpotLight
. C'est juste là dans le nom, il y a un projecteur invisible pointant un faisceau vers l'image. Quant à nous, nous pouvons contrôler la position, l'angle et l'intensité.
<svg>
<filter id="point">
<feDiffuseLighting in="SourceGraphic" lighting-color="#00c2cb"
diffuseConstant="5">
<feSpotLight x="680" y="20" z="30"
limitingConeAngle="60"
pointsAtX="100" pointsAtY="100"
pointsAtZ="0" />
</feDiffuseLighting>
<feComposite in="SourceGraphic" operator="arithmetic" k1="1" k2="0"
k3="0" k4="0" />
</filter>
</svg>
Le limitingConeAngle
contrôle la largeur du projecteur. pointsAtX
, pointsAtY
, et pointsAtZ
contrôlent la direction dans laquelle pointe le projecteur.
Le résultat:
feSpecularLighting
La lumière spéculaire est utilisée pour la mise en évidence. Cette primitive de filtre utilise les mêmes sources lumineuses que feDiffuseLighting
.
<svg>
<filter id="point">
<feSpecularLighting specularExponent="5" lighting-color="#00c2cb"
surfaceScale="1" in="SourceGraphic" specularConstant="1.5">
<fePointLight x="570" y="100" z="200" />
</feSpecularLighting>
<feComposite in="SourceGraphic" operator="arithmetic" k1="1" k2="0"
k3="0" k4="0" />
</filter>
</svg>
Regardons les attributs. specularExponent
contrôle la luminosité de la surbrillance et surfaceScale
correspond à la hauteur de la surface de l'image. specularConstant
fait la même chose que diffuseConstant
et éclaircit ou atténue la couleur de la lumière.
Le résultat:
Nous avons utilisé fePointLight
, mais essayez-le avec d'autres et voyez ce que vous pouvez trouver !
feTile
Nous sommes arrivés à la fin, le dernier filtre SVG qui est feTile
. Cette primitive de filtre crée un motif répétitif sur un élément, tout comme les carreaux au sol.
<svg>
<filter id="tiles">
<feTile in="SourceGraphic" x="50" y="50" width="50" height="50" />
<feTile />
</filter>
</svg>
Dans cet extrait, nous sélectionnons la partie de l'image sur l'axe x et y qui sera affichée sur chaque tuile. Tout ce que nous avons à faire est de définir le width
et height
des tuiles.
Et voila !
Voilà, nous l'avons, les 17 primitives de filtre SVG. Qui a besoin de Photoshop lorsque vous pouvez éditer en déplacement ? Vous pouvez combiner de nombreuses primitives pour obtenir des effets plus complexes.
Les filtres SVG sont bien pris en charge par tous les navigateurs modernes. Voici une capture d'écran de caniuse montrant leur gamme de compatibilité.
Les SVG peuvent faire beaucoup de choses incroyables, et nous venons de voir comment améliorer les images, ainsi que d'autres éléments graphiques, avec des filtres SVG.
Nous avons également démontré les 17 primitives disponibles avec les filtres SVG. Distorsion, manipulation des couleurs, flou, inversion des couleurs - vous l'appelez, vous pouvez obtenir ces effets en quelques touches !
Maintenant, quelques éléments à retenir :
result
les valeurs doivent être entièrement en majuscules pour les distinguer des attributs primitifsAllez de l'avant et créez un code magique, une ligne, un pixel à la fois !
Source : https://blog.logrocket.com/complete-guide-using-css-filters-svgs/
1657599240
Les filtres sont extrêmement populaires en photographie. Vous pouvez les trouver sur presque toutes les applications ou sites Web de retouche photo, et certains appareils photo ont des options de filtre intégrées pour que vous n'ayez pas à éditer les photos plus tard.
CSS a plusieurs filtres qui aident à améliorer les aspects visuels d'un site Web. Vous pouvez les appliquer directement à un élément Web à l'aide de la filter
propriété, ainsi qu'à la zone derrière l'élément avec la backdrop-filter
propriété.
Avec ces filtres, vous pouvez flouter une image, régler le contraste et la saturation, modifier la teinte, réduire l'opacité, et bien plus encore !
Dans cet article, nous allons en savoir plus sur un ensemble d'outils unique et puissant : les filtres SVG. Mais avant de continuer, faisons une petite introduction aux SVG.
Les SVG, ou Scalable Vector Graphics, sont un format d'image vectorielle basé sur XML pour afficher des graphiques en deux dimensions. XML est un autre acronyme sophistiqué qui signifie Extensible Markup Language. XML est utilisé pour stocker et transmettre des données, et définir vos balises.
Retour aux SVG. Un SVG sert à la fois de format d'image et de document. Les formats d'image standard tels que JPEG et PNG sont constitués de pixels qui perdent généralement en qualité lorsqu'ils sont agrandis.
Ce qui rend les SVG différents, c'est qu'ils conservent leur qualité, quel que soit l'ampleur du zoom. C'est possible parce qu'ils sont constitués de formules mathématiques.
Voyons ce qu'il y a sous le capot d'un SVG.
Commencez par ouvrir une image SVG dans un éditeur de code. Voici une capture d'écran de ce que vous pourriez trouver :
Ce code constitue une forme complexe. Nous pouvons contrôler la couleur, la taille et d'autres caractéristiques de l'image dans les lignes de code. Créons une forme plus simple, un cercle :
<body>
<svg width="400" height="400">
<circle cx="200" cy="200" r="100" fill="#553c9a">
</svg>
</body>
Et nous avons un cercle violet !
Nous pouvons transformer ce cercle en anneau en ajoutant une stroke
valeur. Un trait est la bordure et nous pouvons définir la fill
couleur sur transparent
.
<body>
<svg width="400" height="400">
<circle cx="200" cy="200" r="100" fill="transparent"
stroke="#553c9a" stroke-width="20px">
</svg>
</body>
Le résultat est celui-ci :
Des images complexes peuvent être créées en combinant différents SVG. Les SVG sont utilisés pour les icônes, les logos ou comme images d'arrière-plan. Ils peuvent aussi être animés !
Les filtres CSS sont principalement limités aux images et sont assez faciles à utiliser. Les filtres SVG, en revanche, peuvent être appliqués aux images (à la fois SVG et autres formats), au texte et à tous les autres éléments HTML. Les filtres CSS sont en fait un sous-ensemble de filtres SVG.
Les filtres SVG fonctionnent avec l' <filter>
élément et un ensemble de fonctions appelées primitives de filtre. Ces fonctions sont des éléments enfants qui créent des effets.
L' <filter>
élément sera référencé par la filter
propriété CSS via un fichier id
.
Pour commencer, créez un svg
élément avec un filter
élément imbriqué à l'intérieur. Ensuite, ajoutez les primitives avant l'image (ou tout autre élément auquel vous souhaitez appliquer le filtre).
Il y a 17 primitives de filtre, et ce sont :
feGaussianBlur
feDropShadow
feMorphology
feTurbulence
feDisplacementMap
feColorMatrix
feConvolveMatrix
feComponentTransfer
feOffset
feMerge
feFlood
feComposite
feImage
feBlend
feDiffuseLighting
feSpecularLighting
feTile
"fe" signifie effet de filtre. D'après les noms, nous pouvons avoir une idée des effets qu'ils produiront. Examinons une syntaxe de filtre SVG de base :
<svg>
<filter id="">
<!--Filter Primitives go in here-->
</filter>
</svg>
Chaque primitive SVG possède son propre ensemble unique d'attributs utilisés pour créer les effets. Certaines de ces primitives de filtrage fonctionnent bien par elles-mêmes, mais certaines doivent être combinées avec d'autres primitives.
Il y a beaucoup à couvrir, alors commençons.
feGaussianBlur
Les SVG sont basés sur des formules mathématiques, il est donc normal de faire avancer les choses avec un filtre de flou gaussien. Ce filtre porte le nom du regretté mathématicien Carl Friedrich Gauss et applique une fonction mathématique pour brouiller l'image.
Tout d'abord, vous aurez besoin d'une image. En voici un de freepik.com :
Ensuite, nous allons créer la syntaxe SVG dans le fichier HTML :
<svg>
<filter id="blur">
<feGaussianBlur stdDeviation="5" in="SourceGraphic" result="BLUR"></feGaussianBlur>
</filter>
<image
xlink:href="2833.jpg" filter="url(#blur)"></image>
</svg>
Maintenant, nous aurons la primitive de filtre SVG, feGaussianBlur
, dans l' filter
élément. Certains attributs à l'intérieur de la primitive auront un effet sur le flou produit.
Le premier attribut est stdDeviation
, qui régule la quantité de flou.
Vient ensuite in
, pour l'entrée, qui définit où le filtre sera appliqué. Dans ce cas, c'est le SourceGraphic
, qui est notre image. Il SourceGraphic
peut également s'agir de texte.
Le dernier attribut de cet exemple est result
. Nous l'utilisons pour nommer le filtre. Ceci est utile comme référence in
lorsque vous travaillez avec plusieurs filtres.
Voici l'image résultante avec le filtre appliqué :
Comme mentionné précédemment, les filtres SVG peuvent être appliqués en externe en utilisant la filter
propriété et un url
pointant vers un id
:
<svg>
<filter id="blur">
<feGaussianBlur stdDeviation="5"></feGaussianBlur>
</filter>
</svg>
Enfin, appliquez-le avec la filter
propriété CSS :
img{
width: 1000px;
height: auto;
filter: url(#blur);
}
feDropShadow
Ce filtre est assez simple et ajoute une ombre portée derrière un élément.
Commencez par la syntaxe :
<svg >
<filter id="blur">
<feDropShadow in="SourceGraphic" dx="10" dy="10"></feDropShadow>
</filter>
</svg>
Les attributs dx
et dy
définissent la position de l'ombre le long des axes x et y, respectivement. Le résultat est une ombre vraiment sombre derrière l'image :
feMorphology
La morphologie est l'étude de la forme, de la forme et de la structure. La feMorphology
primitive est utilisée pour changer, ou transformer, la forme des éléments.
Il fonctionne avec l' operator
attribut qui accepte l'une des deux valeurs, dilate
ou erode
, et a radius
qui définit la quantité de dilatation ou d'érosion. Pour dilate
, les pixels du SourceGraphic
sont étalés vers l'extérieur. erode
fait le contraire.
Comparons les deux. Tout d'abord c'est dilate
:
<svg>
<filter id="blur">
<feMorphology in="SourceGraphic" operator="dilate" radius="5">
</feMorphology>
</filter>
</svg>
Le résultat:
Voyons maintenant erode
:
<svg>
<filter id="blur">
<feMorphology in="SourceGraphic" operator="erode" radius="5">
</feMorphology>
</filter>
</svg>
Le résultat:
Où sont passées toutes les étoiles ?
D'après ces résultats, nous pouvons voir que dilate
produit une image plus vibrante par rapport à l'image assombrie et atténuée de erode
. La luminosité est due à l'expansion des pixels de l'image et vice versa.
feTurbulence
La seule véritable explication de l'effet de cette primitive de filtre est juste là dans son nom : la turbulence. Il utilise deux attributs : baseFrequency
et numOctaves
.
<feTurbulence in="SourceGRaphic" baseFrequency="0.01 0.02"
numOctaves="1" result="NOISE">
</feTurbulence>
Le résultat est un effet de bruit sur l'image :
Expliquons les attributs.
Le baseFrequency
contrôle la quantité de distorsion, ou de bruit, dans les directions x et y. Une baseFrequency
valeur élevée réduit la taille du motif de distorsion. Il peut contenir deux valeurs, et si une seule valeur est utilisée, elle couvre à la fois les axes x et y.
numOctaves
est également une fonction de bruit et contrôle le nombre d'octaves dans l'effet de filtre. En utilisant un baseFrequency
de "0.01 0.02"
, nous obtenons ce qui suit :
En fin de compte, c'est à vous de décider du nombre d'octaves et de la quantité de fréquence. Jouez avec les valeurs et voyez ce que vous proposez. Gardez à l'esprit qu'ils n'acceptent pas les valeurs négatives.
feDisplacementMap
Une carte de déplacement est une image utilisée pour modifier le contenu d'un autre élément. La texture d'un élément peut être appliquée à un autre.
Pour cette primitive de filtre SVG, nous aurons besoin de deux entrées : in
et in2
. L'un contiendra le graphique original et l'autre sera l'image servant de carte de déplacement.
<svg>
<filter id="turbulence">
<feTurbulence type="turbulence" baseFrequency="0.01 0.02" numOctaves="1" result="NOISE"></feTurbulence>
<feDisplacementMap in="SourceGraphic" in2="NOISE" scale="50">
</feDisplacementMap>
</filter>
</svg>
Maintenant pour le résultat. L'image suit le motif de distorsion créé par le feTurbulence
filtre :
Nous pouvons aller plus loin en ajoutant une animation ondulée pour compléter le look aqueux :
<svg>
<filter id="wavy">
<feTurbulence id="turbulence" type="turbulence" numOctaves="1"
result="NOISE"></feTurbulence>
<feDisplacementMap in="SourceGraphic" in2="NOISE" scale="50">
</feDisplacementMap>
<animate xlink:href="#turbulence" attributeName="baseFrequency" dur="60s" keyTimes="0;0.5;1"
values="0.01 0.02;0.02 0.04;0.01 0.02" repeatCount="indefinite"></animate>
</filter>
</svg>
Notez que la première primitive de filtre a maintenant un id
. C'est ce que nous animons.
Ensuite, nous utiliserons l' <animate>
élément pour définir l'animation. Cet élément contiendra xlink:href
, pointant vers le filtre qui sera animé. Après c'est attributeName
, et l'attribut primitif que nous animons est le baseFrequency
.
Ensuite, nous fixons la durée avec dur
et le keyTimes
. Ce sont essentiellement @keyframes
.
values
contiennent les nouvelles baseFrequency
valeurs des points d'arrêt définis avec keyTimes
.
Enfin, nous avons repeatCount
réglé pour indefinite
que l'effet tourne en boucle.
Et voici le résultat :
Nous pouvons également utiliser les propriétés régulières animation
et transition
CSS ou du JavaScript pour l'animation.
feColorMatrix
Ce filtre SVG permet de modifier la teinte et la saturation d'un élément. Il fonctionne avec un type
attribut et quatre valeurs possibles : matrix
, saturate
, hueRotate
et luminaceToAlpha
.
Pour matrix
, l'effet de filtre est appliqué à l'aide d'une matrice de couleurs RVBA, ou grille, pour son value
.
<svg>
<filter>
<feColorMatrix in="SourceGraphic" type="matrix"
values="1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0">
</filter>
</svg>
La syntaxe ci-dessus ne changera pas la couleur de l'image. Regardons chaque canal de couleur.
Jouez avec les valeurs et voyez quelles teintes, nuances et teintes vous pouvez trouver !
Ensuite, nous avons saturate
. Cela utilise values
entre 0 et 1 pour contrôler la quantité de noir et blanc dans l'image.
<svg>
<filter id="saturate">
<feColorMatrix in="SourceGraphic" type="saturate" values="0.5"/>
</filter>
</svg>
Le résultat:
La prochaine étape est hueRotate
. Cet attribut fait pivoter les couleurs de l'image autour de la roue chromatique selon un angle spécifique. Commençons par vous montrer la roue chromatique :
Utilisons maintenant l'attribut :
<feColorMatrix in="SourceGraphic" type="hueRotate" values="60"/>
Le navigateur détecte toutes les couleurs de l'image et les fait pivoter de 60 degrés le long de la roue chromatique. Ce sera l'image résultante :
La finale type
est luminaceToAlpha
. Cela transforme essentiellement l'image en un négatif translucide en supprimant le canal alpha.
Le matrix
peut obtenir les mêmes effets que les autres si on leur donne les bonnes valeurs pour la grille.
feConvolveMatrix
D'une matrice à l'autre ! Cette primitive de filtre ajoute un effet de convolution, ou noyau, à une image. Il est utilisé pour le flou, la détection des contours, la netteté, le gaufrage et le biseautage à l'aide d'une combinaison de pixels.
Nous pouvons démontrer un subtil effet de pépin en utilisant des valeurs aléatoires dans la grille :
<svg>
<filter id="convolve">
<feConvolveMatrix kernelMatrix
="1 -4 1
1 0 -8
1 0 -4" />
</filter>
</svg>
Le résultat:
Comparons avec l'original pour bien voir les effets :
feComponentTransfer
Cette primitive est similaire à feColorMatrix
, mais, à la place d'une grille, chaque canal de couleur (RGBA) est une fonction distincte. Et tout comme avec la matrice, nous pouvons ajuster le contraste de l'image en manipulant l'intensité de la couleur sur ces canaux.
Voici à quoi cela ressemble :
Et voici comment cela fonctionne en utilisant les valeurs données dans cet exemple :
Dans le canal rouge, par exemple, l'intensité de la couleur varie de 0 à 1. Nous sommes partis avec quatre valeurs, donc 1 est divisé par 4. Nous avons maintenant quatre plages égales de rouge : 0–0,25, 0,25–0,5, 0,5 –0,75 et 0,75–1.
Toute valeur de rouge comprise entre 0 et 0,25 se voit attribuer la première valeur dans tableValues
et ainsi de suite. Le même principe est utilisé jusqu'à 10 valeurs.
Il existe diverses fonctions qui peuvent être utilisées avec cette primitive de filtre, et la première que nous allons examiner est discrete
. Cela réduit la quantité de couleur dans une image.
<svg>
<filter id="discrete">
<feComponentTransfer>
<feFuncR type="discrete" tableValues="0 0.5 0 1"/>
<feFuncG type="discrete" tableValues="0 0.5 0 1"/>
<feFuncB type="discrete" tableValues="0 0.5 0 1"/>
<feFuncA type="discrete" tableValues="0 0.5 0 1"/>
</feComponentTransfer>
</filter>
</svg>
Le résultat:
Le suivant type
est table
, qui apporte des modifications plus subtiles au contraste de l'image. Donc, en utilisant la même chose tableValues
que ci-dessus…
<svg>
<filter id="convolve">
<feComponentTransfer>
<feFuncR type="table" tableValues="0 0.5 0 1" />
<feFuncG type="table" tableValues="0 0.5 0 1" />
<feFuncB type="table" tableValues="0 0.5 0 1" />
<feFuncA type="table" tableValues="0 0.5 0 1" />
</feComponentTransfer>
</filter>
</svg>
… nous obtenons ceci :
Nous pouvons créer un effet de bichromie en utilisant cette primitive. Duo signifie deux, nous utilisons donc deux valeurs de couleur pour chaque canal dans tableValues
.
Nous avons besoin de deux couleurs, allons-y avec #A91C93
et #8EE3FF
. Maintenant, nous avons besoin des valeurs de couleur RVB — #A91C93
est équivalent à (169,28,147)
et #8EE3FF
est équivalent à (255,142,227)
.
Ensuite, nous devons diviser les valeurs des canaux rouge, vert et bleu par 255 pour obtenir une valeur comprise entre 0 et 1. Cela va dans tableValues
.
<svg>
<filter id="duotone">
<feComponentTransfer>
<feFuncR type="table" tableValues="0.662745098 1" />
<feFuncG type="table" tableValues="0.109803922 0.556862745" />
<feFuncB type="table" tableValues="0.576470588 0.890196078" />
</feComponentTransfer>
</filter>
</svg>
Et on obtient ceci :
Il existe une troisième façon de contrôler le contraste de l'image, et c'est le type
, gamma
. Cela vient avec trois autres attributs : exponent
, amplitude
et offset
.
L'augmentation de exponent
rend les zones sombres de l'image encore plus sombres. C'est le contraire avec amplitude
, éclaircissant les zones déjà claires de l'image.
offset
ajoute une teinte blanche à l'image et ses valeurs sont comprises entre 0 et 1.
<svg>
<filter id="amplify">
<feComponentTransfer>
<feFuncR type="gamma" exponent="1.9" amplitude="1.9" offset="0" />
<feFuncG type="gamma" exponent="1.9" amplitude="1.9" offset="0" />
<feFuncB type="gamma" exponent="1.9" amplitude="1.9" offset="0" />
</feComponentTransfer>
</filter>
</svg>
Comparons avec l'image d'origine :
Essayez d'autres valeurs pour trouver d'autres façons de pimenter un élément. Il y a tellement de possibilités à portée de main avec cette primitive de filtre SVG !
feOffset
Cette primitive est assez simple. Nous décalons l'image le long des directions x et y, comme nous l'avons fait avec l'ombre portée.
<svg>
<filter id="convolve">
<feOffset in="SourceGraphic" dx="10" dy="10"></feOffset>
</filter>
</svg>
feMerge
Ce filtre SVG nous permet de superposer deux ou plusieurs éléments. Chaque couche fait partie de la primitive feMergeNode
principale .feMerge
C'est maintenant le moment idéal pour présenter le SourceAlpha
, une copie noire du SourceGraphic
. Donc, en utilisant notre image, le SourceAlpha
est un rectangle noir avec les mêmes dimensions que l'image. Nous pouvons l'utiliser pour créer une meilleure ombre portée.
On commencera par décaler SourceAlpha
:
<svg>
<filter id="drop-shadow">
<feOffset in="SourceAlpha" dx="10" dy="10"></feOffset>
</filter>
</svg>
Ensuite, nous allons appliquer un flou et réduire l'opacité en utilisant feColorMatrix
:
<svg>
<filter id="drop-shadow">
<feOffset in="SourceAlpha" dx="10" dy="10"></feOffset>
<feGaussianBlur stdDeviation="10" result="BLUR"></feGaussianBlur>
<feColorMatrix
type="matrix"
in="BLUR"
result="DROPSHADOW"
values="1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 0.5 0"></feColorMatrix>
</filter>
</svg>
À ce stade, nous avons un rectangle translucide flou :
Maintenant, nous allons superposer notre image au-dessus de cette ombre en utilisant feMerge
. Le premier feMergeNode
sera la couche supérieure et les autres suivront dans cet ordre.
<feMerge>
<feMergeNode in="FINALSHADOW"></feMergeNode>
<feMergeNode in="SourceGraphic"></feMergeNode>
</feMerge>
Maintenant, nous avons une meilleure ombre portée en combinant quatre filtres SVG !
feFlood
Avec cette primitive de filtre, nous inondons simplement la zone de filtre de couleur.
<svg>
<filter id="convolve">
<feflood flood-color="#00c2cb" flood-opacity="0.1" />
</filter>
</svg>
Le résultat:
feComposite
Ce filtre combine une image avec son arrière-plan. Nous allons passer au texte pour démontrer l'effet de cette primitive de filtre.
Nous allons également travailler avec deux autres filtres SVG, feFlood
et feMorphology
, pour créer du texte knock-out.
Voici notre h1
texte :
Et voici la syntaxe SVG :
<body>
<svg>
<filter id="knockout">
<feMorphology operator="dilate" radius="2" in="sourceGraphic"
result="DILATE" />
<feFlood flood-color="#301934" flood-opacity="0.5" result="FLOOD" />
<feComposite operator="out" in="FLOOD" in2="DILATE" />
</filter>
</svg>
<h1>HELLO! I'M A KNOCKOUT...</h1>
</body>
Voici le résultat :
Tout d'abord, nous avons utilisé feMorphology
avec le operator
as dilate
pour étendre le texte. Ensuite, nous avons inondé la zone de texte avec la couleur. Et enfin, nous avons utilisé feComposite
pour mélanger le texte avec le fond blanc.
Nous avons utilisé out
comme valeur pour le composite operator
. Pouvez-vous deviner ce qui se passe lorsque nous utilisons in
?
Voyons voir:
ça fait le contraire ! Cette fois, la couleur d'inondation reste dans les lettres du texte.
feImage
Cette primitive remplit la zone de filtre avec une image. C'est exactement ce que nous avons fait avec feFlood
. Nous nous en tenons à l'exemple de texte, alors voyons comment fonctionne ce filtre SVG.
<feImage xlink:href="2833.jpg" x="0" y="0"
width="100%" height="100%"
preserveAspectRatio="none" result="IMAGE">
</feImage>
Pour l'instant, voici le résultat :
Maintenant, nous pouvons utiliser feComposite
pour ajouter cette image au texte.
<svg>
<filter id="knockout">
<feImage xlink:href="2833.jpg" x="0" y="0"
width="100%" height="100%"
preserveAspectRatio="none" result="IMAGE"></feImage>
<feComposite operator="in" in="IMAGE" in2="SourceGraphic" />
</filter>
</svg>
feBlend
Comme son nom l'indique, cette primitive mélange l'image avec son arrière -plan . Pour le démontrer, nous allons créer un effet de bruit avec feTurbulence
et le combiner avec l'image.
<svg>
<filter id="blend">
<feTurbulence in="SourceGraphic" type="turbulence"
baseFrequency="0.01 0.02" numOctaves="1" result="NOISE">
</feTurbulence>
<feBlend in="SourceGraphic" in2="NOISE" mode="multiply" result="BLEND"> </feBlend>
</filter>
</svg>
Le résultat est une image trouble :
Regardons une démo animée :
feDiffuseLighting
L'éclairage diffus est la lumière provenant d'une grande source extérieure. Il utilise le canal alpha de l'image comme carte en relief. Le bump mapping est une méthode graphique d'ajout de texture à une image.
Trois sources lumineuses fonctionnent avec cette primitive : feDistantLight
, fePointLight
et feSpotLight
.
feDistant
définit une source de lumière qui vient d'une certaine distance.
<svg>
<filter id="knockout">
<feDiffuseLighting in="SourceGraphic" lighting-color="#00c2cb"
diffuseConstant="2">
<feDistantLight azimuth="100" elevation="15" />
</feDiffuseLighting>
<feComposite in="SourceGraphic" operator="arithmetic" k1="1" k2="0"
k3="0" k4="0" />
</filter>
</svg>
À partir de cet extrait, la source de lumière est bleue. diffuseConstant
définit la constante de réflexion de diffusion de la lumière, et c'est ainsi que la lumière se réfléchit sur la surface. Des valeurs inférieures atténueront la lumière.
Pour les feDistantLight
attributs, azimuth
est le sens horaire de la lumière sur le plan xy et elevation
est la direction de l'angle sur l'axe z.
Voici l'effet résultant en utilisant le code ci-dessus :
Ensuite, fePointLight
. Nous pointons essentiellement la lumière sur un point particulier de l'image. En regardant notre image, la lune semble être le meilleur endroit pour éclairer.
Pour obtenir cela, nous déplaçons la lumière le long des axes x, y et z.
<svg>
<filter id="point">
<feDiffuseLighting in="SourceGraphic" lighting-color="#00c2cb" diffuseConstant="2">
<fePointLight x="580" y="100" z="40"/>
</feDiffuseLighting>
<feComposite in="SourceGraphic" operator="arithmetic" k1="1" k2="0"
k3="0" k4="0" />
</filter>
</svg>
Maintenant, nous avons une belle lune bleue dans le ciel étoilé :
Enfin, pour ce filtre SVG, nous avons feSpotLight
. C'est juste là dans le nom, il y a un projecteur invisible pointant un faisceau vers l'image. Quant à nous, nous pouvons contrôler la position, l'angle et l'intensité.
<svg>
<filter id="point">
<feDiffuseLighting in="SourceGraphic" lighting-color="#00c2cb"
diffuseConstant="5">
<feSpotLight x="680" y="20" z="30"
limitingConeAngle="60"
pointsAtX="100" pointsAtY="100"
pointsAtZ="0" />
</feDiffuseLighting>
<feComposite in="SourceGraphic" operator="arithmetic" k1="1" k2="0"
k3="0" k4="0" />
</filter>
</svg>
Le limitingConeAngle
contrôle la largeur du projecteur. pointsAtX
, pointsAtY
, et pointsAtZ
contrôlent la direction dans laquelle pointe le projecteur.
Le résultat:
feSpecularLighting
La lumière spéculaire est utilisée pour la mise en évidence. Cette primitive de filtre utilise les mêmes sources lumineuses que feDiffuseLighting
.
<svg>
<filter id="point">
<feSpecularLighting specularExponent="5" lighting-color="#00c2cb"
surfaceScale="1" in="SourceGraphic" specularConstant="1.5">
<fePointLight x="570" y="100" z="200" />
</feSpecularLighting>
<feComposite in="SourceGraphic" operator="arithmetic" k1="1" k2="0"
k3="0" k4="0" />
</filter>
</svg>
Regardons les attributs. specularExponent
contrôle la luminosité de la surbrillance et surfaceScale
correspond à la hauteur de la surface de l'image. specularConstant
fait la même chose que diffuseConstant
et éclaircit ou atténue la couleur de la lumière.
Le résultat:
Nous avons utilisé fePointLight
, mais essayez-le avec d'autres et voyez ce que vous pouvez trouver !
feTile
Nous sommes arrivés à la fin, le dernier filtre SVG qui est feTile
. Cette primitive de filtre crée un motif répétitif sur un élément, tout comme les carreaux au sol.
<svg>
<filter id="tiles">
<feTile in="SourceGraphic" x="50" y="50" width="50" height="50" />
<feTile />
</filter>
</svg>
Dans cet extrait, nous sélectionnons la partie de l'image sur l'axe x et y qui sera affichée sur chaque tuile. Tout ce que nous avons à faire est de définir le width
et height
des tuiles.
Et voila !
Voilà, nous l'avons, les 17 primitives de filtre SVG. Qui a besoin de Photoshop lorsque vous pouvez éditer en déplacement ? Vous pouvez combiner de nombreuses primitives pour obtenir des effets plus complexes.
Les filtres SVG sont bien pris en charge par tous les navigateurs modernes. Voici une capture d'écran de caniuse montrant leur gamme de compatibilité.
Les SVG peuvent faire beaucoup de choses incroyables, et nous venons de voir comment améliorer les images, ainsi que d'autres éléments graphiques, avec des filtres SVG.
Nous avons également démontré les 17 primitives disponibles avec les filtres SVG. Distorsion, manipulation des couleurs, flou, inversion des couleurs - vous l'appelez, vous pouvez obtenir ces effets en quelques touches !
Maintenant, quelques éléments à retenir :
result
les valeurs doivent être entièrement en majuscules pour les distinguer des attributs primitifsAllez de l'avant et créez un code magique, une ligne, un pixel à la fois !
Source : https://blog.logrocket.com/complete-guide-using-css-filters-svgs/
1652926080
Un viernes por la mañana, holgazaneando, estás pensando en los nuevos programas de Netflix para ver. Su jefe viene y le pide que escriba un analizador para un archivo de unidad de Systemd .
Lo necesita para el lunes.
Estás nervioso.
La última vez que se le pidió que escribiera un analizador, se metió en la madriguera del conejo de la web, copiando y pegando fórmulas Regex hasta que funcionó™.
Tomas un sorbo de tu té de boba para calmarte. Buscas Systemd en Google y te gusta... no, no es tan simple como pensabas.
Tu buen truco de copiar y pegar expresiones regulares sale volando por la ventana. Las posibilidades de pasar un fin de semana sin interrupciones para atracones de programas se acercan rápidamente null
.
No pierdas la esperanza todavía. Permítame presentarle Parse Expression Grammer (PEG) , una manera fácil de familiarizarse con los analizadores y ahorrar su valioso fin de semana.
PEG es una forma legible de escribir reglas de sintaxis y es bastante similar a las expresiones regulares, que es diferente de una contraparte de gramática libre de contexto como Backus-Naur Form (BNF) en la que las expresiones deben reducirse a símbolos más pequeños. Lo siento, Noam Chomsky , quizás otros días de trabajo.
Usaré una biblioteca de análisis de Rust PEG llamada Pest , que es bastante impresionante. Si aún no lo has hecho, esperaré mientras instalas Rust .
Comencemos con una gramática simple para analizar una declaración de declaración de variable similar a JavaScript. Comenzaremos pensando en un conjunto de reglas para entradas válidas.
var
, seguida de uno o más identificadores.;
)var
palabra claveUn identificador es un término , lo que significa que es una pieza irrompible del token. También lo son las var
palabras clave y los puntos y comas.
Regresa un poco al lado BNF, usando Extended Backus-Naur Grammar (EBNF) , podrías definir formalmente la gramática anterior de esta manera:
<alpha> := 'a' | 'b' | 'c' | 'd' | 'e' | /* ... */ 'z'
| 'A' | 'B' | 'C' | 'D' | 'E' | /* ... */ 'Z'
<digit> := 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
<Decl> := 'var' <Idents> '\n'? ';'
<Idents> := <Ident> ('\n'? ',' <Ident>)*
<Ident> := <alpha>+ (<alpha> | <digit> | '_')*
El nombre de la regla en mayúsculas representa un símbolo que no termina (es decir, se puede dividir en términos más pequeños). El nombre en minúscula representa un término.
En aras de la brevedad, omitimos los espacios en blanco implícitos de las reglas. Básicamente, pueden existir uno o más espacios en blanco entre cada símbolo que ve.
¡Vamos a profundizar en ello! Las reglas <alpha>
y <digit>
se explican por sí mismas, por lo que dejaremos que lo adivines.
<Decl>
es la regla más compleja para una instrucción de declaración, que presenta una var
palabra clave, un <Idents>
símbolo, una nueva línea opcional y termina con un punto y coma. Básicamente, esta regla dice: "Cualquier entrada de cadena que comience con var
, seguida de uno o más espacios, luego una subregla <Idents>
, seguida de uno o más espacios y finalmente termine con un solo punto y coma es válida y felizmente la masticaré. "
<Idents>
puede ser un solo <Ident>
símbolo, seguido de cero o más pares de comas y <Ident>
.
Finalmente, un <Ident>
debe comenzar con uno o más caracteres, seguido de cero o más caracteres, dígitos o guiones bajos.
¡Espera, joven Anakin! Cabeza caliente, eres. He aquí que, con la gramática definida, podremos analizar estas declaraciones:
var foo, bar, baz;
var foo_1, baRamYu,baz99;
var foo_x
, baroo
, bazoo
;
No, no me olvidé de formatear mi código. ¡Es JS válido, y también es para nuestro analizador! Aquí hay algo que nuestras reglas no soportarán:
var 99Problems
¿Alguien quiere adivinar qué está mal aquí? ✋ Deja tu respuesta en el comentario. (psss, si tu respuesta es correcta, te sigo + 3 me gusta en tu publicación 👍)
Ok, espero que ya tengas Rust instalado (En tu terminal, intenta escribir which cargo
y ver si aparece). Comience creando un nuevo proyecto binario de Rust con
$ cargo new --bin maybe-js; cd maybe-js
Dentro de la carpeta del proyecto, abra el Cargo.toml
archivo y agregue lo siguiente en dependencies
, y ejecútelo cargo update
para instalarlo.
[dependencies]
pest = "2.0"
pest_derive = "2.0"
Una vez hecho esto, cd
ingrese src
y cree un archivo llamado grammar.pest
y pegue lo siguiente en él:
alpha = { 'a'..'z' | 'A'..'Z' }
digit = { '0'..'9' }
underscore = { "_" }
newline = _{ "\n" | "\r" }
WHITESPACE = _{ " " }
declaration = { "var" ~ !newline ~ idents ~ newline? ~ ";" }
idents = { ident ~ (newline? ~ "," ~ ident)* }
ident = @{ !digit ~ (alpha | digit | underscore)+ }
Ahora bien, si he tenido su atención durante los últimos minutos, no debería ser difícil adivinar lo que está sucediendo aquí. (Oh, ¿no lo he hecho? De todos modos... aquí vamos)
Los cinco primeros son todos términos. Son conjuntos de valores válidos. el | se llama Choice Operator , que es como "o-si no".
first | or_else
Al hacer coincidir una expresión de elección, first
se intenta. Si first coincide con éxito, la expresión completa se realiza correctamente de inmediato. Sin embargo, si first
falla, or_else
se intenta a continuación.
La newline
regla tiene un peculiar _
antes del corchete, que en Pest habla significa "silencioso": simplemente no lo queremos como parte de nuestros tokens analizados, pero de todos modos es parte de una sintaxis válida.
La WHITESPACE
regla tiene un lugar especial en Pest. Si lo definió, Pest insertará automáticamente espacios en blanco opcionales implícitos (de acuerdo con la WHITESPACE
regla que defina) entre cada símbolo. Nuevamente, _
dice que queremos silenciarlo, ya que no queremos toneladas de espacios en blanco como parte de nuestro árbol de sintaxis.
La declaration
regla es muy similar a la contraparte de EBNF que aprendimos antes. Las tildes ("~") simplemente significan "y luego". La regla comienza con una palabra clave "var", seguida de cualquier cosa que no sea un salto de línea (el "!" hace lo que hubiera adivinado intuitivamente: negar una regla), seguida de una subregla idents
, un salto de línea opcional y finaliza con un punto y coma.
La idents
regla es nuevamente similar al ejemplo EBNF. Es un solo ident
, seguido de cero o más ident
s separados por comas.
La ident
regla es un poco especial. La "@", conocida como Atomic , delante del corchete está ahí para decir: "No quiero que se apliquen espacios en blanco implícitos a esta regla". Seguro que no queremos incluir ningún espacio en nuestro nombre de variable. Además, marcar una regla como atómica de esta manera trata la regla como un término, silenciando las reglas internas de coincidencia. Cualquier regla interna se descarta.
string_lit = { "\"" ~ inner ~ "\"" }
inner = { ASCII_ALPHANUMERIC* }
Tenga en cuenta que ASCII_ALPHANUMERIC
es una regla incorporada conveniente en Pest para cualquier carácter y dígito ASCII.
Si analizamos una cadena "hola" con esta regla, esto generará primero un string_lit
nodo, que a su vez tiene un inner
nodo que contiene la cadena "hola", sin comillas.
Agregar un sigilo "@" delante del string_lit
corchete:
string_lit = @{ "\"" ~ inner ~ "\"" }
inner = { ASCII_ALPHANUMERIC* }
string_lit
Terminaremos con un nodo plano que contiene ""hola"".
Un sigilo similar "$" conocido como Compound Atomic , protege los espacios en blanco implícitos dentro de la regla. La diferencia es que permite que las reglas de coincidencia internas se analicen normalmente.
La !digit
parte evita que la regla avance si comienza con un número. Si no es así, una o más combinaciones de caracteres, números y guiones bajos están bien.
¡Dang, mi inteligente explorador! Pareces arrinconarme en cada movimiento. Sí, eso no era código en absoluto, sino una definición de gramática de Pest. Ahora tenemos que escribir un código de Rust para analizar un texto. Inicie src/main.rs
y agregue lo siguiente:
/// You need to do this to use macro
extern crate pest;
#[macro_use]
extern crate pest_derive;
/// 1. Import modules
use std::fs;
use pest::Parser;
use pest::iterators::Pair;
/// 2. Define a "marker" struct and add a path to our grammar file.
#[derive(Parser)]
#[grammar = "grammar.pest"]
struct IdentParser;
/// 3. Print the detail of a current Pair and optional divider
fn print_pair(pair: &Pair<Rule>, hard_divider: bool) {
println!("Rule: {:?}", pair.as_rule());
println!("Span: {:?}", pair.as_span());
println!("Text: {:?}", pair.as_str());
if hard_divider {
println!("{:=>60}", "");
} else {
println!("{:->60}", "");
}
}
fn main() {
/// 4. Parse a sample string input
let pair = IdentParser::parse(Rule::declaration, "var foo1, bar_99, fooBar;")
.expect("unsuccessful parse")
.next().unwrap();
print_pair(&pair, true);
/// 5. Iterate over the "inner" Pairs
for inner_pair in pair.into_inner() {
print_pair(&inner_pair, true);
match inner_pair.as_rule() {
/// 6. If we match an idents rule...
Rule::idents => {
/// 7. Iterate over another inner Pairs
for inner_inner_pair in inner_pair.into_inner() {
match inner_inner_pair.as_rule() {
/// 8. The term ident is the last level
Rule::ident => {
print_pair(&inner_inner_pair, false);
}
_ => unreachable!(),
}
}
}
_ => unreachable!(),
}
}
}
Está bien si no entiendes la mayoría de las cosas aquí. Ejecutémoslo cargo run
en el directorio de su proyecto y miremos la salida impresa.
Rule: declaration
Span: Span { str: "var foo1, bar_99, fooBar;", start: 0, end: 28 }
Text: "var foo1, bar_99, fooBarBaz;"
============================================================
Rule: idents
Span: Span { str: "foo1, bar_99, fooBar", start: 4, end: 27 }
Text: "foo1, bar_99, fooBarBaz"
============================================================
Rule: ident
Span: Span { str: "foo1", start: 4, end: 8 }
Text: "foo1"
------------------------------------------------------------
Rule: ident
Span: Span { str: "bar_99", start: 10, end: 16 }
Text: "bar_99"
------------------------------------------------------------
Rule: ident
Span: Span { str: "fooBar", start: 18, end: 27 }
Text: "fooBarBaz"
------------------------------------------------------------
El concepto más importante aquí es un Pair
. Representa un par de tokens coincidentes o, de manera equivalente, el texto distribuido que una regla con nombre coincidió correctamente.
A menudo usamos Pair
s para:
Determinar qué regla produjo elPair
Usar el Pair
como materia prima&str
Inspeccionar las sub-reglas internas nombradas que produjeron elPair
let pair = Parser::parse(Rule::enclosed, "(..6472..) and more text")
.unwrap().next().unwrap();
assert_eq!(pair.as_rule(), Rule::enclosed);
assert_eq!(pair.as_str(), "(..6472..)");
let inner_rules = pair.into_inner();
println!("{}", inner_rules); // --> [number(3, 7)]
A Pair
puede tener cero, una o más reglas internas. Para máxima flexibilidad, Pair::into_inner()
devuelve Pairs
, que es un tipo de iterador sobre cada par.
💡
Pair::into_inner()
es un idioma muy común cuando se trabaja con Pest. Asegúrate de entender quéPair
es a.
Ahora es el momento de poner el trabajo. Aquí hay un ejemplo de un archivo de unidad Systemd:
[Unit]
Description=Nginx
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/home/ec2-user/.local/bin
Environment=LD_LIBRARY_PATH=/usr/local/lib
Environment=PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
ExecStart=/usr/local/sbin/nginx-runner.sh
Restart=on-failure
RestartSec=0
KillMode=process
[Install]
WantedBy=multi-user.target
El archivo está agrupado en secciones, cada una con un nombre entre corchetes. Cada sección contiene cero o más pares de nombre y valor de propiedad, separados por un signo igual "=".
Tratemos de desarrollar un conjunto de reglas. Cree un nuevo proyecto de óxido con cargo new --bin systemd-parser
, luego cree un archivo con el nombre src/grammar.pest
con las siguientes reglas:
/// Implicit white spaces are ok.
WHITESPACE = _{ " " }
/// Set of characters permited
char = { ASCII_ALPHANUMERIC | "." | "_" | "/" | "-" }
/// name is one or more chars. Note that white spaces are allowed.
name = { char+ }
// value can be zero or more char, plus = and : for path variables.
value = { (char | "=" | ":" )* }
/// section is a name, enclosed by square brackets.
section = { "[" ~ name ~ "]" }
/// property pair is a name and value, separated by an equal sign.
property = { name ~ "=" ~ value }
/// A Systemd unit file structure
file = {
SOI ~
((section | property)? ~ NEWLINE)* ~
EOI
}
En el main.rs
archivo, comience con lo siguiente
extern crate pest;
#[macro_use]
extern crate pest_derive;
use std::fs;
use std::env::current_dir;
use std::collections::HashMap;
use pest::Parser;
#[derive(Parser)]
#[grammar = "grammar.pest"]
struct SystemdParser;
/// Implement a simple AST representation
#[derive(Debug, Clone)]
pub enum SystemdValue {
List(Vec<String>),
Str(String),
}
// ...
Como primer paso, después de las importaciones y la configuración iniciales, definimos una SystemdValue
enumeración como una representación simple del tipo de datos en un archivo Systemd. SystemdValue::Str(String)
capturará un solo valor de propiedad y SystemdValue::List(Vec<String>)
capturará varios valores de propiedad con un nombre de clave de propiedad duplicado. Por ejemplo, en el nginx.service
archivo anterior hay varias Environment
propiedades.
Aquí está la main
función:
fn main() {
// Read and parse the unit file.
let unparsed_file = fs::read_to_string("nginx.service")
.expect("cannot read file");
let file = SystemdParser::parse(Rule::file, &unparsed_file).expect("fail to parse")
.next()
.unwrap();
// Create a fresh HashMap to store the data.
let mut properties: HashMap<String, HashMap<String, SystemdValue>> = HashMap::new();
// These two mutable variables will be used to store
// section name and property key name.
let mut current_section_name = String::new();
let mut current_key_name = String::new();
// Iterate over the file line-by-line.
for line in file.into_inner() {
match line.as_rule() {
Rule::section => {
// Update the current_section_name
let mut inner_rules = line.into_inner();
current_section_name = inner_rules.next().unwrap().as_str().to_string();
}
Rule::property => {
let mut inner_rules = line.into_inner();
// Get a sub map of properties with the current_section_name key, or create new.
let section = properties.entry(current_section_name.clone()).or_default();
// Get the current property name and value.
let name = inner_rules.next().unwrap().as_str().to_string();
let value = inner_rules.next().unwrap().as_str().to_string();
// If the property name already exists...
if name == current_key_name {
// Get the section of the map with the key name, or insert a new SytemdValue::List.
let entry = section.entry(current_key_name.clone()).or_insert(SystemdValue::List(vec![]));
// Push the value onto the inner vector of SystemdValue::List.
if let SystemdValue::List(ent) = entry {
ent.push(value);
}
} else {
// Create a new SystemdValue::List and save it under name key.
let entry = section.entry(name.clone()).or_insert(SystemdValue::List(vec![]));
// Push the current value onto the vector, then set the
// current_key_name to the current name.
if let SystemdValue::List(ent) = entry {
ent.push(value);
}
current_key_name = name;
}
}
Rule::EOI => (),
_ => unreachable!(),
}
}
}
Todo esto está bien, pero no usamos SystemdValue::Str
ninguna parte del código. Para mantener limpio el código, decidimos tratar cada propiedad como HashMap<String, SystemdValue::List(Vec<String>)
, donde la clave del mapa es la clave de propiedad y el vector String almacena la lista de valores de propiedad. Si no hay valor, el vector está vacío. Si hay un valor, este vector contiene ese único valor, y así sucesivamente.
Para que la API sea un poco más fácil de usar, escribiremos una pequeña función auxiliar para procesar todos los correos electrónicos de un solo valor Systemd::List(Vec<String>)
y convertirlos en archivos Systemd::Str(String)
.
// Iterate over the nested maps, and convert empty and
// single-element `SystemdValue::List<Vec<String>>` to
// `SystemdValue::Str(String)`.
fn pre_process_map(map: &mut HashMap<String, HashMap<String, SystemdValue>>) {
for (_, value) in map.into_iter() {
for (_, v) in value.into_iter() {
if let SystemdValue::List(vs) = v {
if vs.len() == 0 {
let v_ = SystemdValue::Str(String::new());
*v = v_.clone();
} else if vs.len() == 1 {
let v_ = SystemdValue::Str((vs[0]).clone());
*v = v_.clone();
}
}
}
}
}
¡Ahora estamos listos para imprimirlo para que el mundo lo vea!
fn main() {
// Our main code
pre_process_map(properties);
println!("{:#?}", properties);
}
¡Auge! ¡Felicidades! Acaba de escribir un analizador de archivos Systemd, además de uno mini JS. 🤯 Ahora tendrás algo de tiempo libre para divertirte el viernes por la noche. Con otra tarde, es posible que incluso descubras cómo serializar el archivo de tu unidad Systemd en JSON para impresionar a tu jefe el lunes.
Puede consultar el código del analizador implementado como biblioteca en [este repositorio] (https://github.com/jochasinga/systemd-parser)
Fuente: https://hackernoon.com/how-to-build-a-parser-in-rust-for-fun-and-profit
1601575800
After my partner and I built our first Ruby program in the first module of our Bootcamp, I was so excited by the accomplishment that the following weekend I decided to take my programming skills a step further and make a command-line game.
The result was Badgers and Gyms, a game where you kill badgers with grenades:
&: User | %: Badger
After I had graduated from the Bootcamp and was building a portfolio site for my projects, I wanted to incorporate this game into the site somehow. I looked around for ways to embed a terminal on the site that could run Ruby, but I couldn’t find anything. So, I decided to adapt the game into React.
The first problem I faced was how to display the game with moving parts and animations. When first learning JavaScript, I had played around with moving <div>
elements on the page, but that didn’t seem like the best way to handle this.
I had used SVG before, but not with moving parts. I started experimenting with some different things and discovered the <circle>
tag, which has a cx
and cy
attribute for positioning the circle within the <svg>
tag. This seemed like a straightforward way to start.
I found an SVG graphic of a basketball court on Wikimedia Commons and wrapped its paths in their own <g>
layer. I then added a second layer on top for the moving parts:
If you look at the bottom <g>
layer, you’ll see I’ve controlled the cx
and cy
attributes and pointed them to values on a user
object. The next task is to change those values to move the objects around within the boundaries of the basketball court.
If you look at the bottom <g>
layer, you’ll see I’ve controlled the cx
and cy
attributes and pointed them to values on a user
object. The next task is to change those values to move the objects around within the boundaries of the basketball court.
There are three types of moving objects in this game: the user, the badgers, and the grenades. While these three objects might move at different speeds, they all need to know how to move about the <svg>
basketball court.
#svg-animation #game-development #svg #react #javascript
1602788400
In my previous post about ensemble learning, I have explained what is ensemble learning, how it relates with Bias and Variance in machine learning and what are the simple techniques of ensemble learning. If you haven’t read the post, please refer here.
In this post I will cover ensemble learning types, advanced ensemble learning methods — Bagging, Boosting, Stacking and Blending with code samples. At the end I will explain some pros and cons of using ensemble learning.
Ensemble learning methods can be categorized into two groups:
1. Sequential Ensemble Methods
In this method base learners are dependent on the results from previous base learners. Every subsequent base model corrects the prediction made by its predecessor fixing the errors in it. Hence the overall performance can be increased via improving the weight of previous labels.
2. Parallel Ensemble Methods
In this method there is no dependency between the base learners and all base learners execute in parallel and the results of all base models are combined in the end (using averaging for regression and voting for classification problems).
Parallel Ensemble methods are divided in two categories-
**1. Homogeneous Parallel Ensemble Methods- **In this method a single machine learning algorithm is used as a base learner.
2. Heterogeneous Parallel Ensemble Methods- In this method multiple machine learning algorithms are used as base learners.
Bagging or Bootstrap Aggregation is a parallel ensemble learning technique to reduce the variance in the final prediction.
The Bagging process is very similar to averaging, only difference is that bagging uses random sub-samples of the original dataset to train same/multiple models and then combines the prediction, whereas in averaging the same dataset is used to train models. Hence the technique is called Bootstrap Aggregation as it combines both Bootstrapping (or Sampling of data) and Aggregation to form an ensemble model.
#artificial-intelligence #ensemble-learning #ensemble #data-science #machine-learning
1597288897
Learn why SVG is superior to pixel graphics in terms of scalability, responsiveness, interactivity, programmability, performance, and accessibility.
Though it was conceived back in the late 1990s, SVG is in many ways the “ugly duckling” file format that grew up to become a swan. Poorly supported and largely ignored for most of the 2000s, since around 2017 all modern web browsers have been rendering SVG without serious issues, and most vector drawing programs have been offering the option to export SVG, which has unquestionably become a widely used graphic format on the Web.
This hasn’t happened by chance. Although traditional raster graphic file formats like JPGs and PNGs are perfect for photographs or very complex images, it turns out that SVG is the one graphic format that most closely meets current web development demands of scalability, responsiveness, interactivity, programmability, performance, and accessibility.
SVG is an eXtensible Markup Language (XML)-based vector graphic format for the Web and other environments. XML uses tags like HTML, although it’s stricter. You cannot, for example, omit a closing tag since this will make the file invalid and the SVG will not be rendered.
To give you a taste of what SVG code looks like, here’s how you would draw a white circle with a black border:
<circle cx="100" cy="100" r="50" stroke-width="4" stroke="#000" fill="#fff" />
As you can see, under the hood, SVG documents are nothing more than simple plain text files that describe lines, curves, shapes, colors, and text. As it’s human-readable, easily understandable and modifiable, when embedded in an HTML document as an inline SVG, SVG code can be manipulated via CSS or JavaScript. This gives SVG a flexibility and versatility that can’t ever be matched by traditional PNG, GIF or JPG graphic formats.
SVG is a W3C standard, which means that it can inter-operate easily with other open standard languages and technologies including JavaScript, DOM, CSS, and HTML. As long as the W3C sets the global industry standards, it’s likely that SVG will continue to be the de facto standard for vector graphics in the browser.
The awesomeness of SVG is that it can solve many of the most vexing problems in modern web development. Let’s breeze through some of them.
#svg #ux #web-development #developer