mirror of
https://github.com/misode/misode.github.io.git
synced 2026-04-26 00:16:51 +00:00
107 lines
3.3 KiB
TypeScript
107 lines
3.3 KiB
TypeScript
import { DataModel, Path, ModelPath } from "@mcschema/core"
|
|
import { Preview } from './Preview'
|
|
import { toggleMenu, View } from '../views/View'
|
|
import { Octicon } from '../components/Octicon'
|
|
import { NoiseChunkGenerator } from './NoiseChunkGenerator'
|
|
|
|
export class NoiseSettingsPreview extends Preview {
|
|
private width: number = 512
|
|
private depth: number = 0.1
|
|
private scale: number = 0.2
|
|
private offsetX: number = 0
|
|
private debug: boolean = false
|
|
|
|
getName() {
|
|
return 'noise-settings'
|
|
}
|
|
|
|
active(path: ModelPath) {
|
|
return path.endsWith(new Path(['noise']))
|
|
}
|
|
|
|
menu(view: View, redraw: () => void) {
|
|
return `<div class="panel-menu">
|
|
<div class="btn" data-id="${view.onClick(toggleMenu)}">
|
|
${Octicon.kebab_horizontal}
|
|
</div>
|
|
<div class="panel-menu-list btn-group">
|
|
<div class="btn input">
|
|
${Octicon.gear}
|
|
<label data-i18n="preview.depth"></label>
|
|
<input type="number" step="0.1" data-id="${view.register(el => {
|
|
(el as HTMLInputElement).value = this.depth.toString()
|
|
el.addEventListener('change', () => {
|
|
this.depth = parseFloat((el as HTMLInputElement).value)
|
|
redraw()
|
|
})
|
|
})}">
|
|
</div>
|
|
<div class="btn input">
|
|
${Octicon.gear}
|
|
<label data-i18n="preview.scale"></label>
|
|
<input type="number" step="0.1" data-id="${view.register(el => {
|
|
(el as HTMLInputElement).value = this.scale.toString()
|
|
el.addEventListener('change', () => {
|
|
this.scale = parseFloat((el as HTMLInputElement).value)
|
|
redraw()
|
|
})
|
|
})}">
|
|
</div>
|
|
<div class="btn input">
|
|
${Octicon.arrow_both}
|
|
<label data-i18n="preview.width"></label>
|
|
<input type="number" step="16" data-id="${view.register(el => {
|
|
(el as HTMLInputElement).value = this.width.toString()
|
|
el.addEventListener('change', () => {
|
|
this.width = parseFloat((el as HTMLInputElement).value)
|
|
redraw()
|
|
})
|
|
})}">
|
|
</div>
|
|
<div class="btn" data-id="${view.onClick(() => {this.debug = !this.debug; redraw()})}">
|
|
${Octicon.square}
|
|
<span data-i18n="preview.show_density"></span>
|
|
</div>
|
|
</div>
|
|
</div>`
|
|
}
|
|
|
|
getSize(): [number, number] {
|
|
return [this.width, this.state.height]
|
|
}
|
|
|
|
draw(model: DataModel, img: ImageData) {
|
|
const generator = new NoiseChunkGenerator(this.state, this.depth, this.scale)
|
|
|
|
const data = img.data
|
|
for (let x = 0; x < this.width; x += 1) {
|
|
const noise = generator.iterateNoiseColumn(x - this.offsetX).reverse()
|
|
for (let y = 0; y < this.state.height; y += 1) {
|
|
const i = (y * (img.width * 4)) + (x * 4)
|
|
const color = this.getColor(noise, y)
|
|
data[i] = (this.debug && noise[y] > 0) ? 255 : color
|
|
data[i + 1] = color
|
|
data[i + 2] = color
|
|
data[i + 3] = 255
|
|
}
|
|
}
|
|
}
|
|
|
|
onDrag(dx: number, dy: number) {
|
|
this.offsetX += dx
|
|
}
|
|
|
|
private getColor(noise: number[], y: number): number {
|
|
if (this.debug) {
|
|
return -noise[y] / 2 + 128
|
|
}
|
|
if (noise[y] > 0) {
|
|
return 0
|
|
}
|
|
if (noise[y+1] > 0) {
|
|
return 150
|
|
}
|
|
return 255
|
|
}
|
|
}
|