Pixi.js 如何用另一张图片遮盖一张图片

Pixi.js how to mask one image with other image

抱歉这个业余问题,我是 Pixi.js

的新手

嗯,我正在尝试制作刮刮卡。

将有两张图片,一张用于背景(“A”),一张用于隐藏背景(“B”,我认为这是遮罩,但我不确定这个术语,以免混淆我将描述为隐藏背景)

因此,图片 'A' 将覆盖图片 'B'。

然后,我将使用毛刷图像。

当我在图像“A”上执行拖动事件时,我想沿着鼠标移动的路径显示图像“B”。

抱歉,我的描述很糟糕。我想我正在克隆这个网站 ( https://art4globalgoals.com/en )

我照着这个例子(https://pixijs.io/examples/#/demos-advanced/scratchcard.js)做了一个画笔效果,只有一张图。但是无法用两个图像实现它。

准确地说,当我运行我的应用程序时,呈现黑屏,如果我刮擦屏幕,隐藏的图像就会出现。 但问题是,我想设置其他图像而不是黑屏。

下图是我的当前状态,运行宁下面的代码时会发生

import * as PIXI from 'pixi.js';

// const canvas = document.getElementById('webgl');

const screenSize = {
    width: window.innerWidth,
    height: window.innerHeight
};
let brushWidth = (window.innerHeight / window.innerWidth) * 200;
let brushHeight = (window.innerHeight / window.innerWidth) * 200;

// canvas.width = screenSize.width;
// canvas.height = screenSize.height;
const app = new PIXI.Application({
    width: window.innerWidth,
    height: window.innerHeight,
    resolution: window.devicePixelRatio,
    autoDensity: true
});

document.body.appendChild(app.view);

app.loader
    .add('background', '/png/effel.png')
    .add('mask', '/png/effel-gray.png')
    .add('bristle1', '/png/brush6.png')
    .add('bristle2', '/png/bristle2.png')
    .load(() => {
        setup();
    });

const setup = () => {
    const brushTexture = app.loader.resources.bristle1.texture;
    const brushTexture2 = app.loader.resources.bristle2.texture;

    const brush = new PIXI.Sprite(brushTexture);
    const brush2 = new PIXI.Sprite(brushTexture2);

    brush.width = brushWidth;
    brush.height = brushHeight;

    brush2.width = brushWidth;
    brush2.height = brushHeight;

    const backgroundTexture = app.loader.resources.background.texture;
    const maskTexture = app.loader.resources.mask.texture;
    const background = new PIXI.Sprite(backgroundTexture);
    background.x = app.renderer.screen.width / 2;
    background.y = app.renderer.screen.height / 2;
    background.anchor.x = 0.5;
    background.anchor.y = 0.5;
    background.width = window.innerWidth;
    background.height = window.innerHeight;

    const Mask = new PIXI.Sprite(maskTexture);
    Mask.width = app.renderer.screen.width;
    Mask.height = app.renderer.screen.height;
    Mask.x = app.renderer.screen.width / 2;
    Mask.y = app.renderer.screen.height / 2;
    Mask.anchor.x = 0.5;
    Mask.anchor.y = 0.5;
    Mask.width = window.innerWidth;
    Mask.height = window.innerHeight;

    // app.stage.addChild(background);
    app.stage.addChild(Mask);

    const renderTexture = PIXI.RenderTexture.create(app.screen.width, app.screen.height);

    const renderTextureSprite = new PIXI.Sprite(renderTexture);

    app.stage.addChild(renderTextureSprite);

    Mask.mask = renderTextureSprite;

    app.stage.interactive = true;
    app.stage.on('pointerdown', pointerDown);
    app.stage.on('pointerup', pointerUp);
    app.stage.on('pointermove', pointerMove);

    let dragging = false;
    let bristle2Render = false;

    function pointerMove(event) {
        if (dragging) {
            brush.position.copyFrom(event.data.global);
            // brushWidth += 0.5;
            // brush.width = brushWidth;

            if (!bristle2Render) {
                setTimeout(() => (bristle2Render = true), 500);
            }

            app.renderer.render(brush, renderTexture, false, null, false);
            if (bristle2Render) {
                brush2.position.copyFrom(event.data.global);
                app.renderer.render(brush2, renderTexture, false, null, false);
            }

            // if (brush.width === 100) {
            //  dragging = false;
            //  brushWidth = 0;
            // }
        }
    }

    function pointerDown(event) {
        dragging = true;
        console.log(11);
        pointerMove(event);
    }

    function pointerUp(event) {
        dragging = false;
        bristle2Render = false;
    }

    window.addEventListener('resize', () => {
        screenSize.width = window.innerWidth;
        screenSize.height = window.innerHeight;

        app.renderer.resize(window.innerWidth, window.innerHeight);
        app.renderer.stage.width = window.innerWidth;
        app.renderer.stage.height = window.innerHeight;
    });
};
// const backgroundTexture = PIXI.Texture.from('/png/effel.png');
// const maskTexture = PIXI.Texture.from('/png/effel-gray.png');

我想问题是你还没有将 background 添加到舞台,因为你评论了它。

    // app.stage.addChild(background);
    app.stage.addChild(Mask);

所以,一开始没有什么可显示的,所以是黑屏。

这是我创建的 CodePen。我删除了一些评论并用其他图片替换了资源。在您取消注释该行后,它应该可以正常工作。


顺便说一下,您可能需要确保:

  • 出于某些特殊原因(例如Mask
  • ,您的变量的名称仅
  • 您不会覆盖之前设置的值(例如 Mask.width = ...)。

虽然代码在不修复上述问题的情况下仍然有效,但这可能会使代码更难用于其他人,包括未来的“你”。 ;)

当您的代码运行时,您可能希望 post 在 Code Review 上查看如何改进代码。