Using HTML5/JavaScript to generate and save a file

后端 未结 17 1739
有刺的猬
有刺的猬 2020-11-21 07:30

I\'ve been fiddling with WebGL lately, and have gotten a Collada reader working. Problem is it\'s pretty slow (Collada is a very verbose format), so I\'m going to start conv

17条回答
  •  悲哀的现实
    2020-11-21 07:58

    This thread was invaluable to figure out how to generate a binary file and prompt to download the named file, all in client code without a server.

    First step for me was generating the binary blob from data that I was saving. There's plenty of samples for doing this for a single binary type, in my case I have a binary format with multiple types which you can pass as an array to create the blob.

    saveAnimation: function() {
    
        var device = this.Device;
        var maxRow = ChromaAnimation.getMaxRow(device);
        var maxColumn = ChromaAnimation.getMaxColumn(device);
        var frames = this.Frames;
        var frameCount = frames.length;
    
        var writeArrays = [];
    
    
        var writeArray = new Uint32Array(1);
        var version = 1;
        writeArray[0] = version;
        writeArrays.push(writeArray.buffer);
        //console.log('version:', version);
    
    
        var writeArray = new Uint8Array(1);
        var deviceType = this.DeviceType;
        writeArray[0] = deviceType;
        writeArrays.push(writeArray.buffer);
        //console.log('deviceType:', deviceType);
    
    
        var writeArray = new Uint8Array(1);
        writeArray[0] = device;
        writeArrays.push(writeArray.buffer);
        //console.log('device:', device);
    
    
        var writeArray = new Uint32Array(1);
        writeArray[0] = frameCount;
        writeArrays.push(writeArray.buffer);
        //console.log('frameCount:', frameCount);
    
        for (var index = 0; index < frameCount; ++index) {
    
          var frame = frames[index];
    
          var writeArray = new Float32Array(1);
          var duration = frame.Duration;
          if (duration < 0.033) {
            duration = 0.033;
          }
          writeArray[0] = duration;
          writeArrays.push(writeArray.buffer);
    
          //console.log('Frame', index, 'duration', duration);
    
          var writeArray = new Uint32Array(maxRow * maxColumn);
          for (var i = 0; i < maxRow; ++i) {
            for (var j = 0; j < maxColumn; ++j) {
              var color = frame.Colors[i][j];
              writeArray[i * maxColumn + j] = color;
            }
          }
          writeArrays.push(writeArray.buffer);
        }
    
        var blob = new Blob(writeArrays, {type: 'application/octet-stream'});
    
        return blob;
    }
    

    The next step is to get the browser to prompt the user to download this blob with a predefined name.

    All I needed was a named link I added in the HTML5 that I could reuse to rename the initial filename. I kept it hidden since the link doesn't need display.

    
    

    The last step is to prompt the user to download the file.

    var data = animation.saveAnimation();
    var uriContent = URL.createObjectURL(data);
    var lnkDownload = document.getElementById('lnkDownload');
    lnkDownload.download = 'theDefaultFileName.extension';
    lnkDownload.href = uriContent;
    lnkDownload.click();
    

提交回复
热议问题