简体   繁体   English

使用CSS,Javascript或SVG反转基础元素上的颜色

[英]Invert colors on underlying elements with CSS, Javascript, or SVG

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. 基本上,我想创建一个空的div,可以将其放置在页面上的任何位置,并且它将反转其后面所有内容的颜色。 Is this possible? 这可能吗? (It shouldn't invert entire elements that are overlapped, only the part covered by the div) (它不应反转重叠的整个元素,而仅反转div覆盖的部分)

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. 注意applyFilter函数。

或在直接SVG中,您可以像http://cs.sru.edu/~svg/Chapter05/G05xx16.svg中那样使用feComponentTransfer来对滤波后的区域的光谱进行反转。

You can implement it (or any other filter ) using the backdrop-filter css property. 您可以使用backdrop-filter css属性来实现它(或任何其他过滤器 )。

 .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. 不幸的是,浏览器并未广泛支持此CSS属性。

The easiest way is to use CSS3 property mix-blend-mode . 最简单的方法是使用CSS3属性mix-blend-mode It's just one line of code! 只需一行代码!

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM