Is there any way to colorize only part of image on hover?

前端 未结 4 1818
情深已故
情深已故 2021-02-06 18:51

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

相关标签:
4条回答
  • 2021-02-06 19:09

    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

    enter image description here

    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>

    0 讨论(0)
  • 2021-02-06 19:09

    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/

    0 讨论(0)
  • 2021-02-06 19:14

    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.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;
    
    }
    

    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/

    0 讨论(0)
  • 2021-02-06 19:32

    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>

    0 讨论(0)
提交回复
热议问题