SVG Gradient like Canvas Gradient?
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.
javascript svg canvas gradient mask
add a comment |
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.
javascript svg canvas gradient mask
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
add a comment |
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.
javascript svg canvas gradient mask
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.
javascript svg canvas gradient mask
javascript svg canvas gradient mask
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
add a comment |
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
add a comment |
1 Answer
1
active
oldest
votes
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.
in ur first demo, the part of the map that is covered by the white is oneimage
element, whereas the part that is not white is the otherimage
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
|
show 3 more comments
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
in ur first demo, the part of the map that is covered by the white is oneimage
element, whereas the part that is not white is the otherimage
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
|
show 3 more comments
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.
in ur first demo, the part of the map that is covered by the white is oneimage
element, whereas the part that is not white is the otherimage
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
|
show 3 more comments
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.
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>
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 oneimage
element, whereas the part that is not white is the otherimage
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
|
show 3 more comments
in ur first demo, the part of the map that is covered by the white is oneimage
element, whereas the part that is not white is the otherimage
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
|
show 3 more comments
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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