使用 d3-zoom 与 WebGL 交互

2023-12-02

我正在尝试收集一个小示例,该示例使用 d3-zoom 为使用 WebGL 渲染的画布元素提供简单的交互性。我想做的就是提供平移/缩放,这使用 4x4 变换矩阵相当简单。

我遇到的问题是缩放(缩放)。如果您查看一些 d3-zoom 示例,您会发现缩放焦点始终位于鼠标的位置。

如果您使用k, tx, and ty,直接来自缩放变换的值,平移有效,但缩放会偏移画布宽度和高度的一半,请参阅

var width = 300,
        height = 150;

    var zoom = d3.zoom()
        .on( 'zoom', zoomed );

    var canvas = d3.select( 'body' )
        .append( 'canvas' )
        .attr( 'width', width )
        .attr( 'height', height )
        .call( zoom );

    var gl = canvas.node().getContext( 'webgl' );
    var shader = basic_shader(gl);

    initialize_gl();
    set_transform( 1, 0, 0 );

    function zoomed () {
        var t = d3.event.transform;
        set_transform( t.k, t.x, t.y );
    }

    function initialize_gl () {

        var sb = d3.color('steelblue');
        gl.clearColor(sb.r / 255, sb.g / 255, sb.b / 255, 1.0);
        gl.clear(gl.COLOR_BUFFER_BIT);

        var vertices = [
            0.5, 0.5, 0.0, 1.0,
            -0.5, 0.5, 0.0, 1.0,
            0.5, -0.5, 0.0, 1.0,
            -0.5, -0.5, 0.0, 1.0
        ];

        var colors = [
            1.0, 1.0, 1.0, 1.0,    // white
            1.0, 0.0, 0.0, 1.0,    // red
            0.0, 1.0, 0.0, 1.0,    // green
            0.0, 0.0, 1.0, 1.0     // blue
        ];

        var vertex_buffer = gl.createBuffer();
        var color_buffer = gl.createBuffer();

        gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
        gl.vertexAttribPointer(shader.color_attrib, 4, gl.FLOAT, false, 0, 0);
        gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
        gl.vertexAttribPointer(shader.vertex_attrib, 4, gl.FLOAT, false, 0, 0);

    }

    function set_transform ( k, tx, ty ) {

        var matrix = new Float32Array([
            k, 0, 0, 0,
            0, k, 0, 0,
            0, 0, 1, 0,
            2*tx/width, -2*ty/height, 0, 1
        ]);

        gl.uniformMatrix4fv( shader.matrix_uniform, false, matrix );
        gl.clear( gl.COLOR_BUFFER_BIT );
        gl.drawArrays( gl.TRIANGLE_STRIP, 0, 4 );

    }

    function basic_vertex () {

        return [
            'attribute vec4 vertex_position;',
            'attribute vec4 vertex_color;',
            'varying lowp vec4 vert_color;',
            'uniform mat4 matrix;',
            'void main( void ) {',
            '   gl_Position = matrix * vertex_position;',
            '   vert_color = vertex_color;',
            '}'
        ].join('\n');

    }

    function basic_fragment () {

        return [
            'varying lowp vec4 vert_color;',
            'void main( void ) {',
            '   gl_FragColor = vert_color;',
            '}'
        ].join('\n');

    }

    function basic_shader ( gl ) {

        var program = gl_program( gl, basic_vertex(), basic_fragment() );

        gl.useProgram( program );
        program.vertex_attrib = gl.getAttribLocation( program, 'vertex_position' );
        program.color_attrib = gl.getAttribLocation( program, 'vertex_color' );
        program.matrix_uniform = gl.getUniformLocation( program, 'matrix' );
        program.translate_uniform = gl.getUniformLocation( program, 'translate_matrix' );
        program.scale_uniform = gl.getUniformLocation( program, 'scale_matrix' );
        gl.enableVertexAttribArray( program.vertex_attrib );
        gl.enableVertexAttribArray( program.color_attrib );

        return program;

    }

    function gl_shader ( gl, type, code ) {

        var shader = gl.createShader( type );
        gl.shaderSource( shader, code );
        gl.compileShader( shader );
        return shader;

    }

    function gl_program ( gl, vertex_source, fragment_source ) {

        var shader_program = gl.createProgram();
        var vertex_shader = gl_shader( gl, gl.VERTEX_SHADER, vertex_source );
        var fragment_shader = gl_shader( gl, gl.FRAGMENT_SHADER, fragment_source );

        if ( shader_program && vertex_shader && fragment_shader ) {

            gl.attachShader( shader_program, vertex_shader );
            gl.attachShader( shader_program, fragment_shader );
            gl.linkProgram( shader_program );

            gl.deleteShader( vertex_shader );
            gl.deleteShader( fragment_shader );

            return shader_program;

        }

    }
<script src="https://d3js.org/d3.v4.min.js"></script>

我的预感是,这与以下事实有关:在 WebGL 中,视口 x 和 y 坐标分别从 -1 到 1,而 d3-zoom 使用画布元素内的鼠标坐标,标准化后可以在范围 0 到 1。

如果将鼠标放在画布的左上角(画布坐标中的 (0,0))并尝试缩放,您会看到这种情况。它将缩放,就好像鼠标位于画布中心(WebGL 坐标中的 (0,0))一样。

为了解决这个问题,您可以从 x 平移中减去 1(即坐​​标系 [-1,1] 宽度的一半)并添加 1(即坐​​标系 [-1,1] 高度的一半) y 翻译,如下所示

    var width = 300,
        height = 150;

    var zoom = d3.zoom()
        .on( 'zoom', zoomed );

    var canvas = d3.select( 'body' )
        .append( 'canvas' )
        .attr( 'width', width )
        .attr( 'height', height )
        .call( zoom );

    var gl = canvas.node().getContext( 'webgl' );
    var shader = basic_shader(gl);

    initialize_gl();
    set_transform( 1, 0, 0 );

    function zoomed () {
        var t = d3.event.transform;
        set_transform( t.k, t.x, t.y );
    }

    function initialize_gl () {

        var sb = d3.color('steelblue');
        gl.clearColor(sb.r / 255, sb.g / 255, sb.b / 255, 1.0);
        gl.clear(gl.COLOR_BUFFER_BIT);

        var vertices = [
            0.5, 0.5, 0.0, 1.0,
            -0.5, 0.5, 0.0, 1.0,
            0.5, -0.5, 0.0, 1.0,
            -0.5, -0.5, 0.0, 1.0
        ];

        var colors = [
            1.0, 1.0, 1.0, 1.0,    // white
            1.0, 0.0, 0.0, 1.0,    // red
            0.0, 1.0, 0.0, 1.0,    // green
            0.0, 0.0, 1.0, 1.0     // blue
        ];

        var vertex_buffer = gl.createBuffer();
        var color_buffer = gl.createBuffer();

        gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
        gl.vertexAttribPointer(shader.color_attrib, 4, gl.FLOAT, false, 0, 0);
        gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
        gl.vertexAttribPointer(shader.vertex_attrib, 4, gl.FLOAT, false, 0, 0);

    }

    function set_transform ( k, tx, ty ) {

        var matrix = new Float32Array([
            k, 0, 0, 0,
            0, k, 0, 0,
            0, 0, 1, 0,
            2*tx/width-1.0, -2*ty/height+1.0, 0, 1
        ]);

        gl.uniformMatrix4fv( shader.matrix_uniform, false, matrix );
        gl.clear( gl.COLOR_BUFFER_BIT );
        gl.drawArrays( gl.TRIANGLE_STRIP, 0, 4 );

    }

    function basic_vertex () {

        return [
            'attribute vec4 vertex_position;',
            'attribute vec4 vertex_color;',
            'varying lowp vec4 vert_color;',
            'uniform mat4 matrix;',
            'void main( void ) {',
            '   gl_Position = matrix * vertex_position;',
            '   vert_color = vertex_color;',
            '}'
        ].join('\n');

    }

    function basic_fragment () {

        return [
            'varying lowp vec4 vert_color;',
            'void main( void ) {',
            '   gl_FragColor = vert_color;',
            '}'
        ].join('\n');

    }

    function basic_shader ( gl ) {

        var program = gl_program( gl, basic_vertex(), basic_fragment() );

        gl.useProgram( program );
        program.vertex_attrib = gl.getAttribLocation( program, 'vertex_position' );
        program.color_attrib = gl.getAttribLocation( program, 'vertex_color' );
        program.matrix_uniform = gl.getUniformLocation( program, 'matrix' );
        program.translate_uniform = gl.getUniformLocation( program, 'translate_matrix' );
        program.scale_uniform = gl.getUniformLocation( program, 'scale_matrix' );
        gl.enableVertexAttribArray( program.vertex_attrib );
        gl.enableVertexAttribArray( program.color_attrib );

        return program;

    }

    function gl_shader ( gl, type, code ) {

        var shader = gl.createShader( type );
        gl.shaderSource( shader, code );
        gl.compileShader( shader );
        return shader;

    }

    function gl_program ( gl, vertex_source, fragment_source ) {

        var shader_program = gl.createProgram();
        var vertex_shader = gl_shader( gl, gl.VERTEX_SHADER, vertex_source );
        var fragment_shader = gl_shader( gl, gl.FRAGMENT_SHADER, fragment_source );

        if ( shader_program && vertex_shader && fragment_shader ) {

            gl.attachShader( shader_program, vertex_shader );
            gl.attachShader( shader_program, fragment_shader );
            gl.linkProgram( shader_program );

            gl.deleteShader( vertex_shader );
            gl.deleteShader( fragment_shader );

            return shader_program;

        }

    }
<script src="https://d3js.org/d3.v4.min.js"></script>

但是,通过执行偏移,您的场景最初会被平移,这并不完全理想。所以我的问题是,处理这个问题的最佳方法是什么?是由 d3 端处理最好还是由 WebGL 端处理最好?


我刚刚移动了你的顶点以匹配你的矩阵

    var vertices = [
         .5,  -.5, 0.0, 1.0,
        1.5,  -.5, 0.0, 1.0,
         .5, -1.5, 0.0, 1.0,
        1.5, -1.5, 0.0, 1.0
    ];      

var width = 300,
        height = 150;

    var zoom = d3.zoom()
        .on( 'zoom', zoomed );

    var canvas = d3.select( 'body' )
        .append( 'canvas' )
        .attr( 'width', width )
        .attr( 'height', height )
        .call( zoom );

    var gl = canvas.node().getContext( 'webgl' );
    var shader = basic_shader(gl);

    initialize_gl();
    set_transform( 1, 0, 0 );

    function zoomed () {
        var t = d3.event.transform;
        set_transform( t.k, t.x, t.y );
    }

    function initialize_gl () {

        var sb = d3.color('steelblue');
        gl.clearColor(sb.r / 255, sb.g / 255, sb.b / 255, 1.0);
        gl.clear(gl.COLOR_BUFFER_BIT);

        var vertices = [
             .5,  -.5, 0.0, 1.0,
            1.5,  -.5, 0.0, 1.0,
             .5, -1.5, 0.0, 1.0,
            1.5, -1.5, 0.0, 1.0
        ];        

        var colors = [
            1.0, 1.0, 1.0, 1.0,    // white
            1.0, 0.0, 0.0, 1.0,    // red
            0.0, 1.0, 0.0, 1.0,    // green
            0.0, 0.0, 1.0, 1.0     // blue
        ];

        var vertex_buffer = gl.createBuffer();
        var color_buffer = gl.createBuffer();

        gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
        gl.vertexAttribPointer(shader.color_attrib, 4, gl.FLOAT, false, 0, 0);
        gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
        gl.vertexAttribPointer(shader.vertex_attrib, 4, gl.FLOAT, false, 0, 0);

    }

    function set_transform ( k, tx, ty ) {

        var matrix = new Float32Array([
            k, 0, 0, 0,
            0, k, 0, 0,
            0, 0, 1, 0,
            2*tx/width-1.0, -2*ty/height+1.0, 0, 1
        ]);

        gl.uniformMatrix4fv( shader.matrix_uniform, false, matrix );
        gl.clear( gl.COLOR_BUFFER_BIT );
        gl.drawArrays( gl.TRIANGLE_STRIP, 0, 4 );

    }

    function basic_vertex () {

        return [
            'attribute vec4 vertex_position;',
            'attribute vec4 vertex_color;',
            'varying lowp vec4 vert_color;',
            'uniform mat4 matrix;',
            'void main( void ) {',
            '   gl_Position = matrix * vertex_position;',
            '   vert_color = vertex_color;',
            '}'
        ].join('\n');

    }

    function basic_fragment () {

        return [
            'varying lowp vec4 vert_color;',
            'void main( void ) {',
            '   gl_FragColor = vert_color;',
            '}'
        ].join('\n');

    }

    function basic_shader ( gl ) {

        var program = gl_program( gl, basic_vertex(), basic_fragment() );

        gl.useProgram( program );
        program.vertex_attrib = gl.getAttribLocation( program, 'vertex_position' );
        program.color_attrib = gl.getAttribLocation( program, 'vertex_color' );
        program.matrix_uniform = gl.getUniformLocation( program, 'matrix' );
        program.translate_uniform = gl.getUniformLocation( program, 'translate_matrix' );
        program.scale_uniform = gl.getUniformLocation( program, 'scale_matrix' );
        gl.enableVertexAttribArray( program.vertex_attrib );
        gl.enableVertexAttribArray( program.color_attrib );

        return program;

    }

    function gl_shader ( gl, type, code ) {

        var shader = gl.createShader( type );
        gl.shaderSource( shader, code );
        gl.compileShader( shader );
        return shader;

    }

    function gl_program ( gl, vertex_source, fragment_source ) {

        var shader_program = gl.createProgram();
        var vertex_shader = gl_shader( gl, gl.VERTEX_SHADER, vertex_source );
        var fragment_shader = gl_shader( gl, gl.FRAGMENT_SHADER, fragment_source );

        if ( shader_program && vertex_shader && fragment_shader ) {

            gl.attachShader( shader_program, vertex_shader );
            gl.attachShader( shader_program, fragment_shader );
            gl.linkProgram( shader_program );

            gl.deleteShader( vertex_shader );
            gl.deleteShader( fragment_shader );

            return shader_program;

        }

    }
<script src="https://d3js.org/d3.v4.min.js"></script>

但老实说,我可能会使用数学库并使用一些转换。这样我更容易理解代码。我不确定D3的“空间”是什么。我想虽然它只是传递给你一个偏移量和一个比例。在这种情况下

        // change the space to be pixels with 0,0 in top left
        var matrix = m4.ortho(0, gl.canvas.width, gl.canvas.height, 0, -1, 1);

        // apply the d3 translate and zoom
        matrix = m4.translate(matrix, [tx, ty, 0]);
        matrix = m4.scale(matrix, [k, k, 1]);

        // translate the unit quad to the center 
        matrix = m4.translate(matrix, [width / 2, height / 2, 0]);

        // make the unit quad be half the size of the canvas
        matrix = m4.scale(matrix, [width / 2, height / 2 , 1]);

var m4 = twgl.m4;
    var width = 300,
        height = 150;

    var zoom = d3.zoom()
        .on( 'zoom', zoomed );

    var canvas = d3.select( 'body' )
        .append( 'canvas' )
        .attr( 'width', width )
        .attr( 'height', height )
        .call( zoom );

    var gl = canvas.node().getContext( 'webgl' );
    var shader = basic_shader(gl);

    initialize_gl();
    set_transform( 1, 0, 0 );

    function zoomed () {
        var t = d3.event.transform;
        set_transform( t.k, t.x, t.y );
    }

    function initialize_gl () {

        var sb = d3.color('steelblue');
        gl.clearColor(sb.r / 255, sb.g / 255, sb.b / 255, 1.0);
        gl.clear(gl.COLOR_BUFFER_BIT);

        var vertices = [
            -.5,   .5, 0.0, 1.0,
             .5,   .5, 0.0, 1.0,
            -.5,  -.5, 0.0, 1.0,
             .5,  -.5, 0.0, 1.0
        ];        

        var colors = [
            1.0, 1.0, 1.0, 1.0,    // white
            1.0, 0.0, 0.0, 1.0,    // red
            0.0, 1.0, 0.0, 1.0,    // green
            0.0, 0.0, 1.0, 1.0     // blue
        ];

        var vertex_buffer = gl.createBuffer();
        var color_buffer = gl.createBuffer();

        gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
        gl.vertexAttribPointer(shader.color_attrib, 4, gl.FLOAT, false, 0, 0);
        gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
        gl.vertexAttribPointer(shader.vertex_attrib, 4, gl.FLOAT, false, 0, 0);

    }

    function set_transform ( k, tx, ty ) {

        // change the space to be pixels with 0,0 in top left
        var matrix = m4.ortho(0, gl.canvas.width, gl.canvas.height, 0, -1, 1);
        // apply the d3 translate and zoom
        matrix = m4.translate(matrix, [tx, ty, 0]);
        matrix = m4.scale(matrix, [k, k, 1]);
        // translate the unit quad to the center 
        matrix = m4.translate(matrix, [width / 2, height / 2, 0]);
        // make the unit quad be half the size of the canvas
        matrix = m4.scale(matrix, [width / 2, height / 2 , 1]);

        gl.uniformMatrix4fv( shader.matrix_uniform, false, matrix );
        gl.clear( gl.COLOR_BUFFER_BIT );
        gl.drawArrays( gl.TRIANGLE_STRIP, 0, 4 );

    }

    function basic_vertex () {

        return [
            'attribute vec4 vertex_position;',
            'attribute vec4 vertex_color;',
            'varying lowp vec4 vert_color;',
            'uniform mat4 matrix;',
            'void main( void ) {',
            '   gl_Position = matrix * vertex_position;',
            '   vert_color = vertex_color;',
            '}'
        ].join('\n');

    }

    function basic_fragment () {

        return [
            'varying lowp vec4 vert_color;',
            'void main( void ) {',
            '   gl_FragColor = vert_color;',
            '}'
        ].join('\n');

    }

    function basic_shader ( gl ) {

        var program = gl_program( gl, basic_vertex(), basic_fragment() );

        gl.useProgram( program );
        program.vertex_attrib = gl.getAttribLocation( program, 'vertex_position' );
        program.color_attrib = gl.getAttribLocation( program, 'vertex_color' );
        program.matrix_uniform = gl.getUniformLocation( program, 'matrix' );
        program.translate_uniform = gl.getUniformLocation( program, 'translate_matrix' );
        program.scale_uniform = gl.getUniformLocation( program, 'scale_matrix' );
        gl.enableVertexAttribArray( program.vertex_attrib );
        gl.enableVertexAttribArray( program.color_attrib );

        return program;

    }

    function gl_shader ( gl, type, code ) {

        var shader = gl.createShader( type );
        gl.shaderSource( shader, code );
        gl.compileShader( shader );
        return shader;

    }

    function gl_program ( gl, vertex_source, fragment_source ) {

        var shader_program = gl.createProgram();
        var vertex_shader = gl_shader( gl, gl.VERTEX_SHADER, vertex_source );
        var fragment_shader = gl_shader( gl, gl.FRAGMENT_SHADER, fragment_source );

        if ( shader_program && vertex_shader && fragment_shader ) {

            gl.attachShader( shader_program, vertex_shader );
            gl.attachShader( shader_program, fragment_shader );
            gl.linkProgram( shader_program );

            gl.deleteShader( vertex_shader );
            gl.deleteShader( fragment_shader );

            return shader_program;

        }

    }
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://twgljs.org/dist/3.x/twgl-full.min.js"></script>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 d3-zoom 与 WebGL 交互 的相关文章

  • 如何使用角度在垫选择嵌套值中包含过滤器

    我正在使用带有嵌套下拉菜单的有角材料 下拉值以父级和子级为基础嵌套 我面临两个问题 自动建议不起作用 如果我输入父名称或其关联的子名称 则必须以展开模式过滤并显示特定的父视图 如果我展开第一个父视图并尝试展开第二个父视图 则第一个父视图应在
  • Google Closure 和生成的 getter/setter

    我正在尝试让 KineticJS 与 Google Closure Compiler 一起使用 然而 KineticJS 根据变量的名称生成它的 getter 和 setter 像这样的事情 add getter and setter me
  • Browserify 与 jQuery >= 2 生成“jQuery 需要一个带有文档的窗口”

    我正在使用 browserify 使用 CommonJS 样式的依赖项来捆绑我的前端 javascript 例如 我有 require jquery dist jquery v2 1 0 beta2 require underscore
  • 如何对页面的某个部分进行实时更新?

    我需要刷新页面的各个部分 以便在有新数据时进行更新 我该怎么办 使用jquery 例子 是的 jQuery 非常适合这个 查看这些方法 http api jquery com category ajax http api jquery co
  • 系统js语法错误,IE11

    我有一个 Angular 2 应用程序可以在 Firefox 和 Chrome 中工作 但在 IE 中却没有那么多工作 根据我的堆栈跟踪 我的 System js 设置似乎存在问题 这是我在网络控制台中看到的错误描述 Error Syste
  • EXT JS中有全局变量吗

    在 java 和 C 中 我们可以全局存储变量并从项目中的任何位置访问它的值 比如说 我在一个名为Residence我正在保存residenceNumber这是一个INT到一个名为的全局变量houseNumberGlobalVariable
  • 切换 Ag-Grid 中的浮动过滤器?

    我试图通过开关或按钮单击来确定浮动过滤器的显示 看起来很简单 我应该能够在 true 和 false 之间切换 将该值提供给网格选项中的浮动过滤器 然后刷新标题 对吗 不幸的是 网格似乎总是落后一步 当我第一次点击时 什么也没有发生 当我将
  • 将 Babel 与单个输出文件和 ES6 模块一起使用

    这是我的 gulp 任务 将 ES6 代码编译成单个 ES5 文件 我使用类和模块 import export 在 ES6 中 gulp src paths scripts pipe sourcemaps init pipe babel p
  • 使用 javascript 和 jQuery UI datepicker 获取工作日数

    我有两个日期选择器 我可以从中计算天数 而无需计算星期六和星期日 但我想在周五和周六这样做 我尝试过一些不同的方法但失败了 对我来说 处理不包括周六和周日的天数很容易 但处理周五和周六的天数则不然 以下是我的 javascript 代码 f
  • Google 闭包编译器使用 WebStorm

    我喜欢用谷歌闭包编译器 https developers google com closure compiler in WebStorm https www jetbrains com webstorm 我已经通过 npm 下载了它 npm
  • pointdown 与 onclick:有什么区别?

    两者有什么区别onpointerdown and onclick事件处理程序 有任何实际差异吗 事件在 DOM 树上传播的方式不一样吗 是否有一些设备仅响应这些事件之一 我最初以为这只是pointerdown在触摸设备或笔中触发 但是onc
  • 如何在 Electron 中使窗口大小响应。 (打开应用程序时)

    我最近开始在 Electron 上制作一个应用程序 我想让窗口具有响应能力 例如 如果我在不同的屏幕上打开应用程序 它应该根据屏幕尺寸以全尺寸打开 我的代码 app on ready gt const htmlPath path join
  • up() 和 down() 与 Ext.getCmp()

    我很困惑我需要在 up down 和 Ext getCmp ID 之间使用哪一个作为 grep 对象 对我来说 定义对象的 ID 并通过 Ext getCmp ID 检索对象更容易 而且代码看起来更干净 例如 console log thi
  • 如何在从数据库异步加载中用占位符替换不存在的图像

    我有一个包含图像的数据库 我需要根据用户的请求即时加载这些图像 这些图像将作为包含 div 容器中的单独 s 的背景图像 类似于图像滚动条 该数据库当前是本地数据库 但这不是我的问题 问题是数据库可能没有我请求的所有图像 并且我可能会得到一
  • 使用 _.extend() 进行 JavaScript 继承

    有什么区别 Employee prototype Object create Person prototype and extend Employee prototype Person prototype 两者都给出相似的结果 输出 但下划
  • getCompatedStyle 类似于 IE8 的 javascript 函数

    我正在尝试在 Java GWT 代码中编写一个 Javascript 函数 该函数获取以下样式的值 direction fontFamily fontSize fontSizeAdjust fontStyle fontWeight lett
  • 将 html

    我有一些服务器端代码当前支持 http 字节范围请求 没有任何问题 但是 我希望能够在将转码后的块发送到客户端之前使用 ffmpeg 即时转码视频文件 位于磁盘上 但 ffmpeg 要求我在获取字节时给它一个寻道时间范围来自客户 给定客户端
  • 当 JavaScript 抛出异常时不要停止它

    我正在使用 JavaScript 编写一个 Windows 边栏小工具 现在我想捕获所有 JavaScript 异常并将其记录到文本文件中 一个问题是 当任何一行抛出异常时 下一行将不会被执行 是否可以自动捕获异常 以便执行以下 JavaS
  • 如何将 JSLint 用于依赖于 JQuery 的代码段?

    我对 Javascript 比较陌生 我想通过 JSLint 运行我周末玩的那段代码 这样它就可以指出我在哪里是个十足的白痴 不幸的是 我收到了大量关于缺少函数声明的错误 这些函数声明是 JQuery javascript 库及其各种插件的
  • 将画布下载为 PNG 图像[重复]

    这个问题在这里已经有答案了 当我尝试将画布下载为 PNG 图像时 浏览器会在新页面中打开该图像 但不下载它 我的下载代码 btnScaricaEtichetta click function console log Download loc

随机推荐