SVG masking another SVG issue

I'm stumped as to why I can't use one SVG to mask another. What am I doing wrong?

Screenshot with mask added to display list (the black square) to show position

Screenshot with the mask applied (not added to display list), but nothing is masked!

Here is the code where I expect the mask to be revealing only the small area with the "A" in it, but NOTHING is masked!

        const paths = [
            "assets/image/Objects/Scenario 3/AA__S3_receptorA_neutral.svg",
            "assets/image/Objects/General_Game-wide/bubble-test-3.svg"];
        const loader = F.loadAssets(paths);
        loader.on("complete", () => {
            const contentB = new Bitmap(F.asset(paths[0]));
            const bubbleB = new Bitmap(F.asset(paths[1]));

            bubbleB.x = 100;
            bubbleB.y = 100;

            contentB.mask = bubbleB;
            S.addChild(contentB);

            // S.addChild(bubbleB); // THIS LINE SHOWS WHERE THE MASK SHOULD BE

            S.update();
        });

Where am I going wrong?

mask is createjs - it works in some cases but it tends to show up in the wrong place because location is not taken into account and it only works with Shape(). So we made setMask() which handles more situations and adjusts to accommodate position. It also can be set to be dynamic if things transform. It works on ZIM shapes such as Circle, Blob, Rectangle, etc. But it does not work with Bitmaps.

For bitmaps, you would need to set an alpha mask - and we have made that easier with AlphaEffect.

const tile = new Tile({
    obj:new Circle(10, purple), 
    cols:20, 
    rows:20,
    backgroundColor:pink
})
    .center()        
    .drag({all:true});

tile.effect(new AlphaEffect(new Pic("pragma.png")));
1 Like

Thanks Dr., it seems this is a bugaboo for me, I keep running into it and am always astonished. One thing I noticed is that setting x and y of the mask doesn't seem to have any effect, it always lines up the content and mask to their upper-left.

Yes, that is why we made setMask() and no longer use mask. Mask is based on the shape itself independent of its location - so it was always confusing.

So is it doing what you need now?

Sort of - the AlphaEffect is putting the mask in the upper-left, and changing the mask's location doesn't seem to have an effect:

        const paths = [
            "assets/image/Objects/Scenario 3/AA__S3_receptorA_neutral.svg",
            "assets/image/Objects/General_Game-wide/bubble-test-3.svg"];
        const loader = F.loadAssets(paths);
        loader.on("complete", () => {
            const contentB = new Bitmap(F.asset(paths[0]));
            const bubbleB = new Bitmap(F.asset(paths[1]));

            contentB.effect(new AlphaEffect(bubbleB));
            S.addChild(contentB);
            S.update();

            setTimeout(() => {
                // CHANGING LOCATION SEEMS TO HAVE NO EFFECT
                bubbleB.x += 50;
                bubbleB.y += 50;

                // ADDING THIS LINE THROWS AN "Uncaught" ERROR IN createjs
                // contentB.updateEffects(true);
                S.update();
            }, 1000);
        });

How to?

There are some notes in the Docs for AlphaEffect about making a container the same size, so it seems that the effect has a similar issue as the original CreateJS mask. See if this example helps:

Sorry - would spend a bit more time on it but need to go to bed - we have an open house in the morning.

Ya, sorry to have made you repeat yourself - I saw that code sample in your prior answer. It's a bit too involved and, having not done a lot of it, too finicky to work out at the moment. Instead, since the masks are just simple SVG paths, I'm translating them to Shapes and using that along with setMask. I'll dig into it further after this project. Thanks for your ever responsive help!

1 Like

Is it possible to get the text source of the SVG from when using loadAssets? Probably not the solution, but I tried {src: "...", type: "text"} and that takes FOREVER to load. If I can read the text of the SVG after the normal loadAssets (which is fast) then I can run my SVG-to-Shape translator.

the SVG object gets an svg property so you can use that probably...