SVG Gradient like Canvas Gradient?












0















Here is what I've built. You can drag the image around to explore the whole image.



<?xml version='1.0' standalone='no'?>
<svg version='1.1'>
<image xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='background-image' />
<clipPath>
<rect />
</clipPath>
<image xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='main-image'/>
</svg>


Instead of the clipped rectangle having solid edges, what I would like to do is something like this, except for SVG. The caveat is that it must be responsive since the clipped rectangle is responsive.



Is it possible to do something similar in SVG?



One idea that comes to mind is something similar to either of the following images, whereby multiple gradients would be used, but it seems like a whole lot of work for something that can be done so easily in canvas.



enter image description here



enter image description here










share|improve this question




















  • 1





    Your codepen does not work in FireFox.

    – Kosh Very
    Jan 19 at 0:00











  • @KoshVery it's the image. the image doesn't seem to be loading for some reason :/ why would that be?

    – Anthony
    Jan 19 at 0:17













  • @KoshVery i posted another Q here regarding that if youre interested

    – Anthony
    Jan 19 at 2:01






  • 1





    You must set width and height attribute in svg1. FF still doesn't support this part of svg2

    – Kaiido
    Jan 19 at 2:26


















0















Here is what I've built. You can drag the image around to explore the whole image.



<?xml version='1.0' standalone='no'?>
<svg version='1.1'>
<image xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='background-image' />
<clipPath>
<rect />
</clipPath>
<image xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='main-image'/>
</svg>


Instead of the clipped rectangle having solid edges, what I would like to do is something like this, except for SVG. The caveat is that it must be responsive since the clipped rectangle is responsive.



Is it possible to do something similar in SVG?



One idea that comes to mind is something similar to either of the following images, whereby multiple gradients would be used, but it seems like a whole lot of work for something that can be done so easily in canvas.



enter image description here



enter image description here










share|improve this question




















  • 1





    Your codepen does not work in FireFox.

    – Kosh Very
    Jan 19 at 0:00











  • @KoshVery it's the image. the image doesn't seem to be loading for some reason :/ why would that be?

    – Anthony
    Jan 19 at 0:17













  • @KoshVery i posted another Q here regarding that if youre interested

    – Anthony
    Jan 19 at 2:01






  • 1





    You must set width and height attribute in svg1. FF still doesn't support this part of svg2

    – Kaiido
    Jan 19 at 2:26
















0












0








0








Here is what I've built. You can drag the image around to explore the whole image.



<?xml version='1.0' standalone='no'?>
<svg version='1.1'>
<image xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='background-image' />
<clipPath>
<rect />
</clipPath>
<image xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='main-image'/>
</svg>


Instead of the clipped rectangle having solid edges, what I would like to do is something like this, except for SVG. The caveat is that it must be responsive since the clipped rectangle is responsive.



Is it possible to do something similar in SVG?



One idea that comes to mind is something similar to either of the following images, whereby multiple gradients would be used, but it seems like a whole lot of work for something that can be done so easily in canvas.



enter image description here



enter image description here










share|improve this question
















Here is what I've built. You can drag the image around to explore the whole image.



<?xml version='1.0' standalone='no'?>
<svg version='1.1'>
<image xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='background-image' />
<clipPath>
<rect />
</clipPath>
<image xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='main-image'/>
</svg>


Instead of the clipped rectangle having solid edges, what I would like to do is something like this, except for SVG. The caveat is that it must be responsive since the clipped rectangle is responsive.



Is it possible to do something similar in SVG?



One idea that comes to mind is something similar to either of the following images, whereby multiple gradients would be used, but it seems like a whole lot of work for something that can be done so easily in canvas.



enter image description here



enter image description here







javascript svg canvas gradient mask






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 18 at 23:53







Anthony

















asked Jan 18 at 23:48









AnthonyAnthony

1,333326




1,333326








  • 1





    Your codepen does not work in FireFox.

    – Kosh Very
    Jan 19 at 0:00











  • @KoshVery it's the image. the image doesn't seem to be loading for some reason :/ why would that be?

    – Anthony
    Jan 19 at 0:17













  • @KoshVery i posted another Q here regarding that if youre interested

    – Anthony
    Jan 19 at 2:01






  • 1





    You must set width and height attribute in svg1. FF still doesn't support this part of svg2

    – Kaiido
    Jan 19 at 2:26
















  • 1





    Your codepen does not work in FireFox.

    – Kosh Very
    Jan 19 at 0:00











  • @KoshVery it's the image. the image doesn't seem to be loading for some reason :/ why would that be?

    – Anthony
    Jan 19 at 0:17













  • @KoshVery i posted another Q here regarding that if youre interested

    – Anthony
    Jan 19 at 2:01






  • 1





    You must set width and height attribute in svg1. FF still doesn't support this part of svg2

    – Kaiido
    Jan 19 at 2:26










1




1





Your codepen does not work in FireFox.

– Kosh Very
Jan 19 at 0:00





Your codepen does not work in FireFox.

– Kosh Very
Jan 19 at 0:00













@KoshVery it's the image. the image doesn't seem to be loading for some reason :/ why would that be?

– Anthony
Jan 19 at 0:17







@KoshVery it's the image. the image doesn't seem to be loading for some reason :/ why would that be?

– Anthony
Jan 19 at 0:17















@KoshVery i posted another Q here regarding that if youre interested

– Anthony
Jan 19 at 2:01





@KoshVery i posted another Q here regarding that if youre interested

– Anthony
Jan 19 at 2:01




1




1





You must set width and height attribute in svg1. FF still doesn't support this part of svg2

– Kaiido
Jan 19 at 2:26







You must set width and height attribute in svg1. FF still doesn't support this part of svg2

– Kaiido
Jan 19 at 2:26














1 Answer
1






active

oldest

votes


















1














What you want is a <mask>.



In this mask, you will append your small rounded <rect> filled in black, with an feGaussianBlur applied on it.






const
bdy = document.body,
svg = document.getElementById('svg'),
crc = document.getElementById('circle'),
rec = document.getElementById('rectangle')
let
mousednX = 0,
mousednY = 0

window.addEventListener('load', position)
bdy.addEventListener('mousedown', mousedown)
window.addEventListener('mouseup', mouseup)
bdy.addEventListener('mousemove', moveEye)

function position(){
const
box = svg.getBoundingClientRect()
svg.style.left = -(box.width - innerWidth) / 2 + 'px'
svg.style.top = -(box.height - innerHeight) / 2 + 'px'
}

function mousedown(e){
e.preventDefault()
mousednX = e.clientX
mousednY = e.clientY
bdy.addEventListener('mousemove', mousemove)
}

function mouseup(){
bdy.removeEventListener('mousemove', mousemove)
}

function mousemove(e){
adjustX = e.clientX - mousednX
adjustY = e.clientY - mousednY
if (svg.getBoundingClientRect().left + adjustX < 0 && svg.getBoundingClientRect().right + adjustX > innerWidth){
svg.style.left = svg.getBoundingClientRect().left + adjustX + 'px'
} else if (svg.getBoundingClientRect().left + adjustX >= 0){
svg.style.left = 0 + 'px'
} else {
svg.style.left = -(svg.getBoundingClientRect().width - innerWidth)
}
if (svg.getBoundingClientRect().top + adjustY < 0 && svg.getBoundingClientRect().bottom + adjustY > innerHeight){
svg.style.top = svg.getBoundingClientRect().top + adjustY + 'px'
} else if (svg.getBoundingClientRect().top + adjustY >= 0){
svg.style.top = 0 + 'px'
} else {
svg.style.top = -(svg.getBoundingClientRect().height - innerHeight)
}
mousednX = e.clientX
mousednY = e.clientY
}

function moveEye(e){
rec.setAttribute('x', -(svg.getBoundingClientRect().left) + e.clientX - rec.getBoundingClientRect().width / 2)
rec.setAttribute('y', -(svg.getBoundingClientRect().top) + e.clientY - rec.getBoundingClientRect().height / 2)
}

body {
width: 100vw;
height: 100vh;
overflow: hidden;
margin: 0;
}

#svg {
width: 6144px;
height: 4608px;
position: absolute;
left: -3072px; /* set with JS */
top: -2304px; /* set with JS */
}

#background-image {
width: 6144px;
height: 4608px;
opacity: 0.25;
}

#rectangle {
width: 35vw;
height: 75vh;
}

#main-image {
width: 6144px;
height: 4608px;
mask: url(#myMask);
}
#myMask .bg {
width: 100%;
height: 100%;
}

<svg id='svg' viewBox='0 0 6144 4608' version='1.1'>
<defs>
<filter id="blurMe">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" />
</filter>
<mask id="myMask">
<rect class='bg'/>
<rect id='rectangle' x='3172' y='2404' rx='10' ry='10' fill="white" filter="url(#blurMe)"/>
</mask>
</defs>
<image x='0' y='0' preserveAspectRatio='none'
xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='background-image' />
<image x='0' y='0' preserveAspectRatio='none'
xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='main-image'/>
</svg>





But note that setting the dimensions of your svg elements through CSS is a new feature of SVG2 and that all browsers still didn't implemented it (e.g Firefox).
So here is an SVG1 compliant version, but there the vw/vh units won't work.






<svg width="500" height="500" viewBox="0 0 500 500">
<defs>
<filter id="blurMe">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" />
</filter>
<mask id="myMask">
<rect width="500" height="500" fill="black"/>
<rect y="100" fill="white" width="50" height="50" x="35" y="35" rx="5" ry="5" filter="url(#blurMe)"/>
</mask>
</defs>
<image xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='background-image' width="500" height="500" style="opacity:0.3"/>
<image xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='main-image' width="500" height="500" mask="url(#myMask)"/>
</svg>





And you could even make this all with a single image, by setting the background's fill color to some shade of gray:






<svg width="500" height="500" viewBox="0 0 500 500">
<defs>
<filter id="blurMe">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" />
</filter>
<mask id="myMask">
<rect width="500" height="500" fill="#333"/>
<rect y="100" fill="white" width="50" height="50" x="35" y="35" rx="5" ry="5" filter="url(#blurMe)"/>
</mask>
</defs>
<image xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='main-image' width="500" height="500" mask="url(#myMask)"/>
</svg>





Here is the interactive version with a single image.






share|improve this answer


























  • in ur first demo, the part of the map that is covered by the white is one image element, whereas the part that is not white is the other image correct? another caveat is that im going to be animating other elements around the edge of the "eye"/rectangle

    – Anthony
    Jan 19 at 3:39











  • What is white inside the <mask> is what will be kept as opaque in the masked element. What is black becomes transparent. So I first drew a full rect in black (its sizes are set in CSS), and your #rectangle in white. Then we apply this mask on the foreground image. But actually, using a gray rectangle as background, we could even do it all with a single <image>: jsfiddle.net/1gfx7jrL And for your animation thing, I'm not sure to get it, but you can add whatever you wish inside the mask: jsfiddle.net/1gfx7jrL/1

    – Kaiido
    Jan 19 at 4:05













  • i have yet to read over your comment in depth or word for word, but the reason i'm staying away from a mask and also using 2 images is because there will be icons displayed on one image (the image that is clipped) that i don't want to be visible on the white part of the image or outside of the "eye" window

    – Anthony
    Jan 20 at 23:15













  • well, it turns out my method wasn't even going to allow me to do what i wanted to do, therefore using a mask instead is most practical. however, i can't seem to get the additional image (you used an image of dice in your example) to also be the same level of transparency??? here is what i'm working with right now any idea what's going on here???

    – Anthony
    Jan 21 at 23:35











  • You need to see your mask as a standalone image, that will get applied to the target. There every black pixels will be removed on the target, while every white and transparent ones will stay untouched. So if you need an unified mask, you need to make this image unified. This should be done by changing your image so that what is currently black in there actually be the same gray as #background (#999), even if it is technically possible to apply a filter to do it, its a perf killer (on my FF, Chrome is good here).

    – Kaiido
    Jan 22 at 1:34













Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54262829%2fsvg-gradient-like-canvas-gradient%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














What you want is a <mask>.



In this mask, you will append your small rounded <rect> filled in black, with an feGaussianBlur applied on it.






const
bdy = document.body,
svg = document.getElementById('svg'),
crc = document.getElementById('circle'),
rec = document.getElementById('rectangle')
let
mousednX = 0,
mousednY = 0

window.addEventListener('load', position)
bdy.addEventListener('mousedown', mousedown)
window.addEventListener('mouseup', mouseup)
bdy.addEventListener('mousemove', moveEye)

function position(){
const
box = svg.getBoundingClientRect()
svg.style.left = -(box.width - innerWidth) / 2 + 'px'
svg.style.top = -(box.height - innerHeight) / 2 + 'px'
}

function mousedown(e){
e.preventDefault()
mousednX = e.clientX
mousednY = e.clientY
bdy.addEventListener('mousemove', mousemove)
}

function mouseup(){
bdy.removeEventListener('mousemove', mousemove)
}

function mousemove(e){
adjustX = e.clientX - mousednX
adjustY = e.clientY - mousednY
if (svg.getBoundingClientRect().left + adjustX < 0 && svg.getBoundingClientRect().right + adjustX > innerWidth){
svg.style.left = svg.getBoundingClientRect().left + adjustX + 'px'
} else if (svg.getBoundingClientRect().left + adjustX >= 0){
svg.style.left = 0 + 'px'
} else {
svg.style.left = -(svg.getBoundingClientRect().width - innerWidth)
}
if (svg.getBoundingClientRect().top + adjustY < 0 && svg.getBoundingClientRect().bottom + adjustY > innerHeight){
svg.style.top = svg.getBoundingClientRect().top + adjustY + 'px'
} else if (svg.getBoundingClientRect().top + adjustY >= 0){
svg.style.top = 0 + 'px'
} else {
svg.style.top = -(svg.getBoundingClientRect().height - innerHeight)
}
mousednX = e.clientX
mousednY = e.clientY
}

function moveEye(e){
rec.setAttribute('x', -(svg.getBoundingClientRect().left) + e.clientX - rec.getBoundingClientRect().width / 2)
rec.setAttribute('y', -(svg.getBoundingClientRect().top) + e.clientY - rec.getBoundingClientRect().height / 2)
}

body {
width: 100vw;
height: 100vh;
overflow: hidden;
margin: 0;
}

#svg {
width: 6144px;
height: 4608px;
position: absolute;
left: -3072px; /* set with JS */
top: -2304px; /* set with JS */
}

#background-image {
width: 6144px;
height: 4608px;
opacity: 0.25;
}

#rectangle {
width: 35vw;
height: 75vh;
}

#main-image {
width: 6144px;
height: 4608px;
mask: url(#myMask);
}
#myMask .bg {
width: 100%;
height: 100%;
}

<svg id='svg' viewBox='0 0 6144 4608' version='1.1'>
<defs>
<filter id="blurMe">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" />
</filter>
<mask id="myMask">
<rect class='bg'/>
<rect id='rectangle' x='3172' y='2404' rx='10' ry='10' fill="white" filter="url(#blurMe)"/>
</mask>
</defs>
<image x='0' y='0' preserveAspectRatio='none'
xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='background-image' />
<image x='0' y='0' preserveAspectRatio='none'
xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='main-image'/>
</svg>





But note that setting the dimensions of your svg elements through CSS is a new feature of SVG2 and that all browsers still didn't implemented it (e.g Firefox).
So here is an SVG1 compliant version, but there the vw/vh units won't work.






<svg width="500" height="500" viewBox="0 0 500 500">
<defs>
<filter id="blurMe">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" />
</filter>
<mask id="myMask">
<rect width="500" height="500" fill="black"/>
<rect y="100" fill="white" width="50" height="50" x="35" y="35" rx="5" ry="5" filter="url(#blurMe)"/>
</mask>
</defs>
<image xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='background-image' width="500" height="500" style="opacity:0.3"/>
<image xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='main-image' width="500" height="500" mask="url(#myMask)"/>
</svg>





And you could even make this all with a single image, by setting the background's fill color to some shade of gray:






<svg width="500" height="500" viewBox="0 0 500 500">
<defs>
<filter id="blurMe">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" />
</filter>
<mask id="myMask">
<rect width="500" height="500" fill="#333"/>
<rect y="100" fill="white" width="50" height="50" x="35" y="35" rx="5" ry="5" filter="url(#blurMe)"/>
</mask>
</defs>
<image xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='main-image' width="500" height="500" mask="url(#myMask)"/>
</svg>





Here is the interactive version with a single image.






share|improve this answer


























  • in ur first demo, the part of the map that is covered by the white is one image element, whereas the part that is not white is the other image correct? another caveat is that im going to be animating other elements around the edge of the "eye"/rectangle

    – Anthony
    Jan 19 at 3:39











  • What is white inside the <mask> is what will be kept as opaque in the masked element. What is black becomes transparent. So I first drew a full rect in black (its sizes are set in CSS), and your #rectangle in white. Then we apply this mask on the foreground image. But actually, using a gray rectangle as background, we could even do it all with a single <image>: jsfiddle.net/1gfx7jrL And for your animation thing, I'm not sure to get it, but you can add whatever you wish inside the mask: jsfiddle.net/1gfx7jrL/1

    – Kaiido
    Jan 19 at 4:05













  • i have yet to read over your comment in depth or word for word, but the reason i'm staying away from a mask and also using 2 images is because there will be icons displayed on one image (the image that is clipped) that i don't want to be visible on the white part of the image or outside of the "eye" window

    – Anthony
    Jan 20 at 23:15













  • well, it turns out my method wasn't even going to allow me to do what i wanted to do, therefore using a mask instead is most practical. however, i can't seem to get the additional image (you used an image of dice in your example) to also be the same level of transparency??? here is what i'm working with right now any idea what's going on here???

    – Anthony
    Jan 21 at 23:35











  • You need to see your mask as a standalone image, that will get applied to the target. There every black pixels will be removed on the target, while every white and transparent ones will stay untouched. So if you need an unified mask, you need to make this image unified. This should be done by changing your image so that what is currently black in there actually be the same gray as #background (#999), even if it is technically possible to apply a filter to do it, its a perf killer (on my FF, Chrome is good here).

    – Kaiido
    Jan 22 at 1:34


















1














What you want is a <mask>.



In this mask, you will append your small rounded <rect> filled in black, with an feGaussianBlur applied on it.






const
bdy = document.body,
svg = document.getElementById('svg'),
crc = document.getElementById('circle'),
rec = document.getElementById('rectangle')
let
mousednX = 0,
mousednY = 0

window.addEventListener('load', position)
bdy.addEventListener('mousedown', mousedown)
window.addEventListener('mouseup', mouseup)
bdy.addEventListener('mousemove', moveEye)

function position(){
const
box = svg.getBoundingClientRect()
svg.style.left = -(box.width - innerWidth) / 2 + 'px'
svg.style.top = -(box.height - innerHeight) / 2 + 'px'
}

function mousedown(e){
e.preventDefault()
mousednX = e.clientX
mousednY = e.clientY
bdy.addEventListener('mousemove', mousemove)
}

function mouseup(){
bdy.removeEventListener('mousemove', mousemove)
}

function mousemove(e){
adjustX = e.clientX - mousednX
adjustY = e.clientY - mousednY
if (svg.getBoundingClientRect().left + adjustX < 0 && svg.getBoundingClientRect().right + adjustX > innerWidth){
svg.style.left = svg.getBoundingClientRect().left + adjustX + 'px'
} else if (svg.getBoundingClientRect().left + adjustX >= 0){
svg.style.left = 0 + 'px'
} else {
svg.style.left = -(svg.getBoundingClientRect().width - innerWidth)
}
if (svg.getBoundingClientRect().top + adjustY < 0 && svg.getBoundingClientRect().bottom + adjustY > innerHeight){
svg.style.top = svg.getBoundingClientRect().top + adjustY + 'px'
} else if (svg.getBoundingClientRect().top + adjustY >= 0){
svg.style.top = 0 + 'px'
} else {
svg.style.top = -(svg.getBoundingClientRect().height - innerHeight)
}
mousednX = e.clientX
mousednY = e.clientY
}

function moveEye(e){
rec.setAttribute('x', -(svg.getBoundingClientRect().left) + e.clientX - rec.getBoundingClientRect().width / 2)
rec.setAttribute('y', -(svg.getBoundingClientRect().top) + e.clientY - rec.getBoundingClientRect().height / 2)
}

body {
width: 100vw;
height: 100vh;
overflow: hidden;
margin: 0;
}

#svg {
width: 6144px;
height: 4608px;
position: absolute;
left: -3072px; /* set with JS */
top: -2304px; /* set with JS */
}

#background-image {
width: 6144px;
height: 4608px;
opacity: 0.25;
}

#rectangle {
width: 35vw;
height: 75vh;
}

#main-image {
width: 6144px;
height: 4608px;
mask: url(#myMask);
}
#myMask .bg {
width: 100%;
height: 100%;
}

<svg id='svg' viewBox='0 0 6144 4608' version='1.1'>
<defs>
<filter id="blurMe">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" />
</filter>
<mask id="myMask">
<rect class='bg'/>
<rect id='rectangle' x='3172' y='2404' rx='10' ry='10' fill="white" filter="url(#blurMe)"/>
</mask>
</defs>
<image x='0' y='0' preserveAspectRatio='none'
xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='background-image' />
<image x='0' y='0' preserveAspectRatio='none'
xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='main-image'/>
</svg>





But note that setting the dimensions of your svg elements through CSS is a new feature of SVG2 and that all browsers still didn't implemented it (e.g Firefox).
So here is an SVG1 compliant version, but there the vw/vh units won't work.






<svg width="500" height="500" viewBox="0 0 500 500">
<defs>
<filter id="blurMe">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" />
</filter>
<mask id="myMask">
<rect width="500" height="500" fill="black"/>
<rect y="100" fill="white" width="50" height="50" x="35" y="35" rx="5" ry="5" filter="url(#blurMe)"/>
</mask>
</defs>
<image xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='background-image' width="500" height="500" style="opacity:0.3"/>
<image xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='main-image' width="500" height="500" mask="url(#myMask)"/>
</svg>





And you could even make this all with a single image, by setting the background's fill color to some shade of gray:






<svg width="500" height="500" viewBox="0 0 500 500">
<defs>
<filter id="blurMe">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" />
</filter>
<mask id="myMask">
<rect width="500" height="500" fill="#333"/>
<rect y="100" fill="white" width="50" height="50" x="35" y="35" rx="5" ry="5" filter="url(#blurMe)"/>
</mask>
</defs>
<image xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='main-image' width="500" height="500" mask="url(#myMask)"/>
</svg>





Here is the interactive version with a single image.






share|improve this answer


























  • in ur first demo, the part of the map that is covered by the white is one image element, whereas the part that is not white is the other image correct? another caveat is that im going to be animating other elements around the edge of the "eye"/rectangle

    – Anthony
    Jan 19 at 3:39











  • What is white inside the <mask> is what will be kept as opaque in the masked element. What is black becomes transparent. So I first drew a full rect in black (its sizes are set in CSS), and your #rectangle in white. Then we apply this mask on the foreground image. But actually, using a gray rectangle as background, we could even do it all with a single <image>: jsfiddle.net/1gfx7jrL And for your animation thing, I'm not sure to get it, but you can add whatever you wish inside the mask: jsfiddle.net/1gfx7jrL/1

    – Kaiido
    Jan 19 at 4:05













  • i have yet to read over your comment in depth or word for word, but the reason i'm staying away from a mask and also using 2 images is because there will be icons displayed on one image (the image that is clipped) that i don't want to be visible on the white part of the image or outside of the "eye" window

    – Anthony
    Jan 20 at 23:15













  • well, it turns out my method wasn't even going to allow me to do what i wanted to do, therefore using a mask instead is most practical. however, i can't seem to get the additional image (you used an image of dice in your example) to also be the same level of transparency??? here is what i'm working with right now any idea what's going on here???

    – Anthony
    Jan 21 at 23:35











  • You need to see your mask as a standalone image, that will get applied to the target. There every black pixels will be removed on the target, while every white and transparent ones will stay untouched. So if you need an unified mask, you need to make this image unified. This should be done by changing your image so that what is currently black in there actually be the same gray as #background (#999), even if it is technically possible to apply a filter to do it, its a perf killer (on my FF, Chrome is good here).

    – Kaiido
    Jan 22 at 1:34
















1












1








1







What you want is a <mask>.



In this mask, you will append your small rounded <rect> filled in black, with an feGaussianBlur applied on it.






const
bdy = document.body,
svg = document.getElementById('svg'),
crc = document.getElementById('circle'),
rec = document.getElementById('rectangle')
let
mousednX = 0,
mousednY = 0

window.addEventListener('load', position)
bdy.addEventListener('mousedown', mousedown)
window.addEventListener('mouseup', mouseup)
bdy.addEventListener('mousemove', moveEye)

function position(){
const
box = svg.getBoundingClientRect()
svg.style.left = -(box.width - innerWidth) / 2 + 'px'
svg.style.top = -(box.height - innerHeight) / 2 + 'px'
}

function mousedown(e){
e.preventDefault()
mousednX = e.clientX
mousednY = e.clientY
bdy.addEventListener('mousemove', mousemove)
}

function mouseup(){
bdy.removeEventListener('mousemove', mousemove)
}

function mousemove(e){
adjustX = e.clientX - mousednX
adjustY = e.clientY - mousednY
if (svg.getBoundingClientRect().left + adjustX < 0 && svg.getBoundingClientRect().right + adjustX > innerWidth){
svg.style.left = svg.getBoundingClientRect().left + adjustX + 'px'
} else if (svg.getBoundingClientRect().left + adjustX >= 0){
svg.style.left = 0 + 'px'
} else {
svg.style.left = -(svg.getBoundingClientRect().width - innerWidth)
}
if (svg.getBoundingClientRect().top + adjustY < 0 && svg.getBoundingClientRect().bottom + adjustY > innerHeight){
svg.style.top = svg.getBoundingClientRect().top + adjustY + 'px'
} else if (svg.getBoundingClientRect().top + adjustY >= 0){
svg.style.top = 0 + 'px'
} else {
svg.style.top = -(svg.getBoundingClientRect().height - innerHeight)
}
mousednX = e.clientX
mousednY = e.clientY
}

function moveEye(e){
rec.setAttribute('x', -(svg.getBoundingClientRect().left) + e.clientX - rec.getBoundingClientRect().width / 2)
rec.setAttribute('y', -(svg.getBoundingClientRect().top) + e.clientY - rec.getBoundingClientRect().height / 2)
}

body {
width: 100vw;
height: 100vh;
overflow: hidden;
margin: 0;
}

#svg {
width: 6144px;
height: 4608px;
position: absolute;
left: -3072px; /* set with JS */
top: -2304px; /* set with JS */
}

#background-image {
width: 6144px;
height: 4608px;
opacity: 0.25;
}

#rectangle {
width: 35vw;
height: 75vh;
}

#main-image {
width: 6144px;
height: 4608px;
mask: url(#myMask);
}
#myMask .bg {
width: 100%;
height: 100%;
}

<svg id='svg' viewBox='0 0 6144 4608' version='1.1'>
<defs>
<filter id="blurMe">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" />
</filter>
<mask id="myMask">
<rect class='bg'/>
<rect id='rectangle' x='3172' y='2404' rx='10' ry='10' fill="white" filter="url(#blurMe)"/>
</mask>
</defs>
<image x='0' y='0' preserveAspectRatio='none'
xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='background-image' />
<image x='0' y='0' preserveAspectRatio='none'
xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='main-image'/>
</svg>





But note that setting the dimensions of your svg elements through CSS is a new feature of SVG2 and that all browsers still didn't implemented it (e.g Firefox).
So here is an SVG1 compliant version, but there the vw/vh units won't work.






<svg width="500" height="500" viewBox="0 0 500 500">
<defs>
<filter id="blurMe">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" />
</filter>
<mask id="myMask">
<rect width="500" height="500" fill="black"/>
<rect y="100" fill="white" width="50" height="50" x="35" y="35" rx="5" ry="5" filter="url(#blurMe)"/>
</mask>
</defs>
<image xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='background-image' width="500" height="500" style="opacity:0.3"/>
<image xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='main-image' width="500" height="500" mask="url(#myMask)"/>
</svg>





And you could even make this all with a single image, by setting the background's fill color to some shade of gray:






<svg width="500" height="500" viewBox="0 0 500 500">
<defs>
<filter id="blurMe">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" />
</filter>
<mask id="myMask">
<rect width="500" height="500" fill="#333"/>
<rect y="100" fill="white" width="50" height="50" x="35" y="35" rx="5" ry="5" filter="url(#blurMe)"/>
</mask>
</defs>
<image xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='main-image' width="500" height="500" mask="url(#myMask)"/>
</svg>





Here is the interactive version with a single image.






share|improve this answer















What you want is a <mask>.



In this mask, you will append your small rounded <rect> filled in black, with an feGaussianBlur applied on it.






const
bdy = document.body,
svg = document.getElementById('svg'),
crc = document.getElementById('circle'),
rec = document.getElementById('rectangle')
let
mousednX = 0,
mousednY = 0

window.addEventListener('load', position)
bdy.addEventListener('mousedown', mousedown)
window.addEventListener('mouseup', mouseup)
bdy.addEventListener('mousemove', moveEye)

function position(){
const
box = svg.getBoundingClientRect()
svg.style.left = -(box.width - innerWidth) / 2 + 'px'
svg.style.top = -(box.height - innerHeight) / 2 + 'px'
}

function mousedown(e){
e.preventDefault()
mousednX = e.clientX
mousednY = e.clientY
bdy.addEventListener('mousemove', mousemove)
}

function mouseup(){
bdy.removeEventListener('mousemove', mousemove)
}

function mousemove(e){
adjustX = e.clientX - mousednX
adjustY = e.clientY - mousednY
if (svg.getBoundingClientRect().left + adjustX < 0 && svg.getBoundingClientRect().right + adjustX > innerWidth){
svg.style.left = svg.getBoundingClientRect().left + adjustX + 'px'
} else if (svg.getBoundingClientRect().left + adjustX >= 0){
svg.style.left = 0 + 'px'
} else {
svg.style.left = -(svg.getBoundingClientRect().width - innerWidth)
}
if (svg.getBoundingClientRect().top + adjustY < 0 && svg.getBoundingClientRect().bottom + adjustY > innerHeight){
svg.style.top = svg.getBoundingClientRect().top + adjustY + 'px'
} else if (svg.getBoundingClientRect().top + adjustY >= 0){
svg.style.top = 0 + 'px'
} else {
svg.style.top = -(svg.getBoundingClientRect().height - innerHeight)
}
mousednX = e.clientX
mousednY = e.clientY
}

function moveEye(e){
rec.setAttribute('x', -(svg.getBoundingClientRect().left) + e.clientX - rec.getBoundingClientRect().width / 2)
rec.setAttribute('y', -(svg.getBoundingClientRect().top) + e.clientY - rec.getBoundingClientRect().height / 2)
}

body {
width: 100vw;
height: 100vh;
overflow: hidden;
margin: 0;
}

#svg {
width: 6144px;
height: 4608px;
position: absolute;
left: -3072px; /* set with JS */
top: -2304px; /* set with JS */
}

#background-image {
width: 6144px;
height: 4608px;
opacity: 0.25;
}

#rectangle {
width: 35vw;
height: 75vh;
}

#main-image {
width: 6144px;
height: 4608px;
mask: url(#myMask);
}
#myMask .bg {
width: 100%;
height: 100%;
}

<svg id='svg' viewBox='0 0 6144 4608' version='1.1'>
<defs>
<filter id="blurMe">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" />
</filter>
<mask id="myMask">
<rect class='bg'/>
<rect id='rectangle' x='3172' y='2404' rx='10' ry='10' fill="white" filter="url(#blurMe)"/>
</mask>
</defs>
<image x='0' y='0' preserveAspectRatio='none'
xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='background-image' />
<image x='0' y='0' preserveAspectRatio='none'
xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='main-image'/>
</svg>





But note that setting the dimensions of your svg elements through CSS is a new feature of SVG2 and that all browsers still didn't implemented it (e.g Firefox).
So here is an SVG1 compliant version, but there the vw/vh units won't work.






<svg width="500" height="500" viewBox="0 0 500 500">
<defs>
<filter id="blurMe">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" />
</filter>
<mask id="myMask">
<rect width="500" height="500" fill="black"/>
<rect y="100" fill="white" width="50" height="50" x="35" y="35" rx="5" ry="5" filter="url(#blurMe)"/>
</mask>
</defs>
<image xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='background-image' width="500" height="500" style="opacity:0.3"/>
<image xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='main-image' width="500" height="500" mask="url(#myMask)"/>
</svg>





And you could even make this all with a single image, by setting the background's fill color to some shade of gray:






<svg width="500" height="500" viewBox="0 0 500 500">
<defs>
<filter id="blurMe">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" />
</filter>
<mask id="myMask">
<rect width="500" height="500" fill="#333"/>
<rect y="100" fill="white" width="50" height="50" x="35" y="35" rx="5" ry="5" filter="url(#blurMe)"/>
</mask>
</defs>
<image xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='main-image' width="500" height="500" mask="url(#myMask)"/>
</svg>





Here is the interactive version with a single image.






const
bdy = document.body,
svg = document.getElementById('svg'),
crc = document.getElementById('circle'),
rec = document.getElementById('rectangle')
let
mousednX = 0,
mousednY = 0

window.addEventListener('load', position)
bdy.addEventListener('mousedown', mousedown)
window.addEventListener('mouseup', mouseup)
bdy.addEventListener('mousemove', moveEye)

function position(){
const
box = svg.getBoundingClientRect()
svg.style.left = -(box.width - innerWidth) / 2 + 'px'
svg.style.top = -(box.height - innerHeight) / 2 + 'px'
}

function mousedown(e){
e.preventDefault()
mousednX = e.clientX
mousednY = e.clientY
bdy.addEventListener('mousemove', mousemove)
}

function mouseup(){
bdy.removeEventListener('mousemove', mousemove)
}

function mousemove(e){
adjustX = e.clientX - mousednX
adjustY = e.clientY - mousednY
if (svg.getBoundingClientRect().left + adjustX < 0 && svg.getBoundingClientRect().right + adjustX > innerWidth){
svg.style.left = svg.getBoundingClientRect().left + adjustX + 'px'
} else if (svg.getBoundingClientRect().left + adjustX >= 0){
svg.style.left = 0 + 'px'
} else {
svg.style.left = -(svg.getBoundingClientRect().width - innerWidth)
}
if (svg.getBoundingClientRect().top + adjustY < 0 && svg.getBoundingClientRect().bottom + adjustY > innerHeight){
svg.style.top = svg.getBoundingClientRect().top + adjustY + 'px'
} else if (svg.getBoundingClientRect().top + adjustY >= 0){
svg.style.top = 0 + 'px'
} else {
svg.style.top = -(svg.getBoundingClientRect().height - innerHeight)
}
mousednX = e.clientX
mousednY = e.clientY
}

function moveEye(e){
rec.setAttribute('x', -(svg.getBoundingClientRect().left) + e.clientX - rec.getBoundingClientRect().width / 2)
rec.setAttribute('y', -(svg.getBoundingClientRect().top) + e.clientY - rec.getBoundingClientRect().height / 2)
}

body {
width: 100vw;
height: 100vh;
overflow: hidden;
margin: 0;
}

#svg {
width: 6144px;
height: 4608px;
position: absolute;
left: -3072px; /* set with JS */
top: -2304px; /* set with JS */
}

#background-image {
width: 6144px;
height: 4608px;
opacity: 0.25;
}

#rectangle {
width: 35vw;
height: 75vh;
}

#main-image {
width: 6144px;
height: 4608px;
mask: url(#myMask);
}
#myMask .bg {
width: 100%;
height: 100%;
}

<svg id='svg' viewBox='0 0 6144 4608' version='1.1'>
<defs>
<filter id="blurMe">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" />
</filter>
<mask id="myMask">
<rect class='bg'/>
<rect id='rectangle' x='3172' y='2404' rx='10' ry='10' fill="white" filter="url(#blurMe)"/>
</mask>
</defs>
<image x='0' y='0' preserveAspectRatio='none'
xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='background-image' />
<image x='0' y='0' preserveAspectRatio='none'
xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='main-image'/>
</svg>





const
bdy = document.body,
svg = document.getElementById('svg'),
crc = document.getElementById('circle'),
rec = document.getElementById('rectangle')
let
mousednX = 0,
mousednY = 0

window.addEventListener('load', position)
bdy.addEventListener('mousedown', mousedown)
window.addEventListener('mouseup', mouseup)
bdy.addEventListener('mousemove', moveEye)

function position(){
const
box = svg.getBoundingClientRect()
svg.style.left = -(box.width - innerWidth) / 2 + 'px'
svg.style.top = -(box.height - innerHeight) / 2 + 'px'
}

function mousedown(e){
e.preventDefault()
mousednX = e.clientX
mousednY = e.clientY
bdy.addEventListener('mousemove', mousemove)
}

function mouseup(){
bdy.removeEventListener('mousemove', mousemove)
}

function mousemove(e){
adjustX = e.clientX - mousednX
adjustY = e.clientY - mousednY
if (svg.getBoundingClientRect().left + adjustX < 0 && svg.getBoundingClientRect().right + adjustX > innerWidth){
svg.style.left = svg.getBoundingClientRect().left + adjustX + 'px'
} else if (svg.getBoundingClientRect().left + adjustX >= 0){
svg.style.left = 0 + 'px'
} else {
svg.style.left = -(svg.getBoundingClientRect().width - innerWidth)
}
if (svg.getBoundingClientRect().top + adjustY < 0 && svg.getBoundingClientRect().bottom + adjustY > innerHeight){
svg.style.top = svg.getBoundingClientRect().top + adjustY + 'px'
} else if (svg.getBoundingClientRect().top + adjustY >= 0){
svg.style.top = 0 + 'px'
} else {
svg.style.top = -(svg.getBoundingClientRect().height - innerHeight)
}
mousednX = e.clientX
mousednY = e.clientY
}

function moveEye(e){
rec.setAttribute('x', -(svg.getBoundingClientRect().left) + e.clientX - rec.getBoundingClientRect().width / 2)
rec.setAttribute('y', -(svg.getBoundingClientRect().top) + e.clientY - rec.getBoundingClientRect().height / 2)
}

body {
width: 100vw;
height: 100vh;
overflow: hidden;
margin: 0;
}

#svg {
width: 6144px;
height: 4608px;
position: absolute;
left: -3072px; /* set with JS */
top: -2304px; /* set with JS */
}

#background-image {
width: 6144px;
height: 4608px;
opacity: 0.25;
}

#rectangle {
width: 35vw;
height: 75vh;
}

#main-image {
width: 6144px;
height: 4608px;
mask: url(#myMask);
}
#myMask .bg {
width: 100%;
height: 100%;
}

<svg id='svg' viewBox='0 0 6144 4608' version='1.1'>
<defs>
<filter id="blurMe">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" />
</filter>
<mask id="myMask">
<rect class='bg'/>
<rect id='rectangle' x='3172' y='2404' rx='10' ry='10' fill="white" filter="url(#blurMe)"/>
</mask>
</defs>
<image x='0' y='0' preserveAspectRatio='none'
xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='background-image' />
<image x='0' y='0' preserveAspectRatio='none'
xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='main-image'/>
</svg>





<svg width="500" height="500" viewBox="0 0 500 500">
<defs>
<filter id="blurMe">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" />
</filter>
<mask id="myMask">
<rect width="500" height="500" fill="black"/>
<rect y="100" fill="white" width="50" height="50" x="35" y="35" rx="5" ry="5" filter="url(#blurMe)"/>
</mask>
</defs>
<image xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='background-image' width="500" height="500" style="opacity:0.3"/>
<image xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='main-image' width="500" height="500" mask="url(#myMask)"/>
</svg>





<svg width="500" height="500" viewBox="0 0 500 500">
<defs>
<filter id="blurMe">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" />
</filter>
<mask id="myMask">
<rect width="500" height="500" fill="black"/>
<rect y="100" fill="white" width="50" height="50" x="35" y="35" rx="5" ry="5" filter="url(#blurMe)"/>
</mask>
</defs>
<image xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='background-image' width="500" height="500" style="opacity:0.3"/>
<image xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='main-image' width="500" height="500" mask="url(#myMask)"/>
</svg>





<svg width="500" height="500" viewBox="0 0 500 500">
<defs>
<filter id="blurMe">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" />
</filter>
<mask id="myMask">
<rect width="500" height="500" fill="#333"/>
<rect y="100" fill="white" width="50" height="50" x="35" y="35" rx="5" ry="5" filter="url(#blurMe)"/>
</mask>
</defs>
<image xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='main-image' width="500" height="500" mask="url(#myMask)"/>
</svg>





<svg width="500" height="500" viewBox="0 0 500 500">
<defs>
<filter id="blurMe">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" />
</filter>
<mask id="myMask">
<rect width="500" height="500" fill="#333"/>
<rect y="100" fill="white" width="50" height="50" x="35" y="35" rx="5" ry="5" filter="url(#blurMe)"/>
</mask>
</defs>
<image xlink:href='https://i.postimg.cc/hvH4yn2Q/map.jpg'
id='main-image' width="500" height="500" mask="url(#myMask)"/>
</svg>






share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 19 at 4:11

























answered Jan 19 at 3:18









KaiidoKaiido

40.6k460100




40.6k460100













  • in ur first demo, the part of the map that is covered by the white is one image element, whereas the part that is not white is the other image correct? another caveat is that im going to be animating other elements around the edge of the "eye"/rectangle

    – Anthony
    Jan 19 at 3:39











  • What is white inside the <mask> is what will be kept as opaque in the masked element. What is black becomes transparent. So I first drew a full rect in black (its sizes are set in CSS), and your #rectangle in white. Then we apply this mask on the foreground image. But actually, using a gray rectangle as background, we could even do it all with a single <image>: jsfiddle.net/1gfx7jrL And for your animation thing, I'm not sure to get it, but you can add whatever you wish inside the mask: jsfiddle.net/1gfx7jrL/1

    – Kaiido
    Jan 19 at 4:05













  • i have yet to read over your comment in depth or word for word, but the reason i'm staying away from a mask and also using 2 images is because there will be icons displayed on one image (the image that is clipped) that i don't want to be visible on the white part of the image or outside of the "eye" window

    – Anthony
    Jan 20 at 23:15













  • well, it turns out my method wasn't even going to allow me to do what i wanted to do, therefore using a mask instead is most practical. however, i can't seem to get the additional image (you used an image of dice in your example) to also be the same level of transparency??? here is what i'm working with right now any idea what's going on here???

    – Anthony
    Jan 21 at 23:35











  • You need to see your mask as a standalone image, that will get applied to the target. There every black pixels will be removed on the target, while every white and transparent ones will stay untouched. So if you need an unified mask, you need to make this image unified. This should be done by changing your image so that what is currently black in there actually be the same gray as #background (#999), even if it is technically possible to apply a filter to do it, its a perf killer (on my FF, Chrome is good here).

    – Kaiido
    Jan 22 at 1:34





















  • in ur first demo, the part of the map that is covered by the white is one image element, whereas the part that is not white is the other image correct? another caveat is that im going to be animating other elements around the edge of the "eye"/rectangle

    – Anthony
    Jan 19 at 3:39











  • What is white inside the <mask> is what will be kept as opaque in the masked element. What is black becomes transparent. So I first drew a full rect in black (its sizes are set in CSS), and your #rectangle in white. Then we apply this mask on the foreground image. But actually, using a gray rectangle as background, we could even do it all with a single <image>: jsfiddle.net/1gfx7jrL And for your animation thing, I'm not sure to get it, but you can add whatever you wish inside the mask: jsfiddle.net/1gfx7jrL/1

    – Kaiido
    Jan 19 at 4:05













  • i have yet to read over your comment in depth or word for word, but the reason i'm staying away from a mask and also using 2 images is because there will be icons displayed on one image (the image that is clipped) that i don't want to be visible on the white part of the image or outside of the "eye" window

    – Anthony
    Jan 20 at 23:15













  • well, it turns out my method wasn't even going to allow me to do what i wanted to do, therefore using a mask instead is most practical. however, i can't seem to get the additional image (you used an image of dice in your example) to also be the same level of transparency??? here is what i'm working with right now any idea what's going on here???

    – Anthony
    Jan 21 at 23:35











  • You need to see your mask as a standalone image, that will get applied to the target. There every black pixels will be removed on the target, while every white and transparent ones will stay untouched. So if you need an unified mask, you need to make this image unified. This should be done by changing your image so that what is currently black in there actually be the same gray as #background (#999), even if it is technically possible to apply a filter to do it, its a perf killer (on my FF, Chrome is good here).

    – Kaiido
    Jan 22 at 1:34



















in ur first demo, the part of the map that is covered by the white is one image element, whereas the part that is not white is the other image correct? another caveat is that im going to be animating other elements around the edge of the "eye"/rectangle

– Anthony
Jan 19 at 3:39





in ur first demo, the part of the map that is covered by the white is one image element, whereas the part that is not white is the other image correct? another caveat is that im going to be animating other elements around the edge of the "eye"/rectangle

– Anthony
Jan 19 at 3:39













What is white inside the <mask> is what will be kept as opaque in the masked element. What is black becomes transparent. So I first drew a full rect in black (its sizes are set in CSS), and your #rectangle in white. Then we apply this mask on the foreground image. But actually, using a gray rectangle as background, we could even do it all with a single <image>: jsfiddle.net/1gfx7jrL And for your animation thing, I'm not sure to get it, but you can add whatever you wish inside the mask: jsfiddle.net/1gfx7jrL/1

– Kaiido
Jan 19 at 4:05







What is white inside the <mask> is what will be kept as opaque in the masked element. What is black becomes transparent. So I first drew a full rect in black (its sizes are set in CSS), and your #rectangle in white. Then we apply this mask on the foreground image. But actually, using a gray rectangle as background, we could even do it all with a single <image>: jsfiddle.net/1gfx7jrL And for your animation thing, I'm not sure to get it, but you can add whatever you wish inside the mask: jsfiddle.net/1gfx7jrL/1

– Kaiido
Jan 19 at 4:05















i have yet to read over your comment in depth or word for word, but the reason i'm staying away from a mask and also using 2 images is because there will be icons displayed on one image (the image that is clipped) that i don't want to be visible on the white part of the image or outside of the "eye" window

– Anthony
Jan 20 at 23:15







i have yet to read over your comment in depth or word for word, but the reason i'm staying away from a mask and also using 2 images is because there will be icons displayed on one image (the image that is clipped) that i don't want to be visible on the white part of the image or outside of the "eye" window

– Anthony
Jan 20 at 23:15















well, it turns out my method wasn't even going to allow me to do what i wanted to do, therefore using a mask instead is most practical. however, i can't seem to get the additional image (you used an image of dice in your example) to also be the same level of transparency??? here is what i'm working with right now any idea what's going on here???

– Anthony
Jan 21 at 23:35





well, it turns out my method wasn't even going to allow me to do what i wanted to do, therefore using a mask instead is most practical. however, i can't seem to get the additional image (you used an image of dice in your example) to also be the same level of transparency??? here is what i'm working with right now any idea what's going on here???

– Anthony
Jan 21 at 23:35













You need to see your mask as a standalone image, that will get applied to the target. There every black pixels will be removed on the target, while every white and transparent ones will stay untouched. So if you need an unified mask, you need to make this image unified. This should be done by changing your image so that what is currently black in there actually be the same gray as #background (#999), even if it is technically possible to apply a filter to do it, its a perf killer (on my FF, Chrome is good here).

– Kaiido
Jan 22 at 1:34







You need to see your mask as a standalone image, that will get applied to the target. There every black pixels will be removed on the target, while every white and transparent ones will stay untouched. So if you need an unified mask, you need to make this image unified. This should be done by changing your image so that what is currently black in there actually be the same gray as #background (#999), even if it is technically possible to apply a filter to do it, its a perf killer (on my FF, Chrome is good here).

– Kaiido
Jan 22 at 1:34




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54262829%2fsvg-gradient-like-canvas-gradient%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Liquibase includeAll doesn't find base path

How to use setInterval in EJS file?

Petrus Granier-Deferre