重画三个js元素

如何解决重画三个js元素

我用三个js看着this example来绘制带有图像的粒子,并且效果很好,但是我想在单击按钮(调用此功能)时使用开关来更改图像:

    const changeImg = function(num) {

    switch (num)
    {
        case 0:
            imgData ="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA....";
        break;

        case 1:
            imgData = "data:image/png;base64,iVBORw0KGgoAAAAN..."
        break;
    }

    img.src = imgData;

}

可以,但是当您单击多次时,网站变慢。

如何在不降低网站速度的情况下仅更新图像?

编辑1

我这样更改代码:

var renderer,scene,camera,ww,wh,particles,mw,mh,mz,numState;

numState = 0;

mz = 6; // Matrerial size

ww = document.getElementById('map-container').offsetWidth,wh = 450;

mw = ww * 2;
mh = wh * 2;

var centerVector = new THREE.Vector3(0,0);
var previousTime = 0
    speed = 10
    isMouseDown = false;

// Render
renderer = new THREE.WebGLRenderer({
    canvas: document.getElementById("map"),antialias: true
});

renderer.setSize(mw,mh);
renderer.setClearColor(0x12347C);

// Scence
scene = new THREE.Scene();

// Camera
camera = new THREE.OrthographicCamera( ww / - 2,ww / 2,wh / 2,wh / - 2,1,1000 );
camera.position.set(7,4);
camera.lookAt(centerVector);
scene.add(camera);
camera.zoom = 4;
camera.updateProjectionMatrix();

// Geometry
var geometry = new THREE.Geometry();
var material = new THREE.PointsMaterial({
    size: mz,color: 0xFFFFFF,sizeAttenuation: false
});

// Particle
particles = new THREE.Points();

var getImageData = function(image) {

    var canvas = document.createElement("canvas");
    canvas.width = image.width;
    canvas.height = image.height;

    var ctx = canvas.getContext("2d");
    ctx.drawImage(image,0);

    return ctx.getImageData(0,image.width,image.height);
}

var drawTheMap = function() {

    geometry.dispose();
    particles.material.dispose();
    particles.geometry.dispose();

    for (var y = 0,y2 = imagedata.height; y < y2; y += 2) {
        for (var x = 0,x2 = imagedata.width; x < x2; x += 2) {
            if (imagedata.data[(x * 4 + y * 4 * imagedata.width)] < 128) {

                var vertex = new THREE.Vector3();
                vertex.x = x - imagedata.width / 2;
                vertex.y = -y + imagedata.height / 2;
                vertex.z = -Math.random()*500;

                vertex.speed = Math.random() / speed + 0.015;

                geometry.vertices.push(vertex);
            }
        }
    }

    particles.material = material;
    particles.geometry = geometry;

    scene.add(particles);

    requestAnimationFrame(render);
};

var init = function() {

    imagedata = getImageData(image);
    drawTheMap();

    onResize();

    window.addEventListener('mousemove',onMousemove,false);
    window.addEventListener('mousedown',onMousedown,false);
    window.addEventListener('mouseup',onMouseup,false);
    window.addEventListener('resize',onResize,false);

};


var onResize = function(){

    var mov1,mov2;

    ww = document.getElementById('map-container').offsetWidth;
    wh = 450;
    
    if (window.innerWidth > 850) {
        mw = ww * 2;
        mh = wh * 2;
        mz = 6;

        mov1 = 2.2;
        mov2 = 1.9;

        particles.material.size = mz;
    } else {
        mw = ww;
        mh = wh;
        mz = 3;

        mov1 = 2;
        mov2 = 2;

        particles.material.size = mz;
    }

    renderer.setSize(mw,mh);
    camera.left    = ww / - mov1;
    camera.right   = ww / 2;
    camera.top     = wh / mov2;
    camera.bottom  = wh / - 2;
    camera.updateProjectionMatrix();
};

var onMouseup = function(){
    isMouseDown = false;
}
var onMousedown = function(e){
    isMouseDown = true;
    lastMousePos = {x:e.clientX,y:e.clientY};
};
var onMousemove = function(e){
    
    if(isMouseDown){
        camera.position.x += (e.clientX-lastMousePos.x)/100;
        camera.position.y -= (e.clientY-lastMousePos.y)/100;
        camera.lookAt(centerVector);
        lastMousePos = {x:e.clientX,y:e.clientY};
    }
};

var render = function(a) {

    requestAnimationFrame(render);

    particles.geometry.verticesNeedUpdate = true;
    if(!isMouseDown){
        camera.position.x += (0-camera.position.x)*0.06;
        camera.position.y += (0-camera.position.y)*0.06;
        camera.lookAt(centerVector);
    }

    renderer.render(scene,camera);
};

var imgData;
var image;
imgData ="data:image/png;base64,iVBORw0KGgoAAA...";

const changeState = function(state,num) {

    document.getElementById('dropbox-choose').innerHTML = state;
    numState = num;

    switch (numState)
    {
        case 0:
            imgData ="data:image/png;base64,iVBORw0KGgoAAA...";
        break;

        case 1:
            imgData = "data:image/png;base64,iVBORw0KGgoI..."
        break;
    }

    image.src = imgData;
}

image = document.createElement("img");
image.onload = init;
image.src = imgData;

THREE.WebGLRenderer仅应用一次,但是当我单击以更改图像时,它没有更新,而且我仍然遇到网站速度变慢的问题

这是我第一次使用三个js,我不知道我是否很好地应用了文档中的内容

编辑2

var renderer,numState;

numState = 0;

mz = 6;
ww = document.getElementById('map-container').offsetWidth,4);
camera.lookAt(centerVector);
scene.add(camera);
camera.zoom = 4;
camera.updateProjectionMatrix();

// Geometry
//var geometry = new THREE.Geometry();
var material = new THREE.PointsMaterial({
    size: mz,sizeAttenuation: false
});

// Particle
particles = new THREE.Points();
particles.material = material

scene.add(particles);

var getImageData = function(image) {

    var canvas = document.createElement("canvas");
    canvas.width = image.width;
    canvas.height = image.height;

    var ctx = canvas.getContext("2d");
    ctx.drawImage(image,image.height);
}

var drawTheMap = function() {

    let vertices = particles.geometry; // this acts as a REFERENCE!
    vertices.length = 0; // clears the vertices array


    for (var y = 0,x2 = imagedata.width; x < x2; x += 2) {
            if (imagedata.data[(x * 4 + y * 4 * imagedata.width)] < 128) {

                var vertex = new THREE.Vector3();
                vertex.x = x - imagedata.width / 2;
                vertex.y = -y + imagedata.height / 2;
                vertex.z = -Math.random()*500;

                vertex.speed = Math.random() / speed + 0.015;

                vertices.vertices.push(vertex);
            }
        }
    }

    particles.geometry.verticesNeedUpdate = true; // Inform three.js of the update

    requestAnimationFrame(render);
};

var init = function() {

    imagedata = getImageData(image);
    drawTheMap();

    onResize();

    window.addEventListener('mousemove',y:e.clientY};
};
var onMousemove = function(e){
    if(isMouseDown){
        camera.position.x += (e.clientX-lastMousePos.x)/100;
        camera.position.y -= (e.clientY-lastMousePos.y)/100;
        camera.lookAt(centerVector);
        lastMousePos = {x:e.clientX,iVBORw0KGgoAAA..."
        break;
    }

    image.src = imgData;
}

image = document.createElement("img");
image.onload = init;
image.src = imgData;

当我单击以更改图像时,它没有更新,并且我仍然遇到网站速度变慢的问题。我将vertcies.push转换为vertices.vertices.push()

解决方法

我知道我在以前的答案版本中提到过处置,但是让我们考虑重新使用所有对象。

particles-创建后立即将其添加到场景中。

material-立即将其分配给particles;无需每次都重新分配。

geometry-不要全局创建它,我们将使其在particles中起作用。

现在我们要做的是替换顶点,并告诉three.js有新的顶点要上传到GPU。

var drawTheMap = function() {

    let vertices = particles.geometry; // this acts as a REFERENCE!
    vertices.length = 0; // clears the vertices array

    for (var y = 0,y2 = imagedata.height; y < y2; y += 2) {
        for (var x = 0,x2 = imagedata.width; x < x2; x += 2) {
            if (imagedata.data[(x * 4 + y * 4 * imagedata.width)] < 128) {

                var vertex = new THREE.Vector3();
                vertex.x = x - imagedata.width / 2;
                vertex.y = -y + imagedata.height / 2;
                vertex.z = -Math.random()*500;

                vertex.speed = Math.random() / speed + 0.015;

                vertices.push(vertex);
            }
        }
    }

    particles.geometry.verticesNeedUpdate = true; // Inform three.js of the update

    requestAnimationFrame(render);
};

此处的重要部分(而不是替换vertices数组的内容)是设置particles.geometry.verticesNeedUpdate = true;。这就是触发three.js替换GPU上的顶点的原因。其他所有东西都被重用,而不是重新创建,因此应该运行得很顺利。

,

解决方案是将THREE.geometry更改为THREE.BufferGeometry

var drawTheMap = function() {
    particles.geometry = new THREE.BufferGeometry();
    var positions = [];

    for (var y = 0,x2 = imagedata.width; x < x2; x += 2) {
            if (imagedata.data[(x * 4 + y * 4 * imagedata.width)] < 128)  {

                positions.push(x - imagedata.width / 2);
                positions.push(-y + imagedata.height / 2);
                positions.push(-Math.random()*500);

                particles.geometry.setAttribute( 'position',new THREE.Float32BufferAttribute( positions,3 ) );

            }
        }
    }
    
      particles.geometry.verticesNeedUpdate = true;

    requestAnimationFrame(render);
};

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-