简体   繁体   中英

Masking a canvas with semi-transparent png

I'd like to make a web app where the user can, when hovering a canvas with a black and white image, reveal the colors.

My first try was to set a css background image on the canvas with the bw image, and reveal the colored image with a drawn circle in the canvas. In this way the circle have solid edges, but what I want is a circle with faded edges. Is there a way to reveal the colored image with a semi-tansparent png instead of a solid canvas circle?

Hopefully this image will explaine more how I want things to work.

I know this is not a direct answer to the question, but have you thought about switching from canvas to svg. svg has some nice filter mechanics build into it. Current chrome and firefox versions support it. IE10 will too.

Here is an example page:

http://ie.microsoft.com/testdrive/Graphics/hands-on-css3/hands-on_svg-filter-effects.htm

Started a little project with the processing.js framework. Still going to need lots of work. But maybe, it points you into the right direction:

EDIT: Some additional edits in the code

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <script type="text/javascript" src="processing-1.3.6.js"></script>
    </head>
    <body style="background-color:blue">
        <div id="container" style="background-image: url('testgrey.jpg');overflow:hidden;background-clip:content-box;width: 400px;height: 400px" >
            <canvas id="test" width="400" height="400"></canvas>
        </div>
        <script type="text/processing" data-processing-target="test">

        /* @pjs preload="test.jpg"; */
        /* @pjs transparent=true; */
        int nX, nY;
        int radius = 40;
        double powRadius = Math.pow(radius,2);

        void setup()
        {
        size(400,400);
        frameRate( 25 );
        background(0,0,0,0);
        a = loadImage("test.jpg");
        }

        void draw(){ 

        int left = nX - radius;
        int right = left + radius * 2;
        int top = nY - radius;
        int bottom = top + radius * 2;
        for (int j = top; j <= bottom; ++j)
        {
        for (int k = left; k <= right; ++k)
        {
        double dist = Math.pow(nX - k, 2.0) + Math.pow(nY - j, 2.0);
        if (dist <= powRadius)
        {
        color original= a.get(k,j);
        int newAlpha = 255-dist / powRadius*255;
        if(alpha(get(k,j))<newAlpha){
        color toDraw = color(red(original),green(original),blue(original),newAlpha);
        set(k,j,toDraw);
        }
        }
        }
        }

        }

        void mouseMoved(){
        nX = mouseX;
        nY = mouseY;  
        }
        </script>
    </body>
</html>

You need two images to excute this: test.jpg and testgrey.jpg.

You can try composite operations of graphics context

http://www.html5canvastutorials.com/advanced/html5-canvas-global-composite-operations-tutorial/

demo : http://jsfiddle.net/HdyBG/7/

And using the function createRadialGradient you can create gradient fills.

demo: http://jsfiddle.net/AuQTD/7/

I hope you can achieve what you need by combining these two.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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