Last active
August 21, 2023 09:53
-
-
Save noih/21a58792cbc3477fa751c47a92aa59b7 to your computer and use it in GitHub Desktop.
PixiJS - Prevent text flickering caused by scaling
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* PixiJS v7 - Prevent text flickering caused by scaling | |
* | |
* @version 1 | |
* @author noih.dev | |
* @since 2023-08-21 | |
* @link https://gist.github.com/noih/21a58792cbc3477fa751c47a92aa59b7 | |
* @link https://codesandbox.io/s/render-text-rpvksn?file=/src/index.mjs:0-2349 | |
*/ | |
import * as PIXI from 'pixi.js' | |
import { Viewport } from 'pixi-viewport' | |
import debounce from 'lodash.debounce' | |
import { Random } from 'random-js' | |
import Stats from 'stats.js' | |
const TextCount = 2000 | |
const texts = [] | |
const app = new PIXI.Application({ | |
width: window.innerWidth, | |
height: window.innerHeight, | |
antialias: true, | |
autoDensity: true, | |
autoStart: false, | |
resolution: window.devicePixelRatio || 1, | |
backgroundColor: '0x383838', | |
resizeTo: window | |
}) | |
document.body.appendChild(app.view) | |
app.ticker.stop() | |
const viewport = new Viewport({ | |
screenWidth: window.innerWidth, | |
screenHeight: window.innerHeight, | |
worldWidth: 5000, | |
worldHeight: 5000, | |
divWheel: app.view, | |
ticker: app.ticker, | |
passiveWheel: false, | |
noTicker: true, | |
events: app.renderer.events | |
}) | |
const container = new PIXI.Container() | |
const rnd = new Random() | |
const style = new PIXI.TextStyle({ | |
fontSize: 14, | |
fill: 0xff0000, | |
lineJoin: 'round', | |
stroke: '#000000', | |
// fontWeight: 'bold', | |
// strokeThickness: 1 | |
}) | |
for (let i = 0; i < TextCount; i += 1) { | |
const t = new PIXI.Text(`測試測試測試\n測試測試\n${rnd.string(8)}`, style) | |
t.texture.baseTexture.scaleMode = PIXI.SCALE_MODES.NEAREST | |
t.cullable = true | |
t.position.set((i % 40) * (t.width + 5), ~~(i / 40) * (t.height + 5)) | |
texts.push(t) | |
container.addChild(t) | |
} | |
viewport.addChild(container) | |
app.stage.addChild(viewport) | |
viewport | |
.drag() | |
.wheel({ smooth: false, interrupt: true }) | |
const onZoomedEnd = debounce( | |
() => { | |
console.log('scaled', viewport.scaled) | |
for (let i = 0; i < texts.length; i += 1) { | |
texts[i].scale.set(1 / viewport.scaled) | |
texts[i].style.fontSize = 14 * viewport.scaled | |
} | |
}, | |
700, | |
{ | |
leading: false, | |
trailing: true | |
} | |
) | |
viewport.on('zoomed-end', onZoomedEnd) | |
// fps | |
const stats = new Stats() | |
stats.showPanel(0) | |
document.body.appendChild(stats.dom) | |
let prev = performance.now() | |
const loop = () => { | |
const now = performance.now() | |
const elapsedMS = now - prev | |
prev = now | |
app.renderer.render(app.stage) | |
viewport.update(elapsedMS * (60 / 1000)) | |
stats.update() | |
requestAnimationFrame(loop) | |
} | |
requestAnimationFrame(loop) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment