From 66478b4fbeb6b58123862f4694e7f3f09fb8228d Mon Sep 17 00:00:00 2001 From: Misode Date: Fri, 7 Aug 2020 01:59:30 +0200 Subject: [PATCH] Make visualizer draggable --- src/app/visualization/BiomeNoiseVisualizer.ts | 18 +++++++++++-- src/app/visualization/VisualizerView.ts | 26 ++++++++++++++++--- src/styles/global.css | 1 + 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/app/visualization/BiomeNoiseVisualizer.ts b/src/app/visualization/BiomeNoiseVisualizer.ts index ce092ca3..96e644a2 100644 --- a/src/app/visualization/BiomeNoiseVisualizer.ts +++ b/src/app/visualization/BiomeNoiseVisualizer.ts @@ -7,6 +7,8 @@ export class BiomeNoiseVisualizer implements Visualizer { static readonly noiseMaps = ['altitude', 'temperature', 'humidity', 'weirdness'] private noise: SimplexNoise[] private biomeSource: any + private offsetX: number = 0 + private offsetY: number = 0 constructor() { this.noise = BiomeNoiseVisualizer.noiseMaps.map(e => new SimplexNoise()) @@ -22,8 +24,13 @@ export class BiomeNoiseVisualizer implements Visualizer { && model.get(biomeSource.push('type')) === 'minecraft:multi_noise' } + dirty(model: DataModel) { + return JSON.stringify(this.biomeSource) + !== JSON.stringify(model.get(new Path(['generator', 'biome_source']))) + } + draw(model: DataModel, img: ImageData) { - this.biomeSource = model.get(new Path(['generator', 'biome_source'])) + this.biomeSource = JSON.parse(JSON.stringify(model.get(new Path(['generator', 'biome_source'])))) const data = img.data for (let x = 0; x < 200; x += 1) { for (let y = 0; y < 100; y += 1) { @@ -38,6 +45,12 @@ export class BiomeNoiseVisualizer implements Visualizer { } } + onDrag(from: number[], to: number[]) { + this.offsetX += (to[0] - from[0]) / 128 + this.offsetY += (to[1] - from[1]) / 128 + this.biomeSource = {} + } + private closestBiome(x: number, y: number): string { const noise = this.getNoise(x, y) if (!this.biomeSource.biomes) return '' @@ -65,7 +78,8 @@ export class BiomeNoiseVisualizer implements Visualizer { let n = 0 let scale = 2**config.firstOctave for (let i = 0; i < config.amplitudes.length; i++) { - n += this.noise[index].noise2D(x*scale, y*scale + i) * config.amplitudes[i] * 128 / scale + n += this.noise[index].noise2D(x*scale - this.offsetX, y*scale + i - this.offsetY) + * config.amplitudes[i] * 128 / scale scale *= 2 } return n diff --git a/src/app/visualization/VisualizerView.ts b/src/app/visualization/VisualizerView.ts index 2f314a41..b8658119 100644 --- a/src/app/visualization/VisualizerView.ts +++ b/src/app/visualization/VisualizerView.ts @@ -4,7 +4,9 @@ import { BiomeNoiseVisualizer } from "./BiomeNoiseVisualizer"; export interface Visualizer { path(): Path active(model: DataModel): boolean + dirty(model: DataModel): boolean draw(model: DataModel, img: ImageData): void + onDrag?(from: number[], to: number[]): void } export class VisualizerView extends AbstractView { @@ -15,6 +17,7 @@ export class VisualizerView extends AbstractView { sourceView: HTMLElement gutter: HTMLElement lastHeight?: string + dragStart?: number[] constructor(model: DataModel, canvas: HTMLCanvasElement) { super(model) @@ -23,13 +26,30 @@ export class VisualizerView extends AbstractView { this.canvas = canvas this.gutter = canvas.parentElement!.querySelector('.gutter') as HTMLElement this.sourceView = canvas.parentElement!.getElementsByTagName('textarea')[0] as HTMLElement + + canvas.addEventListener('mousedown', evt => { + this.dragStart = [evt.offsetX, evt.offsetY] + }) + canvas.addEventListener('mousemove', evt => { + if (this.dragStart === undefined) return + if (this.visualizer?.onDrag) { + this.visualizer.onDrag(this.dragStart, [evt.offsetX, evt.offsetY]) + } + this.dragStart = [evt.offsetX, evt.offsetY] + this.invalidated() + }) + canvas.addEventListener('mouseup', evt => { + this.dragStart = undefined + }) } invalidated() { if (this.active && this.visualizer && this.visualizer.active(this.model)) { - const img = this.ctx.createImageData(200, 100) - this.visualizer.draw(this.model, img) - this.ctx.putImageData(img, 0, 0) + if (this.visualizer.dirty(this.model)) { + const img = this.ctx.createImageData(200, 100) + this.visualizer.draw(this.model, img) + this.ctx.putImageData(img, 0, 0) + } this.canvas.style.display = 'block' this.gutter.style.display = 'block' if (this.lastHeight) { diff --git a/src/styles/global.css b/src/styles/global.css index 1a07aac3..e11f1562 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -244,6 +244,7 @@ body { /* bottom: 0; */ background-color: var(--nav-faded); display: block; + cursor: grab; image-rendering: optimizeSpeed; image-rendering: -moz-crisp-edges; image-rendering: -webkit-optimize-contrast;