Skip to content

Instantly share code, notes, and snippets.

@noih
Last active August 21, 2023 09:53
Show Gist options
  • Save noih/21a58792cbc3477fa751c47a92aa59b7 to your computer and use it in GitHub Desktop.
Save noih/21a58792cbc3477fa751c47a92aa59b7 to your computer and use it in GitHub Desktop.
PixiJS - Prevent text flickering caused by scaling
/**
* 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