Такой вопрос, как сделать Radial blur с помощью SVG? Порыв в гугле я понял что либо он в SVG не так называется, либо способа нет...
Это конечно не CSS, как и в других моих постах последнее время, будем окучивать WebGL / glsl, (мало внимания ему уделяется, это заметно по просмотрам)
Я написал маленькую функцию, чтобы вынести за скобки весь WebGL код, оставив один лишь фрагментный шейдер на входе:
document.body.append(webglFilter("https://i.imgur.com/cdqfoqZ.png", `
const int samples = 22; // кол-во сэмплов
const float power = 0.001; // сила эффекта
const vec2 center = vec2( 0.5, 0.5 ); // центр эффекта
// матрица поворота
mat2 rotate2d (float angle) {
vec2 sc = vec2( sin(angle), cos(angle) );
return mat2( sc.y, -sc.x, sc.xy );
}
vec4 frag (vec2 uv) {
vec4 color = vec4(0.); // аккумулятор
for (int i = 0; i < samples; i++) {
float dir = sin(length(uv - center)*200.); // направление повотора
dir = smoothstep(-.5, .5, dir) - .5; // делаем из синусоиды сглаженную
// ступенчатую функцию
uv -= center; // сдвиг к центру поворота
uv *= rotate2d( dir * power * float(i) ); // поворот
uv += center; // обратный сдвиг
color += sample(uv); // получить цвет
}
return color / float(samples); // взять среднее
}
`));
UPD1: попытался лучше повторить эффект на оригинальной картинке
UPD2: добавлена реакция на мышь
UPD3: radial blur теперь применяется плавно
UPD4: на мобилке теперь видно эффекты
UPD5: добавил еще сниппет
Версия со ступенчатой функцией поворота
let filter = webglFilter("https://i.imgur.com/cdqfoqZ.png", `
const int samples = 22;
uniform float power;
uniform vec2 mouse;
mat2 rotate2d (float angle) {
vec2 sc = vec2( sin(angle), cos(angle) );
return mat2( sc.y, -sc.x, sc.xy );
}
vec4 frag (vec2 uv) {
float rotateDir = sin(length(uv - mouse)*1./(0.005 + power*5.));
rotateDir = smoothstep(-.3, .3, rotateDir)-.5;
vec2 shiftDir = (uv-mouse)*vec2(-1.0,-1.0);
vec4 color = vec4(0.);
for (int i = 0; i < samples; i ++) {
uv += float(i)/float(samples)*shiftDir*0.01;
uv -= mouse;
uv *= rotate2d( rotateDir * power * float(i));
uv += mouse;
color += sample(uv) / float(samples);
}
return color;
}
`);
let changeCenter = function(e) {
e = e.touches ? e.touches[0] : e;
let c = filter.canvas;
let z = window.getComputedStyle(c).zoom;
let d = document.documentElement;
let x = (e.clientX + d.scrollLeft - c.offsetLeft*z) / c.width / z;
let y = (e.clientY + d.scrollTop - c.offsetTop*z) / c.height / z
filter.uniform('2f', 'mouse', x, y).apply();
}
var applyEffect = (function() {
let power = 0;
let targ = 0
let started = 0;
return function (pow) {
targ = pow;
started = new Date().getTime();
requestAnimationFrame(animate);
}
function animate() {
let dt = new Date().getTime() - started;
power += dt * 1e-6 * (targ === 0 ? -1 : 1);
power = Math[targ === 0 ? 'max' : 'min'](power, targ);
filter.uniform('1f', 'power', power).apply();
Math.abs(power-targ) > 1e-7 && requestAnimationFrame(animate)
}
})();
filter.ready = function() {
let c = filter.canvas;
document.body.append(c);
let z = window.getComputedStyle(c).zoom;
changeCenter({
clientX: c.width/2*z,
clientY: c.height/2*z,
});
applyEffect(0.001);
filter.apply();
window.addEventListener('mousemove', e => changeCenter(e))
window.addEventListener('touchmove', e => changeCenter(e))
window.addEventListener('mouseup', () => applyEffect(0))
window.addEventListener('touchend', () => applyEffect(0))
window.addEventListener('mousedown', () => applyEffect(0.001))
window.addEventListener('touchstart', () => applyEffect(0.001))
}
canvas {
zoom: 33%;
}
<script>
function webglFilter(url, fragCode) {
let canvas = document.createElement('canvas');
let pid, gl = canvas.getContext('webgl')
|| canvas.getContext('experimental-webgl');
let loader = new Image();
loader.crossOrigin = "anonymous";
loader.src = url;
loader.onload = function() {
canvas.width = loader.width;
canvas.height = loader.height;
pid = gl.createProgram();
shader(`
attribute vec2 coords;
void main(void) {
gl_Position = vec4(coords.xy, 0.0, 1.0);
}
`, gl.VERTEX_SHADER);
shader(`
precision highp float;
uniform sampler2D texture;
vec4 sample(vec2 uv) {
return texture2D(texture, uv);
}
${fragCode}
void main(void) {
gl_FragColor = frag(vec2(
gl_FragCoord.x / ${canvas.width}.,
1. - gl_FragCoord.y / ${canvas.height}.
));
}
`, gl.FRAGMENT_SHADER);
gl.linkProgram(pid);
gl.useProgram(pid);
let array = new Float32Array([-1, 3, -1, -1, 3, -1]);
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
gl.bufferData(gl.ARRAY_BUFFER, array, gl.STATIC_DRAW);
let al = gl.getAttribLocation(pid, "coords");
gl.vertexAttribPointer(al, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(al);
let texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, loader);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
var textureLocation = gl.getUniformLocation(pid, "texture");
gl.uniform1i(textureLocation, 0);
filter.ready && filter.ready();
function shader(src, type) {
let sid = gl.createShader(type);
gl.shaderSource(sid, src);
gl.compileShader(sid);
var message = gl.getShaderInfoLog(sid);
gl.attachShader(pid, sid);
if (message.length > 0) {
console.log(src.split('\n').map(function (str, i) {
return ("" + (1 + i)).padStart(4, "0") + ": " + str
}).join('\n'));
throw message;
}
}
}
let filter = {
canvas: canvas,
ready: null,
uniform: function(type, name, v1, v2, v3, v4) {
if (!pid)
throw new Error('image not loaded yet');
var ul = gl.getUniformLocation(pid, name);
gl['uniform' + type](ul, v1, v2, v3, v4);
return filter;
},
apply: function() {
if (!pid)
throw new Error('image not loaded yet');
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
gl.clearColor(0, 0, 0, 0);
gl.drawArrays(gl.TRIANGLES, 0, 3);
return filter;
}
}
return filter;
}
</script>
let filter = webglFilter("https://i.imgur.com/tbmyMTo.jpg", `
const int samples = 66;
uniform float power;
uniform vec2 mouse;
mat2 rotate2d (float angle) {
vec2 sc = vec2( sin(angle), cos(angle) );
return mat2( sc.y, -sc.x, sc.xy );
}
vec4 frag (vec2 uv) {
float rotateDir = length(uv - mouse)*1./(0.005 + power*5.);
rotateDir = smoothstep(-.3, .3, rotateDir)-.5;
vec2 shiftDir = (uv-mouse)*vec2(-1.0,-1.0);
vec4 color = vec4(0.);
for (int i = 0; i < samples; i ++) {
uv += float(i)/float(samples)*shiftDir*0.01;
uv -= mouse;
uv *= rotate2d( rotateDir * power * float(i));
uv += mouse;
color += sample(uv)/float(samples+i);
}
return color*1.5;
}
`);
let changeCenter = function(e) {
e = e.touches ? e.touches[0] : e;
let c = filter.canvas;
let z = window.getComputedStyle(c).zoom;
let d = document.documentElement;
let x = (e.clientX + d.scrollLeft - c.offsetLeft*z) / c.width / z;
let y = (e.clientY + d.scrollTop - c.offsetTop*z) / c.height / z
filter.uniform('2f', 'mouse', x, y).apply();
}
var applyEffect = (function() {
let power = 0;
let targ = 0
let started = 0;
return function (pow) {
targ = pow;
started = new Date().getTime();
requestAnimationFrame(animate);
}
function animate() {
let dt = new Date().getTime() - started;
power += dt * 1e-6 * (targ === 0 ? -1 : 1);
power = Math[targ === 0 ? 'max' : 'min'](power, targ);
filter.uniform('1f', 'power', power).apply();
Math.abs(power-targ) > 1e-7 && requestAnimationFrame(animate)
}
})();
filter.ready = function() {
let c = filter.canvas;
document.body.append(c);
let z = window.getComputedStyle(c).zoom;
changeCenter({
clientX: c.width/2*z,
clientY: c.height/2*z,
});
applyEffect(0.001);
filter.apply();
window.addEventListener('mousemove', e => changeCenter(e))
window.addEventListener('touchmove', e => changeCenter(e))
window.addEventListener('mouseup', () => applyEffect(0))
window.addEventListener('touchend', () => applyEffect(0))
window.addEventListener('mousedown', () => applyEffect(0.001))
window.addEventListener('touchstart', () => applyEffect(0.001))
}
canvas {
zoom:33%
}
<script>
function webglFilter(url, fragCode) {
let canvas = document.createElement('canvas');
let pid, gl = canvas.getContext('webgl')
|| canvas.getContext('experimental-webgl');
let loader = new Image();
loader.crossOrigin = "anonymous";
loader.src = url;
loader.onload = function() {
canvas.width = loader.width;
canvas.height = loader.height;
pid = gl.createProgram();
shader(`
attribute vec2 coords;
void main(void) {
gl_Position = vec4(coords.xy, 0.0, 1.0);
}
`, gl.VERTEX_SHADER);
shader(`
precision highp float;
uniform sampler2D texture;
vec4 sample(vec2 uv) {
return texture2D(texture, uv);
}
${fragCode}
void main(void) {
gl_FragColor = frag(vec2(
gl_FragCoord.x / ${canvas.width}.,
1. - gl_FragCoord.y / ${canvas.height}.
));
}
`, gl.FRAGMENT_SHADER);
gl.linkProgram(pid);
gl.useProgram(pid);
let array = new Float32Array([-1, 3, -1, -1, 3, -1]);
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
gl.bufferData(gl.ARRAY_BUFFER, array, gl.STATIC_DRAW);
let al = gl.getAttribLocation(pid, "coords");
gl.vertexAttribPointer(al, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(al);
let texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, loader);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
var textureLocation = gl.getUniformLocation(pid, "texture");
gl.uniform1i(textureLocation, 0);
filter.ready && filter.ready();
filter.apply();
function shader(src, type) {
let sid = gl.createShader(type);
gl.shaderSource(sid, src);
gl.compileShader(sid);
var message = gl.getShaderInfoLog(sid);
gl.attachShader(pid, sid);
if (message.length > 0) {
console.log(src.split('\n').map(function (str, i) {
return ("" + (1 + i)).padStart(4, "0") + ": " + str
}).join('\n'));
throw message;
}
}
}
let filter = {
canvas: canvas,
ready: null,
uniform: function(type, name, v1, v2, v3, v4) {
if (!pid)
throw new Error('program not ready');
var ul = gl.getUniformLocation(pid, name);
gl['uniform' + type](ul, v1, v2, v3, v4);
return filter;
},
apply: function() {
if (!pid)
throw new Error('program not ready');
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
gl.clearColor(0, 0, 0, 0);
gl.drawArrays(gl.TRIANGLES, 0, 3);
return filter;
}
}
return filter;
}
</script>
Не претендую на участие, ибо подхожу по меткам лишь частично, да и реализация - "костыль костыльный". Но, тем не менее, пока не дали ответы с SVG, нативный вариант:
var nDivs = 90;
var oWrap = document.querySelector('div.radial_blur');
var oDiv = document.createElement('DIV');
var oTemp;
/* Раскомментировать, если нужен только эффект, без анимации
while (nDivs--) {
oTemp = oWrap.querySelector('.radial_blur *:empty').appendChild(oDiv.cloneNode(true));
oTemp.style.transform = 'rotate(1deg)';
}
*/
/* Код ниже, только для наглядной демонстрации */
function radialBlur() {
oTemp = oWrap.querySelector('.radial_blur *:empty').appendChild(oDiv.cloneNode(true));
oTemp.style.transform = 'rotate(1deg)';
nDivs--;
if (!nDivs) { clearInterval(nIntervId); }
}
var nIntervId = window.setInterval(radialBlur, 80);
.radial_blur {
margin: 20px auto;
height: 400px;
width: 435px;
overflow: hidden;
border: 3px solid #000;
background: url('https://i.imgur.com/CQvNGGD_d.jpg?maxwidth=520&shape=thumb&fidelity=high') center/cover;
/* Можно попробовать с другим изображением
background: url('https://i.imgur.com/cdqfoqZ.png') center/cover; */
}
.radial_blur div {
height: inherit;
width: inherit;
background: inherit;
opacity: .95;
}
<div class="radial_blur">
<div></div>
</div>
Конечный вид очень сильно зависит от выбранной картинки.
При одинаковой схеме решения: последовательное применении радиальных градиентов, набора SVG фильтров, всё равно приходится тонко регулировать атрибуты всех SVG компонентов, чтобы получить требуемые эффекты.
cx="0.5" cy="0.55"
r="0.16"
для получения центра фокусировки и придания тунельной
переспективы. baseFrequency="0.01 0.01"
Чем меньше
цифры тем больше искажение. seed="12"
- коэффициент начального
искаженияscale="30"
- коэффициент увеличения искажения Добавлена анимация искажения при наведении мыши
.container {
width:100%;
height:100%;
}
<div class="container">
<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="900" height="600" viewBox="0 0 900 600" preserveAspectRatio="xMinYMin meet" style="border:1px solid gray;" >
<defs>
<mask id="msk1" >
<rect fill="white" width="100%" height="100%" />
<circle stroke="black" fill="white" cx="450" cy="300" r="450" stroke-width="0" />
<circle stroke="black" fill="white" cx="450" cy="300" r="350" stroke-width="0" />
</mask>
<filter id="filter1">
<feTurbulence type="turbulence" baseFrequency="0.01 0.01"
numOctaves="1" result="turbulence" seed="12"/>
<feDisplacementMap in2="turbulence" in="SourceGraphic"
scale="5" xChannelSelector="R" yChannelSelector="B"/>
</filter>
<filter id="goovey">
<feTurbulence type="fractalNoise" baseFrequency="0.015" numOctaves="3" result="warpper"/>
<feColorMatrix in="warpper" type="hueRotate" values="0" >
<animate attributeType="XML" attributeName="values" values="0;150;0" dur="5s" repeatCount="indefinite" begin="svg1.mouseover" end="svg1.mouseout"/>
</feColorMatrix>
<feDisplacementMap xChannelSelector="R" yChannelSelector="G" scale="25" in="SourceGraphic"/>
<feGaussianBlur stdDeviation="1"/>
</filter>
<radialGradient id="grad1" cx="0.5" cy="0.55" r="0.16" spreadMethod="reflect">
<stop offset="2%" stop-color="white"/>
<stop offset="15%" stop-color="#BED0DC" stop-opacity="1" />
<stop offset="55%" stop-color="white"/>
<stop offset="90%" stop-color="#BED0DC" stop-opacity="1"/>
</radialGradient>
<radialGradient id="grad2" cx="0.5" cy="0.6" r="0.06" spreadMethod="reflect">
<stop offset="2%" stop-color="white"/>
<stop offset="100%" stop-color="#BED0DC" stop-opacity="0.9" />
</radialGradient>
</defs>
<g>
<image id="img1" filter="url(#goovey)" xlink:href="https://i.stack.imgur.com/1Ty5b.jpg" width="100%" height="100%" />
<rect width="100%" height="100%" fill="url(#grad2)" fill-opacity="0.6" />
</g>
</svg>
</div>
Второй вариант.
Другая картинка и настройки немного другие
.container {
width:100%;
height:100%;
}
<div class="container">
<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="900" height="600" viewBox="0 0 900 600" preserveAspectRatio="xMinYMin meet" >
<defs>
<mask id="msk1" >
<rect fill="white" width="100%" height="100%" />
<circle stroke="black" fill="white" cx="450" cy="300" r="450" stroke-width="0" />
<circle stroke="black" fill="white" cx="450" cy="300" r="350" stroke-width="0" />
</mask>
<filter id="filter1">
<feTurbulence type="turbulence" baseFrequency="0.01 0.01"
numOctaves="1" result="turbulence" seed="12"/>
<feDisplacementMap in2="turbulence" in="SourceGraphic"
scale="5" xChannelSelector="R" yChannelSelector="B"/>
</filter>
<filter id="goovey">
<feTurbulence type="fractalNoise" baseFrequency="0.01" numOctaves="3" result="warpper"/>
<feColorMatrix in="warpper" type="hueRotate" values="0" >
<animate attributeType="XML" attributeName="values" values="0;150;0" dur="8s" repeatCount="indefinite" begin="svg1.mouseover" end="svg1.mouseout"/>
</feColorMatrix>
<feDisplacementMap xChannelSelector="R" yChannelSelector="G" scale="30" in="SourceGraphic"/>
</filter>
<radialGradient id="grad1" cx="0.5" cy="0.6" r="0.19" spreadMethod="reflect">
<stop offset="2%" stop-color="white"/>
<stop offset="52%" stop-color="#BED0DC" stop-opacity="0.5" />
<stop offset="85%" stop-color="white"/>
<stop offset="100%" stop-color="#BED0DC" stop-opacity="0.8"/>
</radialGradient>
<radialGradient id="grad2" cx="0.5" cy="0.6" r="0.06" spreadMethod="reflect">
<stop offset="2%" stop-color="white"/>
<stop offset="100%" stop-color="#BED0DC" stop-opacity="0.9" />
</radialGradient>
</defs>
<g>
<image id="img1" filter="url(#goovey)" xlink:href="https://i.stack.imgur.com/l1Mpe.jpg" width="100%" height="100%" />
<rect width="100%" height="100%" fill="url(#grad1)" fill-opacity="0.7" />
</g>
</svg>
</div>
Третий вариант
.container {
width:100%;
height:100%;
}
<div class="container">
<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="900" height="600" viewBox="0 0 900 600" preserveAspectRatio="xMinYMin meet">
<defs>
<mask id="msk1">
<rect fill="white" width="100%" height="100%" />
<circle stroke="black" fill="white" cx="450" cy="300" r="450" stroke-width="0" />
<circle stroke="black" fill="white" cx="450" cy="300" r="350" stroke-width="0" />
</mask>
<filter id="filter1">
<feTurbulence type="turbulence" baseFrequency="0.01 0.01"
numOctaves="1" result="turbulence" seed="12"/>
<feDisplacementMap in2="turbulence" in="SourceGraphic"
scale="5" xChannelSelector="R" yChannelSelector="B"/>
</filter>
<filter id="goovey">
<feTurbulence type="fractalNoise" baseFrequency="0.01" numOctaves="1" result="warpper"/>
<feColorMatrix in="warpper" type="hueRotate" values="0" >
<animate attributeType="XML" attributeName="values" values="0;150;0" dur="4s" repeatCount="indefinite" begin="svg1.mouseover" end="svg1.mouseout"/>
</feColorMatrix>
<feDisplacementMap xChannelSelector="R" yChannelSelector="G" scale="30" in="SourceGraphic"/>
<feGaussianBlur stdDeviation="1"/>
</filter>
<radialGradient id="grad1" cx="0.5" cy="0.6" r="0.25" spreadMethod="reflect">
<stop offset="2%" stop-color="white"/>
<stop offset="52%" stop-color="#BED0DC" stop-opacity="0.8" />
<stop offset="85%" stop-color="white"/>
<stop offset="100%" stop-color="#BED0DC" stop-opacity="0.8"/>
</radialGradient>
<radialGradient id="grad2" cx="0.5" cy="0.6" r="0.06" spreadMethod="reflect">
<stop offset="2%" stop-color="white"/>
<stop offset="100%" stop-color="#BED0DC" stop-opacity="0.9" />
</radialGradient>
</defs>
<g>
<image id="img1" filter="url(#goovey)" xlink:href="https://i.stack.imgur.com/ia9YO.jpg" width="100%" height="100%" />
<rect width="100%" height="100%" fill="url(#grad1)" fill-opacity="0.6" />
</g>
</svg>
</div>
Update 04.03.2019 г.
К градиентам применена анимация изменения радиуса градиента, создающая туннельный эффект с фокусировкой на отдельном человеке
Для демонстрации эффекта, откройте сниппет в полном формате и наведите курсор
.container {
width:100%;
height:100%;
}
<div class="container">
<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="900" height="600" viewBox="0 0 900 600" preserveAspectRatio="xMinYMin meet" >
<defs>
<mask id="msk1" >
<!-- <rect fill="white" width="100%" height="100%" /> -->
<circle cx="450" cy="300" r="400" stroke-width="100" stroke="url(#grad2)" fill="url(#grad1)" />
</mask>
<filter id="filter1">
<feTurbulence type="turbulence" baseFrequency="0.01 0.01"
numOctaves="1" result="turbulence" seed="12"/>
<feDisplacementMap in2="turbulence" in="SourceGraphic"
scale="5" xChannelSelector="R" yChannelSelector="B"/>
</filter>
<filter id="goovey">
<feTurbulence type="fractalNoise" baseFrequency="0.015" numOctaves="3" result="warpper"/>
<feColorMatrix in="warpper" type="hueRotate" values="0" >
<animate attributeType="XML" attributeName="values" values="0;150;0" dur="5s" repeatCount="indefinite" begin="svg1.mouseover" end="svg1.mouseout"/>
</feColorMatrix>
<feDisplacementMap xChannelSelector="R" yChannelSelector="G" scale="25" in="SourceGraphic"/>
<feGaussianBlur stdDeviation="1"/>
</filter>
<radialGradient id="grad1" cx="0.35" cy="0.48" r="0.14" spreadMethod="reflect">
<stop offset="2%" stop-color="white"/>
<stop offset="15%" stop-color="#BED0DC" stop-opacity="1" />
<stop offset="55%" stop-color="white"/>
<stop offset="90%" stop-color="#BED0DC" stop-opacity="1"/>
<animate
attributeType="XML"
attributeName="r"
values="0.2;0.035;0.2"
dur="20s"
repeatCount="indefinite"
begin="svg1.mouseover"
end="svg1.mouseout"/>
</radialGradient>
<radialGradient id="grad2" cx="0.5" cy="0.6" r="0.06" spreadMethod="reflect">
<stop offset="2%" stop-color="white"/>
<stop offset="100%" stop-color="#BED0DC" stop-opacity="0.9" />
</radialGradient>
</defs>
<image id="img1" mask="url(#msk1)" filter="url(#goovey)" xlink:href="https://i.stack.imgur.com/kp46o.jpg" width="100%" height="100%" />
</svg>
</div>
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Есть код ajax который работает с помощью библиотеки jquery:
Есть таблица DataGridView, в ней колонка с типом данных DataGridViewImageColumnКак добавить туда ссылку на изображение, чтобы показать картинку? По типу как...
Всем добрый деньСтолкнулся с проблемой включение "сенсорного" интерфейса на движке geckofx 60
Имеется строка запроса(ну или просто строка)/<контроллер>/<метод>/ далее параметры через "/"