最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Is there any way to colorize only part of image on hover? - Stack Overflow

programmeradmin2浏览0评论

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 hover (or 10x10px square or circle of image where cursor is).

I applied some filters to make it grayscale with CSS, but I have no idea how to colorize only hover part (not whole picture).

Example image of best result (keeping colorized advice would be great, but not necessarily).

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 hover (or 10x10px square or circle of image where cursor is).

I applied some filters to make it grayscale with CSS, but I have no idea how to colorize only hover part (not whole picture).

Example image of best result (keeping colorized advice would be great, but not necessarily).

Share Improve this question edited Jan 23, 2015 at 14:39 Weafs.py 23k9 gold badges57 silver badges79 bronze badges asked Jan 9, 2015 at 16:01 user2997914user2997914 635 bronze badges 3
  • 2 Please include the code you have tried keep it simple to reproduce the issue. – DaniP Commented Jan 9, 2015 at 16:03
  • Stackexchange isn't really the best place to brainstorm ideas like this. It's more for troubleshooting what you've already attempted. Some issues I can identify for you: targeting where the cursor is, (.mousemove()) creating a mask for the colorized photo (background-clip), etc. – fontophilic Commented Jan 9, 2015 at 16:10
  • 9 You could possibly use this - but alter it to fit your needs jsfiddle/4WP2C/19 – Chris Commented Jan 9, 2015 at 16:10
Add a ment  | 

4 Answers 4

Reset to default 6

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./600/300" />
  <image mask="url(#m)" width="600" height="300" xlink:href="http://www.lorempixel./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./600/300" />
  <image mask="url(#m)" width="600" height="300" xlink:href="http://www.lorempixel./600/300" />
</svg>

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:

HTML

<div class="greykitty">
  <div class="colorfulkitty" style="top: 150px; left: 280px;">
  </div>
</div>

SCSS with normalize.css

body{
  background-color:whitesmoke;
}

div{
  height: 400px;
  width: 600px;
  background-repeat: no-repeat;
}


.greykitty{
  background-image: url("http://lorempixel./g/600/400/cats/10/");
}

.colorfulkitty{
    background-image: url("http://lorempixel./600/400/cats/10/");
  $circlesize: 150px;
  height:  $circlesize;
  width:  $circlesize;
  border-radius:   $circlesize;
  background-attachment: fixed;
  position: absolute;

}

JS with jQuery

$('.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./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<figure>
    <img src=http://i.imgur./orn8Dgf.jpg />
    <div  class=shadow></div>
</figure>

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/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/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/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/MT4T7/438/

发布评论

评论列表(0)

  1. 暂无评论