admin管理员组

文章数量:1386713

Basically, I want to make an empty div that I can put anywhere on the page, and it will invert the colors of everything behind it. Is this possible? (It shouldn't invert entire elements that are overlapped, only the part covered by the div)

Basically, I want to make an empty div that I can put anywhere on the page, and it will invert the colors of everything behind it. Is this possible? (It shouldn't invert entire elements that are overlapped, only the part covered by the div)

Share Improve this question asked Feb 29, 2016 at 20:53 flyingfischflyingfisch 5291 gold badge6 silver badges19 bronze badges 7
  • not with a div, but you could do it with a canvas element if the html is relatively simple. – I wrestled a bear once. Commented Feb 29, 2016 at 20:57
  • @Pamblam ah, I actually have a div over a canvas, and I need it to invert the canvas behind it. For various reasons I can't just do it in the canvas itself. If it's possible to do with another canvas element though, I might be able to do that. – flyingfisch Commented Feb 29, 2016 at 21:01
  • you could. you'll have to check out the mdn page that explains how to draw html onto canvas, then you have to google to figure out how to loop through the pixels of the canvas and reverse the color of each pixel. sorry that's way too much to write an example for. – I wrestled a bear once. Commented Feb 29, 2016 at 21:06
  • @Pamblam k I'll take a look. Thanks – flyingfisch Commented Feb 29, 2016 at 21:07
  • 1 @dandavis that only applies to the contents of the div, it doesn't affect the canvas element behind it iirc. ;) – flyingfisch Commented Feb 29, 2016 at 21:56
 |  Show 2 more ments

4 Answers 4

Reset to default 4

You can implement it (or any other filter) using the backdrop-filter css property.

.overlay {
  /* The invert effect */
  -webkit-backdrop-filter: invert(100%);
  backdrop-filter: invert(100%);

  position: fixed;
  top: 50px;
  left: 50px;
  width: 100px;
  height: 50px;
  border: solid 1px blue;
  transition: all 0.3s ease;
}
.overlay:hover {
  left: 100px;
}
<div class="overlay"></div>

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dignissim elementum mattis. Pellentesque lacus velit, sollicitudin eget tincidunt et, dapibus a tortor. Vestibulum ultrices nisi ut turpis ultricies interdum. Proin pellentesque purus rutrum, pretium justo ac, scelerisque sem. Suspendisse potenti. Sed iaculis eu velit sed maximus. Phasellus vestibulum in tellus sit amet euismod. Donec id faucibus lectus. Aenean eu pretium risus, ut pharetra odio. Ut hendrerit molestie hendrerit. Morbi consectetur ultricies elit ut convallis. Quisque cursus odio id lacinia ultrices. Nulla eu ligula et mauris laoreet cursus sed nec orci. Donec eu vulputate leo, id scelerisque quam. Aenean dignissim placerat pharetra.</p>
<p>Vestibulum ac fringilla ipsum. Vivamus venenatis non sem sed hendrerit. Etiam mollis libero lorem. Nullam pharetra nulla vitae libero porttitor sollicitudin. Maecenas non sapien a tellus rutrum pellentesque ac non nisi. Aenean rhoncus et arcu ac suscipit. Mauris in nunc quis dolor aliquet pharetra. Nulla mi arcu, mollis ac ligula vel, vestibulum pretium massa. Quisque malesuada justo eu imperdiet lobortis. Mauris elit arcu, feugiat id vulputate quis, efficitur ut neque. In dignissim dignissim euismod. Suspendisse ac arcu ipsum. Cras dignissim justo risus, et blandit ligula egestas eu. Nunc massa purus, hendrerit quis lacinia non, luctus at erat.</p>

Unfortunately this CSS property is not widely supported by browsers.

The easiest way is to use CSS3 property mix-blend-mode. It's just one line of code!

.invert-everything-behind {
  mix-blend-mode: exclusion;
}

See: https://css-tricks./almanac/properties/m/mix-blend-mode/

Maybe this is what you need: example

function start() {
    var canvas1 = document.getElementById("canvas");
    var ctx1 = canvas1.getContext("2d");
    var canvas2 = document.getElementById("over");
    var ctx2 = canvas2.getContext("2d");

    // Just put a colorfull random background to play with.
    randomFill( ctx1 );

    // Animation of the lens.
    var x = Math.random() * 100;
    var y = Math.random() * 100;
    var speed = .02;
    var vx = .03 + Math.random() * speed;
    var vy = .03 + Math.random() * speed;
    var lastTime = 0;

    function anim( time ) {
        window.requestAnimationFrame( anim );
        if (lastTime == 0) {
            lastTime = time;
        } else {
            var delay = time - lastTime;
            lastTime = time;
            x += delay * vx;
            y += delay * vy;
            if (x < 0) {
                x = 0;
                vx = -vx;
            }
            else if (x > 299) {
                x = 299;
                vx = -vx;
            }
            if (y < 0) {
                y = 0;
                vy = -vy;
            }
            else if (y > 299) {
                y = 299;
                vy = -vy;
            }
            canvas2.style.top = Math.floor(y) + "px";
            canvas2.style.left = Math.floor(x) + "px";
        }
        applyFilter( ctx1, ctx2, x, y );
    }
    window.requestAnimationFrame( anim );
}

function randomFill( ctx ) {
    var i, x, y, w, h;
    for (i = 0 ; i < 1000 ; i++) {
        x = Math.floor( Math.random() * 400 ) - 50;
        y = Math.floor( Math.random() * 400 ) - 50;
        w = Math.floor( Math.random() * 100 );
        h = Math.floor( Math.random() * 100 );
        ctx.fillStyle = 'rgb(' + Math.floor(Math.random()*256) + ","
            + Math.floor(Math.random()*256) + "," + Math.floor(Math.random()*256) + ')';
        ctx.fillRect( x, y, w, h );
    }
}

function applyFilter( ctx1, ctx2, x, y ) {
    var w = 100, h = 100;
    var img = ctx1.getImageData(x, y, w, h);
    var pixels = img.data;
    var k;
    for (k = 0 ; k < pixels.length ; k += 4) {
        pixels[k + 0] = 255 - pixels[k + 0];
        pixels[k + 1] = 255 - pixels[k + 1];
        pixels[k + 2] = 255 - pixels[k + 2];
    }
    ctx2.putImageData(img, 0, 0);
}

Take attention to the applyFilter function.

Or in straight SVG, you can invert the spectrum of a filtered area just using feComponentTransfer as in http://cs.sru.edu/~svg/Chapter05/G05xx16.svg

本文标签: htmlInvert colors on underlying elements with CSSjavascriptor SVGStack Overflow