Как избежать обновления и мерцания при загрузке json с p5. js - PullRequest
2 голосов
/ 19 марта 2020

Я пытаюсь использовать p5. js для рендеринга 3d-куба на веб-странице, и мне нужно загрузить один постоянно обновляемый JSON файл, чтобы получить функции цвета. Файлы JSON будут обновляться в секунду, когда я запускаю сценарий python.

Проблема в том, что моя веб-страница результатов постоянно обновляется и иногда мерцает, а это не то, что я хотел. Как я могу настроить свой код так, чтобы визуальные элементы из JSON могли отображаться плавно, без каких-либо перерывов? Любая помощь будет оценена.

Вот мой код p5. js ниже:

var color_data
var urls = "http://127.0.0.1:5500/data.json";
let fr = 500

function setup() {
    createCanvas(windowWidth, windowHeight, WEBGL);
    setInterval(loadData, 100)
    frameRate(fr);
    easycam = createEasyCam();
    document.oncontextmenu = () => false;
    easycam.setDistance(800, 0);
}

function gotData(data) {
    color_data = data
}

function loadData() {
    loadJSON(urls, gotData)
}

function windowResized() {
    resizeCanvas(windowWidth, windowHeight)
}

function draw() {

    function colorPart(x_value, y_value, z_value) {
        let arr = color_data[5 - y_value][5 - z_value][x_value]
        return arr.split(',')
    }

    function forRange(fn) {
        const cubeSpacing = 100
        for (let i = -250; i <= 250; i += cubeSpacing) {
            fn(i);
        }
    }

    function coordToIndex(num) {
        return (num / 50 + 5) / 2
    }

    background(155);

    translate(0, 0, -500);

    rotateY(millis() / 2000);

    // let size = Math.random() % 10 *25
    // let volume = Math.random() % 1 + 1
    let volume = 1

    forRange(x => forRange(y => forRange(z => {
        let pos = createVector(x, y, z);
        noStroke()
        push();
        translate(volume * pos.x, volume * pos.y, volume * pos.z);
        let index_x = coordToIndex(x)
        let index_y = coordToIndex(y)
        let index_z = coordToIndex(z)
        if (color_data) {
            let tem_arr = colorPart(index_x, index_y, index_z)
            fill(parseInt(tem_arr[0]), parseInt(tem_arr[1]), parseInt(tem_arr[2]));
        }
        sphere(18)
        pop();
    })))

}

1 Ответ

1 голос
/ 19 марта 2020

Вот пример того, что я имел в виду в своем комментарии.

Я переместил большинство вычислений из графика, в настройках мы загружаем массив spheres с позициями и начальным цветом, а затем setInterval(changeColor, 500) меняет цвет, в данном случае это просто что-то случайное, но вы можете сделать то же самое с данными, поступающими с json, как вы делаете.

    colors = ["red", "blue", "green", "cyan", "white", "black", "yellow"]

    function setup() {
        spheres = []
        forRange(x => forRange(y => forRange(z => {
            color = "red"
            spheres.push({ x, y, z, color })
        })))

        createCanvas(windowWidth, windowHeight, WEBGL);
        frameRate(500);
        document.oncontextmenu = () => false;
        setInterval(changeColor, 500)
    }

    function changeColor() {
        spheres.forEach(obj => {
            obj.color = colors[int(random(colors.length))]
        })
    }

    function forRange(fn) {
        const cubeSpacing = 120
        for (let i = -250; i <= 250; i += cubeSpacing) {
            fn(i);
        }
    }

    function draw() {
        background(155);
        translate(0, 0, -500);
        rotateY(millis() / 2000);
        rotateX(millis() / 8000);

        spheres.forEach(obj => {
            noStroke()
            push();
            translate(obj.x, obj.y, obj.z);
            fill(obj.color)
            sphere(18)
            pop();
        })
    }

Вот что в действии: https://raw.githack.com/heldersepu/hs-scripts/master/HTML/p5_spheres.html без refre sh и без мерцания (по крайней мере, не в Google chrome, я только проверял там )

...