JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.8.2/pixi.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.0.2/TweenMax.min.js"></script>
<canvas></canvas>
<p id="text">
What I expected: <br>
The red title should only be visible where the blue rectangle is. Instead, it also appears where the black square is.
</p>
<script id="shader" type="x-shader/x-fragment">
precision mediump float;
varying vec2 vTextureCoord;
uniform sampler2D uSampler;
uniform sampler2D maskTexture;
void main() {
vec4 texture = texture2D(uSampler, vTextureCoord);
vec4 mask = texture2D(maskTexture, vTextureCoord);
gl_FragColor = vec4(texture.r, texture.g, texture.b, (mask.a * texture.a));
}
</script>
CSS
canvas {
width: 100vw;
height: 100vh;
}
#text {
position: absolute;
right: 0;
bottom: 0;
left: 0;
padding: 20px;
}
JavaScript
const maskShader = document.getElementById('shader').textContent
var frontStage
var titleStage
var backStage
var renderTexture
var title
var BGrect
var movingMask
const APP = new PIXI.Application({
width : window.innerWidth,
height : window.innerHeight,
view : document.querySelector('canvas'),
resolution : window.devicePixelRatio,
transparent : true,
})
createStages()
createTitle()
createBackgroundRectangle()
createMovingMask()
APP.ticker.add(() => {
APP.renderer.render(maskStage, renderTexture, true, null, false)
})
function createStages() {
frontStage = new PIXI.Container()
titleStage = new PIXI.Container()
backStage = new PIXI.Container()
maskStage = new PIXI.Container()
frontStage.addChild(maskStage, titleStage)
APP.stage.addChild(backStage, frontStage)
renderTexture = PIXI.RenderTexture.create(APP.screen.width, APP.screen.height)
const alphaFilter = new PIXI.Filter(null, maskShader)
alphaFilter.resolution = window.devicePixelRatio
alphaFilter.uniforms.maskTexture = renderTexture
titleStage.filters = [alphaFilter]
titleStage.filterArea = APP.screen
}
function createTitle() {
title = new PIXI.Text('Hello World', { align: 'center', fontFamily: 'Arial', fontSize: 70, fill: 0xFF0000 })
title.x = Math.round((APP.screen.width / 2) - title.width / 2)
title.y = Math.round((APP.screen.height / 2) - title.height / 2)
titleStage.addChild(title)
}
function createBackgroundRectangle() {
BGrect = new PIXI.Graphics()
backStage.addChild(BGrect)
BGrect.beginFill(0x000000, 1)
BGrect.drawRect(0, 0, 100, 100)
BGrect.endFill()
BGrect.x = title.x
BGrect.y = title.y - 10
}
function createMovingMask() {
movingMask = new PIXI.Graphics()
maskStage.addChild(movingMask)
movingMask.beginFill(0x0000FF, 1)
movingMask.drawRect(0, 0, 50, 100)
movingMask.endFill()
movingMask.x = title.x + 100
movingMask.y = title.y - 10
const transX = title.width - 150
...