Skip to content

Commit

Permalink
Merge pull request #13 from remcoder/develop
Browse files Browse the repository at this point in the history
Release 2.1.0
  • Loading branch information
remcoder authored Jun 16, 2020
2 parents 6e1474c + b1cfac8 commit 0ad755d
Show file tree
Hide file tree
Showing 39 changed files with 11,526 additions and 5,306 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ dist/__tests__
yarn-error.log
.firebase/hosting.*
TODO.md
.DS_Store
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
13
30 changes: 29 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,37 @@
## 2.1.0
- remove lineWidth for now

## 2.1.0-alpha.5
- fix an issue with incremental rendering where the top layer would sometimes not have the correct color
- allow canvas snapshots (to save the image as a file for instance)

## 2.1.0-alpha.4
- fixed scaling & resizing issues
- support multiple instances

## 2.1.0-alpha.3
- support lineWidth to render fat lines (known issue: travel is inorrectly rendered as extrusion lines)

## alpha 2.1.0-alpha.2
- don't reset the layer limit after parsing the gcode
- highlight the top layer and the last segment
- top layer / last segment color is configurable
- clear() method added to reset parser state

## alpha 2.1.0-alpha.0
- add incremental parsing
- bugfix: only create a new layer when extruding
- allow input to be either a string or an array of strings
- remove 2.5d canvas version
- demo: shows how to use incremental parsing to render a file progressively


## 2.0
- updated demo page
- toggle rendering of travel
- toggle rendering of extrusion
- WebGL rendering with pan/zoom/rotate controls
- added `lineWidth` option (canvas 2.5D only)
- added `lineWidth` option (canvas 2.5 D only)
- fully typed

## 1.0.0
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ There's also a [Vue.js example](https://github.com/remcoder/gcode-preview-vue-de
This is caused by the device recognition shield in Brave. By changing the setting for "Device Recognition" in Shield settings to "Allow all device recognition attemps" or "Only block cross-site device recognition attemps" you should not get this error.
https://github.com/mrdoob/three.js/issues/16904

## Notice: deprecation of Canvas2D
In favor of WebGL, I'm deprecating the Canvas 2Drendering. My reasons for this are:
- WebGL (via THREE.js) gives me more options, like rotating the model
- WebGL renders faster
- I don't want to maintain 2 rendering methods due to time constraints

This means that as of version 2.1.0 only WebGL will be supported. I you really want to use Canvas 2D, stay at the 2.0.x version branch and/or consider forking.

## Sponsors

A big thanks to these sponsors for their contributions.
Expand Down
268 changes: 268 additions & 0 deletions demo/canvas2image.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
/**
* covert canvas to image
* and save the image file
*/

var Canvas2Image = function () {

// check if support sth.
var $support = function () {
var canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d');

return {
canvas: !!ctx,
imageData: !!ctx.getImageData,
dataURL: !!canvas.toDataURL,
btoa: !!window.btoa
};
}();

var downloadMime = 'image/octet-stream';

function scaleCanvas (canvas, width, height) {
var w = canvas.width,
h = canvas.height;
if (width == undefined) {
width = w;
}
if (height == undefined) {
height = h;
}

var retCanvas = document.createElement('canvas');
var retCtx = retCanvas.getContext('2d');
retCanvas.width = width;
retCanvas.height = height;
retCtx.drawImage(canvas, 0, 0, w, h, 0, 0, width, height);
return retCanvas;
}

function getDataURL (canvas, type, width, height) {
canvas = scaleCanvas(canvas, width, height);
return canvas.toDataURL(type);
}

function saveFile (strData, filename) {
var link = document.createElement("a");
link.download = filename;
link.href = strData;
link.click();
}

function genImage(strData) {
var img = document.createElement('img');
img.src = strData;
return img;
}
function fixType (type) {
type = type.toLowerCase().replace(/jpg/i, 'jpeg');
var r = type.match(/png|jpeg|bmp|gif/)[0];
return 'image/' + r;
}
function encodeData (data) {
if (!window.btoa) { throw 'btoa undefined' }
var str = '';
if (typeof data == 'string') {
str = data;
} else {
for (var i = 0; i < data.length; i ++) {
str += String.fromCharCode(data[i]);
}
}

return btoa(str);
}
function getImageData (canvas) {
var w = canvas.width,
h = canvas.height;
return canvas.getContext('2d').getImageData(0, 0, w, h);
}
function makeURI (strData, type) {
return 'data:' + type + ';base64,' + strData;
}


/**
* create bitmap image
* 按照规则生成图片响应头和响应体
*/
var genBitmapImage = function (oData) {

//
// BITMAPFILEHEADER: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183374(v=vs.85).aspx
// BITMAPINFOHEADER: http://msdn.microsoft.com/en-us/library/dd183376.aspx
//

var biWidth = oData.width;
var biHeight = oData.height;
var biSizeImage = biWidth * biHeight * 3;
var bfSize = biSizeImage + 54; // total header size = 54 bytes

//
// typedef struct tagBITMAPFILEHEADER {
// WORD bfType;
// DWORD bfSize;
// WORD bfReserved1;
// WORD bfReserved2;
// DWORD bfOffBits;
// } BITMAPFILEHEADER;
//
var BITMAPFILEHEADER = [
// WORD bfType -- The file type signature; must be "BM"
0x42, 0x4D,
// DWORD bfSize -- The size, in bytes, of the bitmap file
bfSize & 0xff, bfSize >> 8 & 0xff, bfSize >> 16 & 0xff, bfSize >> 24 & 0xff,
// WORD bfReserved1 -- Reserved; must be zero
0, 0,
// WORD bfReserved2 -- Reserved; must be zero
0, 0,
// DWORD bfOffBits -- The offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits.
54, 0, 0, 0
];

//
// typedef struct tagBITMAPINFOHEADER {
// DWORD biSize;
// LONG biWidth;
// LONG biHeight;
// WORD biPlanes;
// WORD biBitCount;
// DWORD biCompression;
// DWORD biSizeImage;
// LONG biXPelsPerMeter;
// LONG biYPelsPerMeter;
// DWORD biClrUsed;
// DWORD biClrImportant;
// } BITMAPINFOHEADER, *PBITMAPINFOHEADER;
//
var BITMAPINFOHEADER = [
// DWORD biSize -- The number of bytes required by the structure
40, 0, 0, 0,
// LONG biWidth -- The width of the bitmap, in pixels
biWidth & 0xff, biWidth >> 8 & 0xff, biWidth >> 16 & 0xff, biWidth >> 24 & 0xff,
// LONG biHeight -- The height of the bitmap, in pixels
biHeight & 0xff, biHeight >> 8 & 0xff, biHeight >> 16 & 0xff, biHeight >> 24 & 0xff,
// WORD biPlanes -- The number of planes for the target device. This value must be set to 1
1, 0,
// WORD biBitCount -- The number of bits-per-pixel, 24 bits-per-pixel -- the bitmap
// has a maximum of 2^24 colors (16777216, Truecolor)
24, 0,
// DWORD biCompression -- The type of compression, BI_RGB (code 0) -- uncompressed
0, 0, 0, 0,
// DWORD biSizeImage -- The size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps
biSizeImage & 0xff, biSizeImage >> 8 & 0xff, biSizeImage >> 16 & 0xff, biSizeImage >> 24 & 0xff,
// LONG biXPelsPerMeter, unused
0,0,0,0,
// LONG biYPelsPerMeter, unused
0,0,0,0,
// DWORD biClrUsed, the number of color indexes of palette, unused
0,0,0,0,
// DWORD biClrImportant, unused
0,0,0,0
];

var iPadding = (4 - ((biWidth * 3) % 4)) % 4;

var aImgData = oData.data;

var strPixelData = '';
var biWidth4 = biWidth<<2;
var y = biHeight;
var fromCharCode = String.fromCharCode;

do {
var iOffsetY = biWidth4*(y-1);
var strPixelRow = '';
for (var x = 0; x < biWidth; x++) {
var iOffsetX = x<<2;
strPixelRow += fromCharCode(aImgData[iOffsetY+iOffsetX+2]) +
fromCharCode(aImgData[iOffsetY+iOffsetX+1]) +
fromCharCode(aImgData[iOffsetY+iOffsetX]);
}

for (var c = 0; c < iPadding; c++) {
strPixelRow += String.fromCharCode(0);
}

strPixelData += strPixelRow;
} while (--y);

var strEncoded = encodeData(BITMAPFILEHEADER.concat(BITMAPINFOHEADER)) + encodeData(strPixelData);

return strEncoded;
};

/**
* saveAsImage
* @param canvasElement
* @param {String} image type
* @param {Number} [optional] png width
* @param {Number} [optional] png height
*/
var saveAsImage = function (canvas, width, height, type, filename) {
if ($support.canvas && $support.dataURL) {
if (typeof canvas == "string") { canvas = document.getElementById(canvas); }
if (type == undefined) { type = 'png'; }
type = fixType(type);
if (/bmp/.test(type)) {
var data = getImageData(scaleCanvas(canvas, width, height));
var strData = genBitmapImage(data);
saveFile(makeURI(strData, downloadMime), filename);
} else {
var strData = getDataURL(canvas, type, width, height);
saveFile(strData.replace(type, downloadMime), filename);
}
}
};

var convertToImage = function (canvas, width, height, type) {
if ($support.canvas && $support.dataURL) {
if (typeof canvas == "string") { canvas = document.getElementById(canvas); }
if (type == undefined) { type = 'png'; }
type = fixType(type);

if (/bmp/.test(type)) {
var data = getImageData(scaleCanvas(canvas, width, height));
var strData = genBitmapImage(data);
return genImage(makeURI(strData, 'image/bmp'));
} else {
var strData = getDataURL(canvas, type, width, height);
return genImage(strData);
}
}
};



return {
saveAsImage: saveAsImage,
saveAsPNG: function (canvas, width, height, filename) {
return saveAsImage(canvas, width, height, 'png', filename);
},
saveAsJPEG: function (canvas, width, height, filename) {
return saveAsImage(canvas, width, height, 'jpeg', filename);
},
saveAsGIF: function (canvas, width, height, filename) {
return saveAsImage(canvas, width, height, 'gif', filename);
},
saveAsBMP: function (canvas, width, height, filename) {
return saveAsImage(canvas, width, height, 'bmp', filename);
},

convertToImage: convertToImage,
convertToPNG: function (canvas, width, height) {
return convertToImage(canvas, width, height, 'png');
},
convertToJPEG: function (canvas, width, height) {
return convertToImage(canvas, width, height, 'jpeg');
},
convertToGIF: function (canvas, width, height) {
return convertToImage(canvas, width, height, 'gif');
},
convertToBMP: function (canvas, width, height) {
return convertToImage(canvas, width, height, 'bmp');
}
};

}();
Loading

0 comments on commit 0ad755d

Please sign in to comment.