I would love to code simple image painting in HTML, CSS and probably jQuery also.
Let\'s say I have a original image, and I want make it colorized but only in part of ho
You could do this using svg
's mask
and filter
.
CodePen
var img = document.getElementById('img');
img.addEventListener('mousemove', function(e) {
document.getElementById('c').setAttribute('cx', e.clientX - img.getBoundingClientRect().left);
document.getElementById('c').setAttribute('cy', e.clientY - img.getBoundingClientRect().top);
})
<svg id="img" width="600" height="300" viewBox="0 0 600 300">
<defs>
<filter id="f" filterUnits="userSpaceOnUse">
<feColorMatrix type="saturate" values="0" />
</filter>
<mask id="m" maskUnits="userSpaceOnUse" x="0" y="0" width="600" height="300">
<circle id="c" cx="-40" cy="-40" r="40" fill="white" />
</mask>
</defs>
<image filter="url(#f)" width="600" height="300" xlink:href="http://www.lorempixel.com/600/300" />
<image mask="url(#m)" width="600" height="300" xlink:href="http://www.lorempixel.com/600/300" />
</svg>
You could also get a smooth transition on the circle edges by using radialGradient
.
CodePen
var img = document.getElementById('img');
img.addEventListener('mousemove', function(e) {
var x = e.clientX - img.getBoundingClientRect().left;
var y = e.clientY - img.getBoundingClientRect().top;
document.getElementById('r').setAttribute('fx', x);
document.getElementById('r').setAttribute('fy', y);
document.getElementById('r').setAttribute('cx', x);
document.getElementById('r').setAttribute('cy', y);
});
<svg id="img" width="600" height="300" viewBox="0 0 600 300">
<defs>
<radialGradient id="r" gradientUnits="userSpaceOnUse" cx="300" cy="150" r="400" fx="300" fy="150">
<stop offset="0%" stop-color="white" />
<stop offset="10%" stop-color="white" />
<stop offset="12%" stop-color="black" />
<stop offset="100%" stop-color="black" />
</radialGradient>
<filter id="f" filterUnits="userSpaceOnUse">
<feColorMatrix type="saturate" values="0" />
</filter>
<mask id="m" maskUnits="userSpaceOnUse" x="0" y="0" width="600" height="300">
<path d="M0,0 h600 v300 h-600z" fill="url(#r)" />
</mask>
</defs>
<image filter="url(#f)" width="600" height="300" xlink:href="http://www.lorempixel.com/600/300" />
<image mask="url(#m)" width="600" height="300" xlink:href="http://www.lorempixel.com/600/300" />
</svg>
Base on this, i have solution for your problem:
Use mark to overlay image
<div class="container">`
<div class="bg-image"></div>
<div class="highlight-region"></div>
</div>
Grayscale on mark instead of image's container
.container .bg-image {
opacity:0.3;
-moz-filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#grayscale");
-o-filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#grayscale");
-webkit-filter: grayscale(100%);
filter: gray;
filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#grayscale");
height:455px;
width:606px;
}
set opacity = 0 on highlight-region
.container div.highlight-region {
height:150px;
width:150px;
border-radius: 50%;
opacity:0;
}
Demo can see here: http://jsfiddle.net/MT4T7/438/
I suggest avoiding CSS filters, as it is not supported in IE at all, and doesn't look like it is in the pipeline either.
I also would prefer to greyscale my images in photoshop, to have more control over the color balance and contrast. (But I'm a designer as well).
Instead, I'm going to layer a full color image over a grayscale image, fix the position of the colorful background image, and move the position of the top div with jQuery:
<div class="greykitty">
<div class="colorfulkitty" style="top: 150px; left: 280px;">
</div>
</div>
body{
background-color:whitesmoke;
}
div{
height: 400px;
width: 600px;
background-repeat: no-repeat;
}
.greykitty{
background-image: url("http://lorempixel.com/g/600/400/cats/10/");
}
.colorfulkitty{
background-image: url("http://lorempixel.com/600/400/cats/10/");
$circlesize: 150px;
height: $circlesize;
width: $circlesize;
border-radius: $circlesize;
background-attachment: fixed;
position: absolute;
}
$('.greykitty').mousemove(function (colorize) {
var X = colorize.clientX;
var Y = colorize.clientY;
$('.colorfulkitty').css("top", (Y - 75) + 'px');
$('.colorfulkitty').css("left", (X - 75) + 'px');
});
And my codepen: http://codepen.io/fontophilic/pen/XJpVje/
You can wrap you image in a HTML Element and add a div element element with box-shadow
$("figure").on('mousemove', function(e){
$('.shadow').css({
left: e.pageX - $(this).offset().left - 40,
top: e.pageY - $(this).offset().top -40
});
});
figure{
position: relative;
margin: 20px auto;
width: 480px;
height: 480px;
overflow: hidden
}
figure:hover .shadow{
opacity: 1
}
img{
width: 100%
}
.shadow{
position: absolute;
left: 80px;
top: 60px;
z-index: 1;
background: transparent;
width: 100px;
height: 100px;
opacity: 0;
transition: opacity .3s ease;
border-radius: 50%;
box-shadow: 0 0 0 60em rgba(0,0,0,.5)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<figure>
<img src=http://i.imgur.com/orn8Dgf.jpg />
<div class=shadow></div>
</figure>