mirror of
https://github.com/Doodle3D/doodle3d-client.git
synced 2024-11-25 10:37:56 +01:00
bunch of javascript
This commit is contained in:
parent
ae4e8e080b
commit
83237b9a38
276
js/buttonbehaviors.js
Normal file
276
js/buttonbehaviors.js
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
var btnMoveUpInterval;
|
||||||
|
var btnMoveDownInterval;
|
||||||
|
|
||||||
|
var btnTwistLeftInterval;
|
||||||
|
var btnTwistRightInterval;
|
||||||
|
var twistIncrement = Math.PI/1800;
|
||||||
|
|
||||||
|
var btnOopsInterval;
|
||||||
|
|
||||||
|
//var btnNew, btnPrevious, btnNext;
|
||||||
|
var btnOops, btnStop, btnClear;
|
||||||
|
var btnMoveUp, btnMoveDown, btnTwistLeft, btnTwistRight;
|
||||||
|
var btnInfo, btnSettings;
|
||||||
|
var btnDebug; // debug
|
||||||
|
|
||||||
|
function initButtonBehavior() {
|
||||||
|
console.log("f:initButtonBehavior >> btnNew = " + btnNew);
|
||||||
|
|
||||||
|
btnClear= $("#btnClear");
|
||||||
|
btnOops = $("#btnOops");
|
||||||
|
btnMoveUp = $("#btnMoveUp");
|
||||||
|
btnMoveDown = $("#btnMoveDown");
|
||||||
|
btnTwistLeft = $("#btnTwistLeft");
|
||||||
|
btnTwistRight = $("#btnTwistRight");
|
||||||
|
btnInfo = $("#btnInfo");
|
||||||
|
btnSettings = $("#btnSettings");
|
||||||
|
// btnPrint= $("#btnPrint");
|
||||||
|
|
||||||
|
// btnPrevious = $("#btnPrevious");
|
||||||
|
// btnNext = $("#btnNext");
|
||||||
|
|
||||||
|
//debug
|
||||||
|
btnDebug = $(".debugBtn");
|
||||||
|
|
||||||
|
if (!btnNew.addEventListener) {
|
||||||
|
btnNew.attachEvent('onmousedown',clearDoodle);
|
||||||
|
btnNew.attachEvent('ontouchstart',clearDoodle);
|
||||||
|
btnPrint.attachEvent('onmousedown',print);
|
||||||
|
btnPrint.attachEvent('ontouchstart',print);
|
||||||
|
|
||||||
|
// btnPrevious.attachEvent('onmousedown',prevDoodle);
|
||||||
|
// btnPrevious.attachEvent('ontouchstart',prevDoodle);
|
||||||
|
// btnNext.attachEvent('onmousedown',nextDoodle);
|
||||||
|
// btnNext.attachEvent('ontouchstart',nextDoodle);
|
||||||
|
} else {
|
||||||
|
btnNew.addEventListener('mousedown',clearDoodle,false);
|
||||||
|
btnNew.addEventListener('touchstart',clearDoodle,false);
|
||||||
|
btnPrint.addEventListener('mousedown',print,false);
|
||||||
|
btnPrint.addEventListener('touchstart',print,false);
|
||||||
|
|
||||||
|
// btnPrevious.addEventListener('mousedown',prevDoodle,false);
|
||||||
|
// btnPrevious.addEventListener('touchstart',prevDoodle,false);
|
||||||
|
// btnNext.addEventListener('mousedown',nextDoodle,false);
|
||||||
|
// btnNext.addEventListener('touchstart',nextDoodle,false);
|
||||||
|
}
|
||||||
|
|
||||||
|
btnClear.click(function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
// console.log("clear");
|
||||||
|
|
||||||
|
clearDoodle();
|
||||||
|
});
|
||||||
|
|
||||||
|
// btnPrevious.mouseup(function(e) {
|
||||||
|
// e.preventDefault();
|
||||||
|
// console.log("btnPrevious");
|
||||||
|
// })
|
||||||
|
// btnPrevious.bind("touchend", function(e) {
|
||||||
|
// e.preventDefault();
|
||||||
|
// console.log("btnPrevious");
|
||||||
|
// })
|
||||||
|
// btnNext.mouseup(function(e) {
|
||||||
|
// e.preventDefault();
|
||||||
|
// console.log("btnNext");
|
||||||
|
// })
|
||||||
|
// btnNext.bind("touchend", function(e) {
|
||||||
|
// e.preventDefault();
|
||||||
|
// console.log("btnPrevious");
|
||||||
|
// })
|
||||||
|
|
||||||
|
btnOops.mousedown(function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
// console.log("btnOops mouse down");
|
||||||
|
btnOopsInterval = setInterval( function() {
|
||||||
|
oopsUndo();
|
||||||
|
}, 1000/50);
|
||||||
|
});
|
||||||
|
btnOops.mouseup(function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
// console.log("btnOops mouse up");
|
||||||
|
clearInterval(btnOopsInterval);
|
||||||
|
});
|
||||||
|
|
||||||
|
btnMoveUp.mousedown(function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
// console.log("btnMoveUp mouse down");
|
||||||
|
previewUp();
|
||||||
|
clearInterval(btnMoveUpInterval);
|
||||||
|
btnMoveUpInterval = setInterval( function() {
|
||||||
|
previewUp();
|
||||||
|
}, 1000/30);
|
||||||
|
});
|
||||||
|
btnMoveUp.mouseup(function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
console.log("btnMoveUp mouse up");
|
||||||
|
clearInterval(btnMoveUpInterval);
|
||||||
|
});
|
||||||
|
|
||||||
|
btnMoveDown.mousedown(function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
// console.log("btnMoveDown mouse down");
|
||||||
|
previewDown();
|
||||||
|
clearInterval(btnMoveDownInterval);
|
||||||
|
btnMoveDownInterval = setInterval( function() {
|
||||||
|
previewDown();
|
||||||
|
}, 1000/30);
|
||||||
|
});
|
||||||
|
btnMoveDown.mouseup(function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
console.log("btnMoveDown mouse up");
|
||||||
|
clearInterval(btnMoveDownInterval);
|
||||||
|
});
|
||||||
|
|
||||||
|
btnTwistLeft.mousedown(function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
// console.log("btnTwistLeft mouse down");
|
||||||
|
previewTwistLeft();
|
||||||
|
clearInterval(btnTwistLeftInterval);
|
||||||
|
btnTwistLeftInterval = setInterval( function() {
|
||||||
|
previewTwistLeft();
|
||||||
|
}, 1000/30);
|
||||||
|
});
|
||||||
|
btnTwistLeft.mouseup(function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
// console.log("btnTwistLeft mouse up");
|
||||||
|
clearInterval(btnTwistLeftInterval);
|
||||||
|
});
|
||||||
|
|
||||||
|
btnTwistRight.mousedown(function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
// console.log("btnTwistRight mouse down");
|
||||||
|
previewTwistRight();
|
||||||
|
clearInterval(btnTwistRightInterval);
|
||||||
|
btnTwistRightInterval = setInterval( function() {
|
||||||
|
previewTwistRight();
|
||||||
|
}, 1000/30);
|
||||||
|
});
|
||||||
|
btnTwistRight.mouseup(function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
// console.log("btnTwistRight mouse up");
|
||||||
|
clearInterval(btnTwistRightInterval);
|
||||||
|
});
|
||||||
|
|
||||||
|
btnSettings.mouseup(function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
console.log("btnSettings mouse up");
|
||||||
|
});
|
||||||
|
|
||||||
|
btnInfo.mouseup(function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
console.log("btnInfo mouse up");
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
// $(".agentInfo").css("display", "none");
|
||||||
|
btnDebug.click(function(e) {
|
||||||
|
console.log("debugClick");
|
||||||
|
$(".agentInfo").toggleClass("agentInfoToggle");
|
||||||
|
e.preventDefault();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function prevDoodle(e) {
|
||||||
|
console.log("f:prevDoodle()");
|
||||||
|
}
|
||||||
|
function nextDoodle(e) {
|
||||||
|
console.log("f:nextDoodle()");
|
||||||
|
}
|
||||||
|
|
||||||
|
function print(e) {
|
||||||
|
console.log("f:print()");
|
||||||
|
|
||||||
|
$("#textdump").text("");
|
||||||
|
if (_points.length > 2) {
|
||||||
|
//*
|
||||||
|
// generate_gcode();
|
||||||
|
var gencode = generate_gcode();
|
||||||
|
startPrint();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// console.log("");
|
||||||
|
// console.log("");
|
||||||
|
// console.log("-------------------------------------------------");
|
||||||
|
// console.log("generated gcode:");
|
||||||
|
// console.log(gencode);
|
||||||
|
// console.log("-------------------------------------------------");
|
||||||
|
// console.log("");
|
||||||
|
// console.log("");
|
||||||
|
// console.log("");
|
||||||
|
|
||||||
|
$("#textdump").text(gencode);
|
||||||
|
// copyToClipboard(gencode);
|
||||||
|
//*/
|
||||||
|
} else {
|
||||||
|
console.log("f:print >> not enough points!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// $.post("/doodle3d.of", { data:output }, function(data) {
|
||||||
|
// btnPrint.disabled = false;
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function clearMainView() {
|
||||||
|
// console.log("f:clearMainView()");
|
||||||
|
ctx.save();
|
||||||
|
ctx.clearRect(0,0,canvas.width, canvas.height);
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
|
function clearPreview() {
|
||||||
|
// console.log("f:clearPreview()");
|
||||||
|
previewCtx.save();
|
||||||
|
previewCtx.clearRect(0,0,canvas.width, canvas.height);
|
||||||
|
previewCtx.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
function oopsUndo() {
|
||||||
|
// console.log("f:oopsUndo()");
|
||||||
|
_points.pop();
|
||||||
|
redrawPreview();
|
||||||
|
clearMainView();
|
||||||
|
prevX = 0;
|
||||||
|
prevY = 0;
|
||||||
|
for (var i = 0; i < _points.length; i++) {
|
||||||
|
// console.log(" drawing points " + _points[i]);
|
||||||
|
if (_points[i][2] == true) {
|
||||||
|
draw(_points[i][0], _points[i][1], 0.5);
|
||||||
|
} else {
|
||||||
|
draw(_points[i][0], _points[i][1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
function previewUp() {
|
||||||
|
// console.log("f:previewUp()");
|
||||||
|
if (numLayers < 100) {
|
||||||
|
numLayers++;
|
||||||
|
}
|
||||||
|
redrawPreview();
|
||||||
|
}
|
||||||
|
function previewDown() {
|
||||||
|
// console.log("f:previewDown()");
|
||||||
|
if (numLayers > 2) {
|
||||||
|
numLayers--;
|
||||||
|
}
|
||||||
|
redrawPreview();
|
||||||
|
}
|
||||||
|
function previewTwistLeft() {
|
||||||
|
// console.log("f:previewTwistLeft()");
|
||||||
|
// if (rStep < Math.PI) {
|
||||||
|
rStep -= twistIncrement;
|
||||||
|
// }
|
||||||
|
redrawPreview();
|
||||||
|
}
|
||||||
|
function previewTwistRight() {
|
||||||
|
// console.log("f:previewTwistRight()");
|
||||||
|
// if (rStep < Math.PI) {
|
||||||
|
rStep += twistIncrement;
|
||||||
|
// }
|
||||||
|
redrawPreview();
|
||||||
|
}
|
361
js/canvasDrawing_v01.js
Normal file
361
js/canvasDrawing_v01.js
Normal file
@ -0,0 +1,361 @@
|
|||||||
|
/* * * * * * * * * *
|
||||||
|
*
|
||||||
|
* VARS
|
||||||
|
*
|
||||||
|
* * * * * * * * * */
|
||||||
|
var preview;
|
||||||
|
var previewCtx;
|
||||||
|
|
||||||
|
var svgPathRegExp = /[LM]\d* \d*/ig;
|
||||||
|
var svgPathParamsRegExp = /([LM])(\d*) (\d*)/;
|
||||||
|
|
||||||
|
var dragging = false;
|
||||||
|
|
||||||
|
var canvas = $("#mycanvas")[0];
|
||||||
|
var ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
var canvasWidth = canvas.width;
|
||||||
|
var canvasHeight = canvas.height;
|
||||||
|
|
||||||
|
var drawCanvas;
|
||||||
|
var drawCanvasTopLeftCoords = [0, 0];
|
||||||
|
|
||||||
|
var doodleBounds = [-1, -1, -1, -1]; // left, top, right, bottom
|
||||||
|
// var doodleScaleVals = [[0, 0], [1.0, 1.0]]; // [ [x, y], [scaleX, scaleY] ]
|
||||||
|
var doodleTransform = [0, 0, 1.0, 1.0]; // [ x, y, scaleX, scaleY ]
|
||||||
|
|
||||||
|
var _points = [];
|
||||||
|
|
||||||
|
var prevCountingTime = 0;
|
||||||
|
var movementCounter = 0;
|
||||||
|
|
||||||
|
var drawVariableLineWeight = false; // set to true to have the momentum of the mouse/touch movement result in larger/smaller strokes
|
||||||
|
var lineweight = 2;
|
||||||
|
|
||||||
|
/* * * * * * * * * *
|
||||||
|
*
|
||||||
|
* INIT
|
||||||
|
*
|
||||||
|
* * * * * * * * * */
|
||||||
|
function initDoodleDrawing() {
|
||||||
|
console.log("f:initDoodleDrawing()");
|
||||||
|
|
||||||
|
if (!canvas.addEventListener) {
|
||||||
|
canvas.attachEvent('onmousedown',onCanvasMouseDown);
|
||||||
|
canvas.attachEvent('onmousemove',onCanvasMouseMove);
|
||||||
|
canvas.attachEvent('onmouseup',onCanvasMouseUp);
|
||||||
|
canvas.attachEvent('ontouchstart',onCanvasTouchDown);
|
||||||
|
canvas.attachEvent('ontouchmove',onCanvasTouchMove);
|
||||||
|
canvas.attachEvent('ontouchend',onCanvasTouchEnd);
|
||||||
|
document.body.attachEvent('ontouchmove',prevent);
|
||||||
|
} else {
|
||||||
|
canvas.addEventListener('mousedown',onCanvasMouseDown,false);
|
||||||
|
canvas.addEventListener('mousemove',onCanvasMouseMove,false);
|
||||||
|
canvas.addEventListener('mouseup',onCanvasMouseUp,false);
|
||||||
|
canvas.addEventListener('touchstart',onCanvasTouchDown,false);
|
||||||
|
canvas.addEventListener('touchmove',onCanvasTouchMove,false);
|
||||||
|
canvas.addEventListener('touchend',onCanvasTouchEnd,false);
|
||||||
|
document.body.addEventListener('touchmove',prevent,false);
|
||||||
|
}
|
||||||
|
|
||||||
|
drawCanvas = $("#drawAreaContainer");
|
||||||
|
|
||||||
|
console.log("drawCanvasTopLeftCoords: " + drawCanvasTopLeftCoords);
|
||||||
|
drawCanvasTopLeftCoords[0] = drawCanvas.css("left").match(/[0-9]/g).join("");
|
||||||
|
drawCanvasTopLeftCoords[1] = drawCanvas.css("top").match(/[0-9]/g).join("");
|
||||||
|
|
||||||
|
console.log("f:initDoodleDrawing() >> canvasWidth: " + canvasWidth);
|
||||||
|
console.log("f:initDoodleDrawing() >> canvasHeight: " + canvasHeight);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* * * * * * * * * *
|
||||||
|
*
|
||||||
|
* CANVAS DRAWING FUNCTION
|
||||||
|
*
|
||||||
|
* * * * * * * * * */
|
||||||
|
function draw(_x, _y, _width) {
|
||||||
|
// console.log("f:draw() >> _width: " + _width);
|
||||||
|
|
||||||
|
if (prevX == 0 && prevY ==0) {
|
||||||
|
prevX = _x;
|
||||||
|
prevY = _y;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(prevX, prevY);
|
||||||
|
ctx.lineTo(_x, _y);
|
||||||
|
|
||||||
|
if (_width != undefined) {
|
||||||
|
ctx.lineWidth = _width;
|
||||||
|
} else {
|
||||||
|
if (drawVariableLineWeight) {
|
||||||
|
var dist = Math.sqrt(Math.pow((prevX - _x), 2) + Math.pow((prevY - _y), 2));
|
||||||
|
if (dist < 10) {
|
||||||
|
lineweight += .25;
|
||||||
|
} else if (dist < 20) {
|
||||||
|
lineweight += .5;
|
||||||
|
} else if (dist < 30) {
|
||||||
|
lineweight += .75;
|
||||||
|
} else if (dist < 50) {
|
||||||
|
lineweight += 1;
|
||||||
|
} else if (dist < 80) {
|
||||||
|
lineweight += 1.5;
|
||||||
|
} else if (dist < 120) {
|
||||||
|
lineweight += 2.25;
|
||||||
|
} else if (dist < 170) {
|
||||||
|
lineweight += 3.5;
|
||||||
|
} else {
|
||||||
|
lineweight += 2;
|
||||||
|
}
|
||||||
|
lineweight = Math.min(lineweight, 30);
|
||||||
|
lineweight *= 0.90;
|
||||||
|
lineweight = Math.max(lineweight, 1.0);
|
||||||
|
} else {
|
||||||
|
lineweight = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.lineWidth = lineweight;
|
||||||
|
}
|
||||||
|
ctx.lineCap = 'round';
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
|
prevX = _x;
|
||||||
|
prevY = _y;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* * * * * * * * * *
|
||||||
|
*
|
||||||
|
* SUPPORTING FUNCTIONS
|
||||||
|
*
|
||||||
|
* * * * * * * * * */
|
||||||
|
function clearDoodle() {
|
||||||
|
console.log("f:clearDoodle");
|
||||||
|
|
||||||
|
_points = [];
|
||||||
|
|
||||||
|
prevX = 0;
|
||||||
|
prevY = 0;
|
||||||
|
|
||||||
|
doodleBounds = [-1, -1, -1, -1]; // left, top, right, bottom
|
||||||
|
doodleTransform = [0, 0, 1.0, 1.0]; // [ x, y, scaleX, scaleY ]
|
||||||
|
|
||||||
|
clearMainView();
|
||||||
|
clearPreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
function adjustBounds(x, y) {
|
||||||
|
// console.log("f:adjustBounds("+x+","+y+")");
|
||||||
|
|
||||||
|
if (doodleBounds[0] == -1) {
|
||||||
|
// if doodleBounds[0] is -1 then it isn't initted yet, so x and y are both the min and max vals
|
||||||
|
|
||||||
|
doodleBounds[0] = x;
|
||||||
|
doodleBounds[1] = y;
|
||||||
|
doodleBounds[2] = x;
|
||||||
|
doodleBounds[3] = y;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
doodleBounds[0] = Math.min(doodleBounds[0], x); // left
|
||||||
|
doodleBounds[2] = Math.max(doodleBounds[2], x); // right
|
||||||
|
|
||||||
|
doodleBounds[1] = Math.min(doodleBounds[1], y); // top
|
||||||
|
doodleBounds[3] = Math.max(doodleBounds[3], y); // bottom
|
||||||
|
|
||||||
|
// draw the bounding rect (DEBUG)
|
||||||
|
/*
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.rect(doodleBounds[0],doodleBounds[1], doodleBounds[2] - doodleBounds[0], doodleBounds[3] - doodleBounds[1]);
|
||||||
|
ctx.lineWidth = .2;
|
||||||
|
ctx.strokeStyle = "#333"
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.closePath();
|
||||||
|
//*/
|
||||||
|
|
||||||
|
// console.log(" new bounds: " + doodleBounds);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// does what exactly?
|
||||||
|
function adjustPreviewTransformation() {
|
||||||
|
// console.log("f:adjustPreviewTransformation()");
|
||||||
|
|
||||||
|
// doodleTransform[0] = doodleBounds[0] - (doodleBounds[2] - doodleBounds[0]) / 2;
|
||||||
|
// doodleTransform[1] = doodleBounds[1] - (doodleBounds[3] - doodleBounds[1]) / 2;
|
||||||
|
// doodleTransform[0] = doodleBounds[0] - ((doodleBounds[2] - doodleBounds[0]) / 2);
|
||||||
|
// doodleTransform[1] = doodleBounds[1] - ((doodleBounds[3] - doodleBounds[1]) / 2);
|
||||||
|
doodleTransform[0] = doodleBounds[0];
|
||||||
|
doodleTransform[1] = doodleBounds[1];
|
||||||
|
|
||||||
|
var sclX, sclY, finalScl;
|
||||||
|
if (_points.length < 2) {
|
||||||
|
console.log(_points);
|
||||||
|
sclX = 1.0;
|
||||||
|
sclY = 1.0;
|
||||||
|
finalScl = Math.min(sclX, sclY);
|
||||||
|
} else {
|
||||||
|
sclX = canvasWidth / (doodleBounds[2] - doodleBounds[0]);
|
||||||
|
sclY = canvasHeight / (doodleBounds[3] - doodleBounds[1]);
|
||||||
|
|
||||||
|
// TODO this shouldn't be a matter if choosing the smallest but should probably involve maintaining aspect ratio??
|
||||||
|
finalScl = Math.min(sclX, sclY);
|
||||||
|
}
|
||||||
|
|
||||||
|
doodleTransform[2] = finalScl;
|
||||||
|
doodleTransform[3] = finalScl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* * * * * * * * * *
|
||||||
|
*
|
||||||
|
* MOUSE/TOUCH EVENTHANDLERS
|
||||||
|
*
|
||||||
|
* * * * * * * * * */
|
||||||
|
function onCanvasMouseDown(e) {
|
||||||
|
// console.log("onmousedown");
|
||||||
|
dragging = true;
|
||||||
|
|
||||||
|
prevCountingTime = new Date().getTime();
|
||||||
|
movementCounter = 0
|
||||||
|
|
||||||
|
// _points.push([e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop, true]);
|
||||||
|
// adjustBounds(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop);
|
||||||
|
// adjustPreviewTransformation();
|
||||||
|
// draw(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop, 0.5);
|
||||||
|
_points.push([e.offsetX,e.offsetY, true]);
|
||||||
|
adjustBounds(e.offsetX,e.offsetY);
|
||||||
|
adjustPreviewTransformation();
|
||||||
|
draw(e.offsetX,e.offsetY, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onCanvasMouseMove(e) {
|
||||||
|
if (!dragging) return;
|
||||||
|
// console.log("onmousemove");
|
||||||
|
|
||||||
|
// _points.push([e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop, false]);
|
||||||
|
// adjustBounds(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop);
|
||||||
|
// adjustPreviewTransformation();
|
||||||
|
// draw(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop);
|
||||||
|
|
||||||
|
_points.push([e.offsetX,e.offsetY, false]);
|
||||||
|
adjustBounds(e.offsetX,e.offsetY);
|
||||||
|
adjustPreviewTransformation();
|
||||||
|
draw(e.offsetX,e.offsetY);
|
||||||
|
|
||||||
|
// update counter -> this was for getting a handle on how often the Canvas fires a move-event
|
||||||
|
/*
|
||||||
|
movementCounter++;
|
||||||
|
if (new Date().getTime() - prevCountingTime > 1000) {
|
||||||
|
// console.log("number of moves in 1sec: " + movementCounter)
|
||||||
|
prevCountingTime= new Date().getTime();
|
||||||
|
$("#numtimes").text(movementCounter + " times");
|
||||||
|
movementCounter = 0;
|
||||||
|
}
|
||||||
|
//*/
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
// $("#textdump").text("");
|
||||||
|
// $("#textdump").append("doodlebounds:" + doodleBounds + "\n");
|
||||||
|
// $("#textdump").append("doodletransform:" + doodleTransform + "\n");
|
||||||
|
|
||||||
|
if (new Date().getTime() - prevRedrawTime > redrawInterval) {
|
||||||
|
redrawPreview();
|
||||||
|
prevRedrawTime = new Date().getTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onCanvasMouseUp(e) {
|
||||||
|
// console.log("onmouseup");
|
||||||
|
dragging = false;
|
||||||
|
console.log("doodleBounds: " + doodleBounds);
|
||||||
|
console.log("doodleTransform: " + doodleTransform);
|
||||||
|
// ctx.stroke();
|
||||||
|
|
||||||
|
console.log("_points.length :" + _points.length);
|
||||||
|
// console.log(_points);
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
// $("#textdump").text("");
|
||||||
|
// $("#textdump").append("doodlebounds:" + doodleBounds + "\n");
|
||||||
|
// $("#textdump").append("doodletransform:" + doodleTransform + "\n");
|
||||||
|
|
||||||
|
redrawPreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onCanvasTouchDown(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
// var x = e.touches[0].pageX - e.touches[0].target.offsetLeft;
|
||||||
|
// var y = e.touches[0].pageY - e.touches[0].target.offsetTop;
|
||||||
|
var x = e.touches[0].pageX - drawCanvasTopLeftCoords[0];
|
||||||
|
var y = e.touches[0].pageY - drawCanvasTopLeftCoords[1];
|
||||||
|
|
||||||
|
_points.push([x, y, true]);
|
||||||
|
adjustBounds(x, y);
|
||||||
|
adjustPreviewTransformation();
|
||||||
|
draw(x, y, .5);
|
||||||
|
|
||||||
|
movementCounter = 0;
|
||||||
|
|
||||||
|
prevRedrawTime = new Date().getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onCanvasTouchMove(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
// var x = e.touches[0].pageX - e.touches[0].target.offsetLeft;
|
||||||
|
// var y = e.touches[0].pageY - e.touches[0].target.offsetTop;
|
||||||
|
var x = e.touches[0].pageX - drawCanvasTopLeftCoords[0];
|
||||||
|
var y = e.touches[0].pageY - drawCanvasTopLeftCoords[1];
|
||||||
|
|
||||||
|
_points.push([x, y, false]);
|
||||||
|
adjustBounds(x, y);
|
||||||
|
adjustPreviewTransformation();
|
||||||
|
draw(x, y);
|
||||||
|
|
||||||
|
|
||||||
|
// update counter -> this was for getting a handle on how often the Canvas fires a move-event
|
||||||
|
/*
|
||||||
|
movementCounter++;
|
||||||
|
if (new Date().getTime() - prevCountingTime > 1000) {
|
||||||
|
// console.log("number of moves in 1sec: " + movementCounter)
|
||||||
|
prevCountingTime= new Date().getTime();
|
||||||
|
$("#numtimes").text(movementCounter + " times");
|
||||||
|
movementCounter = 0;
|
||||||
|
}
|
||||||
|
//*/
|
||||||
|
|
||||||
|
if (new Date().getTime() - prevRedrawTime > redrawInterval) {
|
||||||
|
redrawPreview();
|
||||||
|
prevRedrawTime = new Date().getTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onCanvasTouchEnd(e) {
|
||||||
|
// console.log("ontouchend");
|
||||||
|
redrawPreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
function prevent(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
function print(e) {
|
||||||
|
|
||||||
|
output = path.attributes.d.nodeValue;
|
||||||
|
console.log(output);
|
||||||
|
|
||||||
|
output = output.split("M").join("\n");
|
||||||
|
output = output.split(" L").join("_");
|
||||||
|
output = output.split(" ").join(",");
|
||||||
|
output = output.split("_").join(" ");
|
||||||
|
|
||||||
|
output = "\nBEGIN\n" + output + "\n\nEND\n";
|
||||||
|
|
||||||
|
$.post("/doodle3d.of", { data:output }, function(data) {
|
||||||
|
btnPrint.disabled = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//*/
|
10
js/d3dServerInterfacing.js
vendored
Normal file
10
js/d3dServerInterfacing.js
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
function setTemperature(callback) {
|
||||||
|
|
||||||
|
if (callback != undefined) callback();
|
||||||
|
|
||||||
|
}
|
||||||
|
function setTemperature(callback) {
|
||||||
|
|
||||||
|
if (callback != undefined) callback();
|
||||||
|
|
||||||
|
}
|
66
js/doodlePrintCode.js
Normal file
66
js/doodlePrintCode.js
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
var sendIndex;
|
||||||
|
var sendLength;
|
||||||
|
|
||||||
|
//var kastjeURL = "http://192.168.10.1/cgi-bin/d3dapi/";
|
||||||
|
var kastjeURL = "http://192.168.5.1/cgi-bin/d3dapi/";
|
||||||
|
|
||||||
|
|
||||||
|
var mydata = "";
|
||||||
|
function startPrint() {
|
||||||
|
console.log("f:startPrint()");
|
||||||
|
|
||||||
|
// sendIndex = 0;
|
||||||
|
// sendLength = 2000; // 2000 regels
|
||||||
|
// sendGCodeSlice(sendIndex, sendLength);
|
||||||
|
|
||||||
|
$.post(kastjeURL + "test/" + "write/", { data: "test"}, function(data) {
|
||||||
|
console.log("returned data: " + JSON.stringify(data));
|
||||||
|
data = JSON.parse(data);
|
||||||
|
console.log(" data.msg: " + data.msg);
|
||||||
|
console.log(" data.status: " + data.status);
|
||||||
|
// console.log(" status: " + data["status"]);
|
||||||
|
// btnPrint.disabled = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
//http://192.168.10.1/cgi-bin/d3dapi/write
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function sendGCodeSlice(startIndex, sendAmt) {
|
||||||
|
console.log("f:senGCodeSlice >> startIndex:" + startIndex + ", sendAmt:" + sendAmt);
|
||||||
|
|
||||||
|
if (typeof startIndex == "number" && typeof sendAmt == "number") {
|
||||||
|
var lastOne = false;
|
||||||
|
if (data.length < (startIndex + sendAmt)) {
|
||||||
|
console.log("f:senGCodeSlice >> not enough data left for full slice, sending smaller (and last) one");
|
||||||
|
sendAmt = data.length - startIndex;
|
||||||
|
lastOne = true;
|
||||||
|
}
|
||||||
|
var _tmp = data.slice(startIndex, startIndex+sendAmt);
|
||||||
|
// console.log("f:senGCodeSlice >> _tmp.length:" + _tmp.length);
|
||||||
|
|
||||||
|
$.post("/doodle3d.of", { data:output }, function(data) {
|
||||||
|
btnPrint.disabled = false;
|
||||||
|
});
|
||||||
|
sendBoy( { data: _tmp, lastOne: lastOne} , function(e) {
|
||||||
|
console.log("sendBoy callback: " + e);
|
||||||
|
// console.log(e);
|
||||||
|
// console.log("e.success: " + e.success);
|
||||||
|
if (e.success = true) {
|
||||||
|
if (lastOne) {
|
||||||
|
console.log("f:sendGCodeSlice >> DONE!");
|
||||||
|
} else {
|
||||||
|
sendGCodeSlice(startIndex + sendAmt, sendAmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
console.log(" something wrong");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendBoy(sendObj, callback) {
|
||||||
|
console.log("f:sendBoy() (dummy kastje) >> data length: " + sendObj.data.length + ", lastOne: " + sendObj.lastOne);
|
||||||
|
console.log("");
|
||||||
|
if (callback != undefined) callback({success:true});
|
||||||
|
}
|
@ -123,6 +123,8 @@ function print(e) {
|
|||||||
|
|
||||||
output = "\nBEGIN\n" + output + "\n\nEND\n";
|
output = "\nBEGIN\n" + output + "\n\nEND\n";
|
||||||
|
|
||||||
|
console.log("output :" + output );
|
||||||
|
|
||||||
$.post("/doodle3d.of", { data:output }, function(data) {
|
$.post("/doodle3d.of", { data:output }, function(data) {
|
||||||
btnPrint.disabled = false;
|
btnPrint.disabled = false;
|
||||||
});
|
});
|
||||||
|
214
js/gcodeGenerating_v01.js
Normal file
214
js/gcodeGenerating_v01.js
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
var gcodeStart = [];
|
||||||
|
gcodeStart.push("G21 (mm)");
|
||||||
|
gcodeStart.push("G91 (relative)");
|
||||||
|
gcodeStart.push("G28 X0 Y0 Z0 (physical home)");
|
||||||
|
gcodeStart.push("M104 S230 (temperature)");
|
||||||
|
gcodeStart.push("G1 E10 F250 (flow)");
|
||||||
|
gcodeStart.push("G92 X-100 Y-100 Z0 E10");
|
||||||
|
gcodeStart.push("G1 Z3 F5000 (prevent diagonal line)");
|
||||||
|
gcodeStart.push("G90 (absolute)");
|
||||||
|
gcodeStart.push("M106 (fan on)");
|
||||||
|
|
||||||
|
var gcodeEnd= [];
|
||||||
|
gcodeEnd.push("G1 X-100 Y-100 F15000 (fast homing)");
|
||||||
|
gcodeEnd.push("M107");
|
||||||
|
gcodeEnd.push("M84 (disable axes)");
|
||||||
|
|
||||||
|
var gcode = [];
|
||||||
|
function generate_gcode(callback) {
|
||||||
|
console.log("f:generategcode()");
|
||||||
|
|
||||||
|
gcode = [];
|
||||||
|
|
||||||
|
objectHeight = Math.ceil(numLayers / 5); // in settings objectHeight = 20, in previewRendering_v01.js numLayers is 100, hence the / 5
|
||||||
|
objectHeight = numLayers; // in settings objectHeight = 20, in previewRendering_v01.js numLayers is 100, hence the / 5
|
||||||
|
|
||||||
|
// todo hier een array van PATHS maken wat de losse paths zijn
|
||||||
|
|
||||||
|
// copy array without reference -> http://stackoverflow.com/questions/9885821/copying-of-an-array-of-objects-to-another-array-without-object-reference-in-java
|
||||||
|
var points = JSON.parse(JSON.stringify(_points));
|
||||||
|
console.log("f:generategcode() >> points.length: " + points.length);
|
||||||
|
|
||||||
|
// console.log("f:generategcode() >> paths: " + paths.toString());
|
||||||
|
// console.log("paths.toString(): " + paths.toString());
|
||||||
|
// return;
|
||||||
|
|
||||||
|
|
||||||
|
// add gcode begin commands
|
||||||
|
gcode = gcode.concat(gcodeStart);
|
||||||
|
|
||||||
|
var layers = maxObjectHeight / layerHeight; //maxObjectHeight instead of objectHeight
|
||||||
|
var extruder = 0.0;
|
||||||
|
var prev = new Point(); prev.set(0, 0);
|
||||||
|
|
||||||
|
// vervanger voor ofxGetCenterofMass
|
||||||
|
var centerOfDoodle = {
|
||||||
|
x: doodleBounds[0] + (doodleBounds[2]- doodleBounds[0])/2,
|
||||||
|
y: doodleBounds[1] + (doodleBounds[3] - doodleBounds[1])/2
|
||||||
|
// x: doodleBounds[0],
|
||||||
|
// y: doodleBounds[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("f:generategcode() >> layers: " + layers);
|
||||||
|
for (var layer = 0; layer < layers; layer++) {
|
||||||
|
|
||||||
|
var p = JSON.parse(JSON.stringify(points)); // [].concat(points);
|
||||||
|
|
||||||
|
if (p.length < 2) return;
|
||||||
|
var even = (layer % 2 == 0);
|
||||||
|
var progress = layer / layers;
|
||||||
|
|
||||||
|
// float layerScale = scaleFunction(float(layer)/layers); // scaleFactor van de layer -> lookup naar vfunc[] voor die scaleVals
|
||||||
|
var layerScale = 1.0;
|
||||||
|
|
||||||
|
// if begin point this row and end point last row are close enough, isLoop is true
|
||||||
|
var isLoop = lineLength(points[0][0], points[0][1], points[points.length-1][0], points[points.length-1][1]) < 3;
|
||||||
|
|
||||||
|
// set center of doodle as middle (ie subtract to that)
|
||||||
|
pointsTranslate(p, -centerOfDoodle.x, -centerOfDoodle.y);
|
||||||
|
pointsScale(p, screenToMillimeterScale,-screenToMillimeterScale);
|
||||||
|
pointsScale(p, layerScale, layerScale);
|
||||||
|
|
||||||
|
// sort-of in de buurt van (360/2.5)
|
||||||
|
// // -> aight.. er zijn 750 lines vs 1000 in de d3d app. 135 = .75 * 180... dit kan je nog rechttrekken als je NET wat slimmer nadenkt :)
|
||||||
|
// update: NEE, het is niet .75 * 180 want 135 was niet de beste value. //TODO dus.
|
||||||
|
pointsRotate(p, rStep * progress * 139);
|
||||||
|
|
||||||
|
if (layer == 0) {
|
||||||
|
gcode.push("M107"); //fan off
|
||||||
|
if (firstLayerSlow) gcode.push("M220 S40"); //slow speed
|
||||||
|
} else if (layer == 2) { ////////LET OP
|
||||||
|
gcode.push("M106"); //fan on
|
||||||
|
gcode.push("M220 S100"); //normal speed
|
||||||
|
}
|
||||||
|
|
||||||
|
var curLayerCommand = 0;
|
||||||
|
var totalLayerCommands = p.length;
|
||||||
|
|
||||||
|
var paths = [];
|
||||||
|
var pathCounter = -1;
|
||||||
|
// var points = [];
|
||||||
|
|
||||||
|
for (var i = 0; i < p.length; i++) {
|
||||||
|
if (p[i][2] == true) {
|
||||||
|
pathCounter++;
|
||||||
|
paths.push([]);
|
||||||
|
paths[pathCounter].push([p[i][0], p[i][1]]);
|
||||||
|
} else {
|
||||||
|
paths[pathCounter].push([p[i][0], p[i][1]]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// console.log("f:generategcode() >> paths.length: " + paths.length);
|
||||||
|
|
||||||
|
// loop over the subpaths (the separately drawn lines)
|
||||||
|
for (var j = 0; j < paths.length; j++) {
|
||||||
|
// this line is probably for drawing efficiency, alternating going from 0->end and end->0 (i.e. to and fro)
|
||||||
|
// vector<ofSubPath::Command> &commands = subpaths[even ? j : subpaths.size()-1-j].getCommands();
|
||||||
|
var commands = paths[j];
|
||||||
|
|
||||||
|
// loop over the coordinates of the subpath
|
||||||
|
for (var i = 0; i < commands.length; i++) {
|
||||||
|
var last = commands.length - 1;
|
||||||
|
|
||||||
|
// this line is probably for drawing efficiency, alternating going from 0->end and end->0 (i.e. to and fro)
|
||||||
|
// ofPoint to = commands[(even || isLoop || loopAlways) ? i : last-i].to;
|
||||||
|
var to = new Point(); to.set(commands[i][0], commands[i][1]);
|
||||||
|
var sublayer = (layer == 0) ? 0.0 : layer + (useSubLayers ? (curLayerCommand/totalLayerCommands) : 0);
|
||||||
|
var z = (sublayer + 1) * layerHeight + zOffset;
|
||||||
|
|
||||||
|
var isTraveling = !isLoop && i==0;
|
||||||
|
var doRetract = prev.distance(to) > retractionminDistance;
|
||||||
|
|
||||||
|
if (enableTraveling && isTraveling) {
|
||||||
|
// console.log("enableTraveling && isTraveling >> doRetract: " + doRetract + ", retractionspeed: " + retractionspeed);
|
||||||
|
if (doRetract) gcode.push("G1 E" + (extruder - retractionamount).toFixed(3) + " F" + (retractionspeed * 60).toFixed(3));
|
||||||
|
gcode.push("G1 X" + to.x.toFixed(3) + " Y" + to.y.toFixed(3) + " Z" + (z + (doRetract ? hop : 0)).toFixed(3) + " F" + (travelSpeed * 60).toFixed(3));
|
||||||
|
if (doRetract) gcode.push("G1 E" + extruder.toFixed(3) + " F" + (retractionspeed * 60).toFixed(3));
|
||||||
|
} else {
|
||||||
|
// console.log(" else");
|
||||||
|
extruder += prev.distance(to) * wallThickness * layerHeight / filamentThickness;
|
||||||
|
gcode.push("G1 X" + to.x.toFixed(3) + " Y" + to.y.toFixed(3) + " Z" + z.toFixed(3) + " F" + (speed * 60).toFixed(3) + " E" + extruder.toFixed(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
curLayerCommand++;
|
||||||
|
prev = to;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((layer/layers) > (objectHeight/maxObjectHeight)) {
|
||||||
|
console.log("f:generategcode() >> (layer/layers) > (objectHeight/maxObjectHeight) is true -> breaking");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// add gcode end commands
|
||||||
|
gcode = gcode.concat(gcodeEnd);
|
||||||
|
|
||||||
|
// debug
|
||||||
|
// var _gc = gc.join("\n");
|
||||||
|
// console.log("f:generategcode() >> _gc = " + _gc);
|
||||||
|
|
||||||
|
// Return the gcode array, joined to one string with '\n' (line break) as the join parameter
|
||||||
|
// This should result in a nice long string with line breaks
|
||||||
|
if (callback == undefined) {
|
||||||
|
return gcode.join("\n");
|
||||||
|
} else {
|
||||||
|
// post
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pointsTranslate = function(p, x, y) {
|
||||||
|
for (var i = 0; i < p.length; i++) {
|
||||||
|
p[i][0] += x;
|
||||||
|
p[i][1] += y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pointsScale = function(p, sx, sy) {
|
||||||
|
for (var i = 0; i < p.length; i++) {
|
||||||
|
p[i][0] *= sx;
|
||||||
|
p[i][1] *= sy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// rotates around point 0,0 (origin).
|
||||||
|
// Not the prettiest kind of rotation solution but in our case we're assuming that the points have just been translated to origin
|
||||||
|
pointsRotate = function(p, ang) {
|
||||||
|
var _ang, dist;
|
||||||
|
for (var i = 0; i < p.length; i++) {
|
||||||
|
dist = Math.sqrt(p[i][0] * p[i][0] + p[i][1] * p[i][1]);
|
||||||
|
_ang = Math.atan2(p[i][1], p[i][0]);
|
||||||
|
p[i][0] = Math.cos(_ang + ang) * dist;
|
||||||
|
p[i][1] = Math.sin(_ang + ang) * dist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//+ Jonas Raoni Soares Silva
|
||||||
|
//@ http://jsfromhell.com/math/line-length [rev. #1]
|
||||||
|
lineLength = function(x, y, x0, y0){
|
||||||
|
return Math.sqrt((x -= x0) * x + (y -= y0) * y);
|
||||||
|
};
|
||||||
|
|
||||||
|
var Point = function() {};
|
||||||
|
Point.prototype = {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
set: function(_x, _y) {
|
||||||
|
this.x = _x;
|
||||||
|
this.y = _y;
|
||||||
|
},
|
||||||
|
distance: function(p) {
|
||||||
|
var d = -1;
|
||||||
|
if (p instanceof Point) {
|
||||||
|
d = Math.sqrt((p.x - this.x) * (p.x - this.x) + (p.y - this.y) * (p.y - this.y));
|
||||||
|
}
|
||||||
|
return d;
|
||||||
|
},
|
||||||
|
toString: function() {
|
||||||
|
console.log("x:" + this.x + ", y:" + this.y);
|
||||||
|
}
|
||||||
|
}
|
2280
js/libs/bootstrap.js
vendored
Normal file
2280
js/libs/bootstrap.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6
js/libs/bootstrap.min.js
vendored
Normal file
6
js/libs/bootstrap.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
35
js/libs/excanvas.compiled.js
Normal file
35
js/libs/excanvas.compiled.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// Copyright 2006 Google Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
document.createElement("canvas").getContext||(function(){var s=Math,j=s.round,F=s.sin,G=s.cos,V=s.abs,W=s.sqrt,k=10,v=k/2;function X(){return this.context_||(this.context_=new H(this))}var L=Array.prototype.slice;function Y(b,a){var c=L.call(arguments,2);return function(){return b.apply(a,c.concat(L.call(arguments)))}}var M={init:function(b){if(/MSIE/.test(navigator.userAgent)&&!window.opera){var a=b||document;a.createElement("canvas");a.attachEvent("onreadystatechange",Y(this.init_,this,a))}},init_:function(b){b.namespaces.g_vml_||
|
||||||
|
b.namespaces.add("g_vml_","urn:schemas-microsoft-com:vml","#default#VML");b.namespaces.g_o_||b.namespaces.add("g_o_","urn:schemas-microsoft-com:office:office","#default#VML");if(!b.styleSheets.ex_canvas_){var a=b.createStyleSheet();a.owningElement.id="ex_canvas_";a.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}g_vml_\\:*{behavior:url(#default#VML)}g_o_\\:*{behavior:url(#default#VML)}"}var c=b.getElementsByTagName("canvas"),d=0;for(;d<c.length;d++)this.initElement(c[d])},
|
||||||
|
initElement:function(b){if(!b.getContext){b.getContext=X;b.innerHTML="";b.attachEvent("onpropertychange",Z);b.attachEvent("onresize",$);var a=b.attributes;if(a.width&&a.width.specified)b.style.width=a.width.nodeValue+"px";else b.width=b.clientWidth;if(a.height&&a.height.specified)b.style.height=a.height.nodeValue+"px";else b.height=b.clientHeight}return b}};function Z(b){var a=b.srcElement;switch(b.propertyName){case "width":a.style.width=a.attributes.width.nodeValue+"px";a.getContext().clearRect();
|
||||||
|
break;case "height":a.style.height=a.attributes.height.nodeValue+"px";a.getContext().clearRect();break}}function $(b){var a=b.srcElement;if(a.firstChild){a.firstChild.style.width=a.clientWidth+"px";a.firstChild.style.height=a.clientHeight+"px"}}M.init();var N=[],B=0;for(;B<16;B++){var C=0;for(;C<16;C++)N[B*16+C]=B.toString(16)+C.toString(16)}function I(){return[[1,0,0],[0,1,0],[0,0,1]]}function y(b,a){var c=I(),d=0;for(;d<3;d++){var f=0;for(;f<3;f++){var h=0,g=0;for(;g<3;g++)h+=b[d][g]*a[g][f];c[d][f]=
|
||||||
|
h}}return c}function O(b,a){a.fillStyle=b.fillStyle;a.lineCap=b.lineCap;a.lineJoin=b.lineJoin;a.lineWidth=b.lineWidth;a.miterLimit=b.miterLimit;a.shadowBlur=b.shadowBlur;a.shadowColor=b.shadowColor;a.shadowOffsetX=b.shadowOffsetX;a.shadowOffsetY=b.shadowOffsetY;a.strokeStyle=b.strokeStyle;a.globalAlpha=b.globalAlpha;a.arcScaleX_=b.arcScaleX_;a.arcScaleY_=b.arcScaleY_;a.lineScale_=b.lineScale_}function P(b){var a,c=1;b=String(b);if(b.substring(0,3)=="rgb"){var d=b.indexOf("(",3),f=b.indexOf(")",d+
|
||||||
|
1),h=b.substring(d+1,f).split(",");a="#";var g=0;for(;g<3;g++)a+=N[Number(h[g])];if(h.length==4&&b.substr(3,1)=="a")c=h[3]}else a=b;return{color:a,alpha:c}}function aa(b){switch(b){case "butt":return"flat";case "round":return"round";case "square":default:return"square"}}function H(b){this.m_=I();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.fillStyle=this.strokeStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=k*1;this.globalAlpha=1;this.canvas=b;
|
||||||
|
var a=b.ownerDocument.createElement("div");a.style.width=b.clientWidth+"px";a.style.height=b.clientHeight+"px";a.style.overflow="hidden";a.style.position="absolute";b.appendChild(a);this.element_=a;this.lineScale_=this.arcScaleY_=this.arcScaleX_=1}var i=H.prototype;i.clearRect=function(){this.element_.innerHTML=""};i.beginPath=function(){this.currentPath_=[]};i.moveTo=function(b,a){var c=this.getCoords_(b,a);this.currentPath_.push({type:"moveTo",x:c.x,y:c.y});this.currentX_=c.x;this.currentY_=c.y};
|
||||||
|
i.lineTo=function(b,a){var c=this.getCoords_(b,a);this.currentPath_.push({type:"lineTo",x:c.x,y:c.y});this.currentX_=c.x;this.currentY_=c.y};i.bezierCurveTo=function(b,a,c,d,f,h){var g=this.getCoords_(f,h),l=this.getCoords_(b,a),e=this.getCoords_(c,d);Q(this,l,e,g)};function Q(b,a,c,d){b.currentPath_.push({type:"bezierCurveTo",cp1x:a.x,cp1y:a.y,cp2x:c.x,cp2y:c.y,x:d.x,y:d.y});b.currentX_=d.x;b.currentY_=d.y}i.quadraticCurveTo=function(b,a,c,d){var f=this.getCoords_(b,a),h=this.getCoords_(c,d),g={x:this.currentX_+
|
||||||
|
0.6666666666666666*(f.x-this.currentX_),y:this.currentY_+0.6666666666666666*(f.y-this.currentY_)};Q(this,g,{x:g.x+(h.x-this.currentX_)/3,y:g.y+(h.y-this.currentY_)/3},h)};i.arc=function(b,a,c,d,f,h){c*=k;var g=h?"at":"wa",l=b+G(d)*c-v,e=a+F(d)*c-v,m=b+G(f)*c-v,r=a+F(f)*c-v;if(l==m&&!h)l+=0.125;var n=this.getCoords_(b,a),o=this.getCoords_(l,e),q=this.getCoords_(m,r);this.currentPath_.push({type:g,x:n.x,y:n.y,radius:c,xStart:o.x,yStart:o.y,xEnd:q.x,yEnd:q.y})};i.rect=function(b,a,c,d){this.moveTo(b,
|
||||||
|
a);this.lineTo(b+c,a);this.lineTo(b+c,a+d);this.lineTo(b,a+d);this.closePath()};i.strokeRect=function(b,a,c,d){var f=this.currentPath_;this.beginPath();this.moveTo(b,a);this.lineTo(b+c,a);this.lineTo(b+c,a+d);this.lineTo(b,a+d);this.closePath();this.stroke();this.currentPath_=f};i.fillRect=function(b,a,c,d){var f=this.currentPath_;this.beginPath();this.moveTo(b,a);this.lineTo(b+c,a);this.lineTo(b+c,a+d);this.lineTo(b,a+d);this.closePath();this.fill();this.currentPath_=f};i.createLinearGradient=function(b,
|
||||||
|
a,c,d){var f=new D("gradient");f.x0_=b;f.y0_=a;f.x1_=c;f.y1_=d;return f};i.createRadialGradient=function(b,a,c,d,f,h){var g=new D("gradientradial");g.x0_=b;g.y0_=a;g.r0_=c;g.x1_=d;g.y1_=f;g.r1_=h;return g};i.drawImage=function(b){var a,c,d,f,h,g,l,e,m=b.runtimeStyle.width,r=b.runtimeStyle.height;b.runtimeStyle.width="auto";b.runtimeStyle.height="auto";var n=b.width,o=b.height;b.runtimeStyle.width=m;b.runtimeStyle.height=r;if(arguments.length==3){a=arguments[1];c=arguments[2];h=g=0;l=d=n;e=f=o}else if(arguments.length==
|
||||||
|
5){a=arguments[1];c=arguments[2];d=arguments[3];f=arguments[4];h=g=0;l=n;e=o}else if(arguments.length==9){h=arguments[1];g=arguments[2];l=arguments[3];e=arguments[4];a=arguments[5];c=arguments[6];d=arguments[7];f=arguments[8]}else throw Error("Invalid number of arguments");var q=this.getCoords_(a,c),t=[];t.push(" <g_vml_:group",' coordsize="',k*10,",",k*10,'"',' coordorigin="0,0"',' style="width:',10,"px;height:",10,"px;position:absolute;");if(this.m_[0][0]!=1||this.m_[0][1]){var E=[];E.push("M11=",
|
||||||
|
this.m_[0][0],",","M12=",this.m_[1][0],",","M21=",this.m_[0][1],",","M22=",this.m_[1][1],",","Dx=",j(q.x/k),",","Dy=",j(q.y/k),"");var p=q,z=this.getCoords_(a+d,c),w=this.getCoords_(a,c+f),x=this.getCoords_(a+d,c+f);p.x=s.max(p.x,z.x,w.x,x.x);p.y=s.max(p.y,z.y,w.y,x.y);t.push("padding:0 ",j(p.x/k),"px ",j(p.y/k),"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",E.join(""),", sizingmethod='clip');")}else t.push("top:",j(q.y/k),"px;left:",j(q.x/k),"px;");t.push(' ">','<g_vml_:image src="',b.src,
|
||||||
|
'"',' style="width:',k*d,"px;"," height:",k*f,'px;"',' cropleft="',h/n,'"',' croptop="',g/o,'"',' cropright="',(n-h-l)/n,'"',' cropbottom="',(o-g-e)/o,'"'," />","</g_vml_:group>");this.element_.insertAdjacentHTML("BeforeEnd",t.join(""))};i.stroke=function(b){var a=[],c=P(b?this.fillStyle:this.strokeStyle),d=c.color,f=c.alpha*this.globalAlpha;a.push("<g_vml_:shape",' filled="',!!b,'"',' style="position:absolute;width:',10,"px;height:",10,'px;"',' coordorigin="0 0" coordsize="',k*10," ",k*10,'"',' stroked="',
|
||||||
|
!b,'"',' path="');var h={x:null,y:null},g={x:null,y:null},l=0;for(;l<this.currentPath_.length;l++){var e=this.currentPath_[l];switch(e.type){case "moveTo":a.push(" m ",j(e.x),",",j(e.y));break;case "lineTo":a.push(" l ",j(e.x),",",j(e.y));break;case "close":a.push(" x ");e=null;break;case "bezierCurveTo":a.push(" c ",j(e.cp1x),",",j(e.cp1y),",",j(e.cp2x),",",j(e.cp2y),",",j(e.x),",",j(e.y));break;case "at":case "wa":a.push(" ",e.type," ",j(e.x-this.arcScaleX_*e.radius),",",j(e.y-this.arcScaleY_*e.radius),
|
||||||
|
" ",j(e.x+this.arcScaleX_*e.radius),",",j(e.y+this.arcScaleY_*e.radius)," ",j(e.xStart),",",j(e.yStart)," ",j(e.xEnd),",",j(e.yEnd));break}if(e){if(h.x==null||e.x<h.x)h.x=e.x;if(g.x==null||e.x>g.x)g.x=e.x;if(h.y==null||e.y<h.y)h.y=e.y;if(g.y==null||e.y>g.y)g.y=e.y}}a.push(' ">');if(b)if(typeof this.fillStyle=="object"){var m=this.fillStyle,r=0,n={x:0,y:0},o=0,q=1;if(m.type_=="gradient"){var t=m.x1_/this.arcScaleX_,E=m.y1_/this.arcScaleY_,p=this.getCoords_(m.x0_/this.arcScaleX_,m.y0_/this.arcScaleY_),
|
||||||
|
z=this.getCoords_(t,E);r=Math.atan2(z.x-p.x,z.y-p.y)*180/Math.PI;if(r<0)r+=360;if(r<1.0E-6)r=0}else{var p=this.getCoords_(m.x0_,m.y0_),w=g.x-h.x,x=g.y-h.y;n={x:(p.x-h.x)/w,y:(p.y-h.y)/x};w/=this.arcScaleX_*k;x/=this.arcScaleY_*k;var R=s.max(w,x);o=2*m.r0_/R;q=2*m.r1_/R-o}var u=m.colors_;u.sort(function(ba,ca){return ba.offset-ca.offset});var J=u.length,da=u[0].color,ea=u[J-1].color,fa=u[0].alpha*this.globalAlpha,ga=u[J-1].alpha*this.globalAlpha,S=[],l=0;for(;l<J;l++){var T=u[l];S.push(T.offset*q+
|
||||||
|
o+" "+T.color)}a.push('<g_vml_:fill type="',m.type_,'"',' method="none" focus="100%"',' color="',da,'"',' color2="',ea,'"',' colors="',S.join(","),'"',' opacity="',ga,'"',' g_o_:opacity2="',fa,'"',' angle="',r,'"',' focusposition="',n.x,",",n.y,'" />')}else a.push('<g_vml_:fill color="',d,'" opacity="',f,'" />');else{var K=this.lineScale_*this.lineWidth;if(K<1)f*=K;a.push("<g_vml_:stroke",' opacity="',f,'"',' joinstyle="',this.lineJoin,'"',' miterlimit="',this.miterLimit,'"',' endcap="',aa(this.lineCap),
|
||||||
|
'"',' weight="',K,'px"',' color="',d,'" />')}a.push("</g_vml_:shape>");this.element_.insertAdjacentHTML("beforeEnd",a.join(""))};i.fill=function(){this.stroke(true)};i.closePath=function(){this.currentPath_.push({type:"close"})};i.getCoords_=function(b,a){var c=this.m_;return{x:k*(b*c[0][0]+a*c[1][0]+c[2][0])-v,y:k*(b*c[0][1]+a*c[1][1]+c[2][1])-v}};i.save=function(){var b={};O(this,b);this.aStack_.push(b);this.mStack_.push(this.m_);this.m_=y(I(),this.m_)};i.restore=function(){O(this.aStack_.pop(),
|
||||||
|
this);this.m_=this.mStack_.pop()};function ha(b){var a=0;for(;a<3;a++){var c=0;for(;c<2;c++)if(!isFinite(b[a][c])||isNaN(b[a][c]))return false}return true}function A(b,a,c){if(!!ha(a)){b.m_=a;if(c)b.lineScale_=W(V(a[0][0]*a[1][1]-a[0][1]*a[1][0]))}}i.translate=function(b,a){A(this,y([[1,0,0],[0,1,0],[b,a,1]],this.m_),false)};i.rotate=function(b){var a=G(b),c=F(b);A(this,y([[a,c,0],[-c,a,0],[0,0,1]],this.m_),false)};i.scale=function(b,a){this.arcScaleX_*=b;this.arcScaleY_*=a;A(this,y([[b,0,0],[0,a,
|
||||||
|
0],[0,0,1]],this.m_),true)};i.transform=function(b,a,c,d,f,h){A(this,y([[b,a,0],[c,d,0],[f,h,1]],this.m_),true)};i.setTransform=function(b,a,c,d,f,h){A(this,[[b,a,0],[c,d,0],[f,h,1]],true)};i.clip=function(){};i.arcTo=function(){};i.createPattern=function(){return new U};function D(b){this.type_=b;this.r1_=this.y1_=this.x1_=this.r0_=this.y0_=this.x0_=0;this.colors_=[]}D.prototype.addColorStop=function(b,a){a=P(a);this.colors_.push({offset:b,color:a.color,alpha:a.alpha})};function U(){}G_vmlCanvasManager=
|
||||||
|
M;CanvasRenderingContext2D=H;CanvasGradient=D;CanvasPattern=U})();
|
924
js/libs/excanvas.js
Normal file
924
js/libs/excanvas.js
Normal file
@ -0,0 +1,924 @@
|
|||||||
|
// Copyright 2006 Google Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
|
||||||
|
// Known Issues:
|
||||||
|
//
|
||||||
|
// * Patterns are not implemented.
|
||||||
|
// * Radial gradient are not implemented. The VML version of these look very
|
||||||
|
// different from the canvas one.
|
||||||
|
// * Clipping paths are not implemented.
|
||||||
|
// * Coordsize. The width and height attribute have higher priority than the
|
||||||
|
// width and height style values which isn't correct.
|
||||||
|
// * Painting mode isn't implemented.
|
||||||
|
// * Canvas width/height should is using content-box by default. IE in
|
||||||
|
// Quirks mode will draw the canvas using border-box. Either change your
|
||||||
|
// doctype to HTML5
|
||||||
|
// (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype)
|
||||||
|
// or use Box Sizing Behavior from WebFX
|
||||||
|
// (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html)
|
||||||
|
// * Non uniform scaling does not correctly scale strokes.
|
||||||
|
// * Optimize. There is always room for speed improvements.
|
||||||
|
|
||||||
|
// Only add this code if we do not already have a canvas implementation
|
||||||
|
if (!document.createElement('canvas').getContext) {
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
// alias some functions to make (compiled) code shorter
|
||||||
|
var m = Math;
|
||||||
|
var mr = m.round;
|
||||||
|
var ms = m.sin;
|
||||||
|
var mc = m.cos;
|
||||||
|
var abs = m.abs;
|
||||||
|
var sqrt = m.sqrt;
|
||||||
|
|
||||||
|
// this is used for sub pixel precision
|
||||||
|
var Z = 10;
|
||||||
|
var Z2 = Z / 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This funtion is assigned to the <canvas> elements as element.getContext().
|
||||||
|
* @this {HTMLElement}
|
||||||
|
* @return {CanvasRenderingContext2D_}
|
||||||
|
*/
|
||||||
|
function getContext() {
|
||||||
|
return this.context_ ||
|
||||||
|
(this.context_ = new CanvasRenderingContext2D_(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
var slice = Array.prototype.slice;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds a function to an object. The returned function will always use the
|
||||||
|
* passed in {@code obj} as {@code this}.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* g = bind(f, obj, a, b)
|
||||||
|
* g(c, d) // will do f.call(obj, a, b, c, d)
|
||||||
|
*
|
||||||
|
* @param {Function} f The function to bind the object to
|
||||||
|
* @param {Object} obj The object that should act as this when the function
|
||||||
|
* is called
|
||||||
|
* @param {*} var_args Rest arguments that will be used as the initial
|
||||||
|
* arguments when the function is called
|
||||||
|
* @return {Function} A new function that has bound this
|
||||||
|
*/
|
||||||
|
function bind(f, obj, var_args) {
|
||||||
|
var a = slice.call(arguments, 2);
|
||||||
|
return function() {
|
||||||
|
return f.apply(obj, a.concat(slice.call(arguments)));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var G_vmlCanvasManager_ = {
|
||||||
|
init: function(opt_doc) {
|
||||||
|
if (/MSIE/.test(navigator.userAgent) && !window.opera) {
|
||||||
|
var doc = opt_doc || document;
|
||||||
|
// Create a dummy element so that IE will allow canvas elements to be
|
||||||
|
// recognized.
|
||||||
|
doc.createElement('canvas');
|
||||||
|
doc.attachEvent('onreadystatechange', bind(this.init_, this, doc));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
init_: function(doc) {
|
||||||
|
// create xmlns
|
||||||
|
if (!doc.namespaces['g_vml_']) {
|
||||||
|
doc.namespaces.add('g_vml_', 'urn:schemas-microsoft-com:vml',
|
||||||
|
'#default#VML');
|
||||||
|
|
||||||
|
}
|
||||||
|
if (!doc.namespaces['g_o_']) {
|
||||||
|
doc.namespaces.add('g_o_', 'urn:schemas-microsoft-com:office:office',
|
||||||
|
'#default#VML');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup default CSS. Only add one style sheet per document
|
||||||
|
if (!doc.styleSheets['ex_canvas_']) {
|
||||||
|
var ss = doc.createStyleSheet();
|
||||||
|
ss.owningElement.id = 'ex_canvas_';
|
||||||
|
ss.cssText = 'canvas{display:inline-block;overflow:hidden;' +
|
||||||
|
// default size is 300x150 in Gecko and Opera
|
||||||
|
'text-align:left;width:300px;height:150px}' +
|
||||||
|
'g_vml_\\:*{behavior:url(#default#VML)}' +
|
||||||
|
'g_o_\\:*{behavior:url(#default#VML)}';
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// find all canvas elements
|
||||||
|
var els = doc.getElementsByTagName('canvas');
|
||||||
|
for (var i = 0; i < els.length; i++) {
|
||||||
|
this.initElement(els[i]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public initializes a canvas element so that it can be used as canvas
|
||||||
|
* element from now on. This is called automatically before the page is
|
||||||
|
* loaded but if you are creating elements using createElement you need to
|
||||||
|
* make sure this is called on the element.
|
||||||
|
* @param {HTMLElement} el The canvas element to initialize.
|
||||||
|
* @return {HTMLElement} the element that was created.
|
||||||
|
*/
|
||||||
|
initElement: function(el) {
|
||||||
|
if (!el.getContext) {
|
||||||
|
|
||||||
|
el.getContext = getContext;
|
||||||
|
|
||||||
|
// Remove fallback content. There is no way to hide text nodes so we
|
||||||
|
// just remove all childNodes. We could hide all elements and remove
|
||||||
|
// text nodes but who really cares about the fallback content.
|
||||||
|
el.innerHTML = '';
|
||||||
|
|
||||||
|
// do not use inline function because that will leak memory
|
||||||
|
el.attachEvent('onpropertychange', onPropertyChange);
|
||||||
|
el.attachEvent('onresize', onResize);
|
||||||
|
|
||||||
|
var attrs = el.attributes;
|
||||||
|
if (attrs.width && attrs.width.specified) {
|
||||||
|
// TODO: use runtimeStyle and coordsize
|
||||||
|
// el.getContext().setWidth_(attrs.width.nodeValue);
|
||||||
|
el.style.width = attrs.width.nodeValue + 'px';
|
||||||
|
} else {
|
||||||
|
el.width = el.clientWidth;
|
||||||
|
}
|
||||||
|
if (attrs.height && attrs.height.specified) {
|
||||||
|
// TODO: use runtimeStyle and coordsize
|
||||||
|
// el.getContext().setHeight_(attrs.height.nodeValue);
|
||||||
|
el.style.height = attrs.height.nodeValue + 'px';
|
||||||
|
} else {
|
||||||
|
el.height = el.clientHeight;
|
||||||
|
}
|
||||||
|
//el.getContext().setCoordsize_()
|
||||||
|
}
|
||||||
|
return el;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function onPropertyChange(e) {
|
||||||
|
var el = e.srcElement;
|
||||||
|
|
||||||
|
switch (e.propertyName) {
|
||||||
|
case 'width':
|
||||||
|
el.style.width = el.attributes.width.nodeValue + 'px';
|
||||||
|
el.getContext().clearRect();
|
||||||
|
break;
|
||||||
|
case 'height':
|
||||||
|
el.style.height = el.attributes.height.nodeValue + 'px';
|
||||||
|
el.getContext().clearRect();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onResize(e) {
|
||||||
|
var el = e.srcElement;
|
||||||
|
if (el.firstChild) {
|
||||||
|
el.firstChild.style.width = el.clientWidth + 'px';
|
||||||
|
el.firstChild.style.height = el.clientHeight + 'px';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
G_vmlCanvasManager_.init();
|
||||||
|
|
||||||
|
// precompute "00" to "FF"
|
||||||
|
var dec2hex = [];
|
||||||
|
for (var i = 0; i < 16; i++) {
|
||||||
|
for (var j = 0; j < 16; j++) {
|
||||||
|
dec2hex[i * 16 + j] = i.toString(16) + j.toString(16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createMatrixIdentity() {
|
||||||
|
return [
|
||||||
|
[1, 0, 0],
|
||||||
|
[0, 1, 0],
|
||||||
|
[0, 0, 1]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function matrixMultiply(m1, m2) {
|
||||||
|
var result = createMatrixIdentity();
|
||||||
|
|
||||||
|
for (var x = 0; x < 3; x++) {
|
||||||
|
for (var y = 0; y < 3; y++) {
|
||||||
|
var sum = 0;
|
||||||
|
|
||||||
|
for (var z = 0; z < 3; z++) {
|
||||||
|
sum += m1[x][z] * m2[z][y];
|
||||||
|
}
|
||||||
|
|
||||||
|
result[x][y] = sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function copyState(o1, o2) {
|
||||||
|
o2.fillStyle = o1.fillStyle;
|
||||||
|
o2.lineCap = o1.lineCap;
|
||||||
|
o2.lineJoin = o1.lineJoin;
|
||||||
|
o2.lineWidth = o1.lineWidth;
|
||||||
|
o2.miterLimit = o1.miterLimit;
|
||||||
|
o2.shadowBlur = o1.shadowBlur;
|
||||||
|
o2.shadowColor = o1.shadowColor;
|
||||||
|
o2.shadowOffsetX = o1.shadowOffsetX;
|
||||||
|
o2.shadowOffsetY = o1.shadowOffsetY;
|
||||||
|
o2.strokeStyle = o1.strokeStyle;
|
||||||
|
o2.globalAlpha = o1.globalAlpha;
|
||||||
|
o2.arcScaleX_ = o1.arcScaleX_;
|
||||||
|
o2.arcScaleY_ = o1.arcScaleY_;
|
||||||
|
o2.lineScale_ = o1.lineScale_;
|
||||||
|
}
|
||||||
|
|
||||||
|
function processStyle(styleString) {
|
||||||
|
var str, alpha = 1;
|
||||||
|
|
||||||
|
styleString = String(styleString);
|
||||||
|
if (styleString.substring(0, 3) == 'rgb') {
|
||||||
|
var start = styleString.indexOf('(', 3);
|
||||||
|
var end = styleString.indexOf(')', start + 1);
|
||||||
|
var guts = styleString.substring(start + 1, end).split(',');
|
||||||
|
|
||||||
|
str = '#';
|
||||||
|
for (var i = 0; i < 3; i++) {
|
||||||
|
str += dec2hex[Number(guts[i])];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (guts.length == 4 && styleString.substr(3, 1) == 'a') {
|
||||||
|
alpha = guts[3];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
str = styleString;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {color: str, alpha: alpha};
|
||||||
|
}
|
||||||
|
|
||||||
|
function processLineCap(lineCap) {
|
||||||
|
switch (lineCap) {
|
||||||
|
case 'butt':
|
||||||
|
return 'flat';
|
||||||
|
case 'round':
|
||||||
|
return 'round';
|
||||||
|
case 'square':
|
||||||
|
default:
|
||||||
|
return 'square';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class implements CanvasRenderingContext2D interface as described by
|
||||||
|
* the WHATWG.
|
||||||
|
* @param {HTMLElement} surfaceElement The element that the 2D context should
|
||||||
|
* be associated with
|
||||||
|
*/
|
||||||
|
function CanvasRenderingContext2D_(surfaceElement) {
|
||||||
|
this.m_ = createMatrixIdentity();
|
||||||
|
|
||||||
|
this.mStack_ = [];
|
||||||
|
this.aStack_ = [];
|
||||||
|
this.currentPath_ = [];
|
||||||
|
|
||||||
|
// Canvas context properties
|
||||||
|
this.strokeStyle = '#000';
|
||||||
|
this.fillStyle = '#000';
|
||||||
|
|
||||||
|
this.lineWidth = 1;
|
||||||
|
this.lineJoin = 'miter';
|
||||||
|
this.lineCap = 'butt';
|
||||||
|
this.miterLimit = Z * 1;
|
||||||
|
this.globalAlpha = 1;
|
||||||
|
this.canvas = surfaceElement;
|
||||||
|
|
||||||
|
var el = surfaceElement.ownerDocument.createElement('div');
|
||||||
|
el.style.width = surfaceElement.clientWidth + 'px';
|
||||||
|
el.style.height = surfaceElement.clientHeight + 'px';
|
||||||
|
el.style.overflow = 'hidden';
|
||||||
|
el.style.position = 'absolute';
|
||||||
|
surfaceElement.appendChild(el);
|
||||||
|
|
||||||
|
this.element_ = el;
|
||||||
|
this.arcScaleX_ = 1;
|
||||||
|
this.arcScaleY_ = 1;
|
||||||
|
this.lineScale_ = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
var contextPrototype = CanvasRenderingContext2D_.prototype;
|
||||||
|
contextPrototype.clearRect = function() {
|
||||||
|
this.element_.innerHTML = '';
|
||||||
|
};
|
||||||
|
|
||||||
|
contextPrototype.beginPath = function() {
|
||||||
|
// TODO: Branch current matrix so that save/restore has no effect
|
||||||
|
// as per safari docs.
|
||||||
|
this.currentPath_ = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
contextPrototype.moveTo = function(aX, aY) {
|
||||||
|
var p = this.getCoords_(aX, aY);
|
||||||
|
this.currentPath_.push({type: 'moveTo', x: p.x, y: p.y});
|
||||||
|
this.currentX_ = p.x;
|
||||||
|
this.currentY_ = p.y;
|
||||||
|
};
|
||||||
|
|
||||||
|
contextPrototype.lineTo = function(aX, aY) {
|
||||||
|
var p = this.getCoords_(aX, aY);
|
||||||
|
this.currentPath_.push({type: 'lineTo', x: p.x, y: p.y});
|
||||||
|
|
||||||
|
this.currentX_ = p.x;
|
||||||
|
this.currentY_ = p.y;
|
||||||
|
};
|
||||||
|
|
||||||
|
contextPrototype.bezierCurveTo = function(aCP1x, aCP1y,
|
||||||
|
aCP2x, aCP2y,
|
||||||
|
aX, aY) {
|
||||||
|
var p = this.getCoords_(aX, aY);
|
||||||
|
var cp1 = this.getCoords_(aCP1x, aCP1y);
|
||||||
|
var cp2 = this.getCoords_(aCP2x, aCP2y);
|
||||||
|
bezierCurveTo(this, cp1, cp2, p);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper function that takes the already fixed cordinates.
|
||||||
|
function bezierCurveTo(self, cp1, cp2, p) {
|
||||||
|
self.currentPath_.push({
|
||||||
|
type: 'bezierCurveTo',
|
||||||
|
cp1x: cp1.x,
|
||||||
|
cp1y: cp1.y,
|
||||||
|
cp2x: cp2.x,
|
||||||
|
cp2y: cp2.y,
|
||||||
|
x: p.x,
|
||||||
|
y: p.y
|
||||||
|
});
|
||||||
|
self.currentX_ = p.x;
|
||||||
|
self.currentY_ = p.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) {
|
||||||
|
// the following is lifted almost directly from
|
||||||
|
// http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes
|
||||||
|
|
||||||
|
var cp = this.getCoords_(aCPx, aCPy);
|
||||||
|
var p = this.getCoords_(aX, aY);
|
||||||
|
|
||||||
|
var cp1 = {
|
||||||
|
x: this.currentX_ + 2.0 / 3.0 * (cp.x - this.currentX_),
|
||||||
|
y: this.currentY_ + 2.0 / 3.0 * (cp.y - this.currentY_)
|
||||||
|
};
|
||||||
|
var cp2 = {
|
||||||
|
x: cp1.x + (p.x - this.currentX_) / 3.0,
|
||||||
|
y: cp1.y + (p.y - this.currentY_) / 3.0
|
||||||
|
};
|
||||||
|
|
||||||
|
bezierCurveTo(this, cp1, cp2, p);
|
||||||
|
};
|
||||||
|
|
||||||
|
contextPrototype.arc = function(aX, aY, aRadius,
|
||||||
|
aStartAngle, aEndAngle, aClockwise) {
|
||||||
|
aRadius *= Z;
|
||||||
|
var arcType = aClockwise ? 'at' : 'wa';
|
||||||
|
|
||||||
|
var xStart = aX + mc(aStartAngle) * aRadius - Z2;
|
||||||
|
var yStart = aY + ms(aStartAngle) * aRadius - Z2;
|
||||||
|
|
||||||
|
var xEnd = aX + mc(aEndAngle) * aRadius - Z2;
|
||||||
|
var yEnd = aY + ms(aEndAngle) * aRadius - Z2;
|
||||||
|
|
||||||
|
// IE won't render arches drawn counter clockwise if xStart == xEnd.
|
||||||
|
if (xStart == xEnd && !aClockwise) {
|
||||||
|
xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something
|
||||||
|
// that can be represented in binary
|
||||||
|
}
|
||||||
|
|
||||||
|
var p = this.getCoords_(aX, aY);
|
||||||
|
var pStart = this.getCoords_(xStart, yStart);
|
||||||
|
var pEnd = this.getCoords_(xEnd, yEnd);
|
||||||
|
|
||||||
|
this.currentPath_.push({type: arcType,
|
||||||
|
x: p.x,
|
||||||
|
y: p.y,
|
||||||
|
radius: aRadius,
|
||||||
|
xStart: pStart.x,
|
||||||
|
yStart: pStart.y,
|
||||||
|
xEnd: pEnd.x,
|
||||||
|
yEnd: pEnd.y});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
contextPrototype.rect = function(aX, aY, aWidth, aHeight) {
|
||||||
|
this.moveTo(aX, aY);
|
||||||
|
this.lineTo(aX + aWidth, aY);
|
||||||
|
this.lineTo(aX + aWidth, aY + aHeight);
|
||||||
|
this.lineTo(aX, aY + aHeight);
|
||||||
|
this.closePath();
|
||||||
|
};
|
||||||
|
|
||||||
|
contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) {
|
||||||
|
var oldPath = this.currentPath_;
|
||||||
|
this.beginPath();
|
||||||
|
|
||||||
|
this.moveTo(aX, aY);
|
||||||
|
this.lineTo(aX + aWidth, aY);
|
||||||
|
this.lineTo(aX + aWidth, aY + aHeight);
|
||||||
|
this.lineTo(aX, aY + aHeight);
|
||||||
|
this.closePath();
|
||||||
|
this.stroke();
|
||||||
|
|
||||||
|
this.currentPath_ = oldPath;
|
||||||
|
};
|
||||||
|
|
||||||
|
contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) {
|
||||||
|
var oldPath = this.currentPath_;
|
||||||
|
this.beginPath();
|
||||||
|
|
||||||
|
this.moveTo(aX, aY);
|
||||||
|
this.lineTo(aX + aWidth, aY);
|
||||||
|
this.lineTo(aX + aWidth, aY + aHeight);
|
||||||
|
this.lineTo(aX, aY + aHeight);
|
||||||
|
this.closePath();
|
||||||
|
this.fill();
|
||||||
|
|
||||||
|
this.currentPath_ = oldPath;
|
||||||
|
};
|
||||||
|
|
||||||
|
contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) {
|
||||||
|
var gradient = new CanvasGradient_('gradient');
|
||||||
|
gradient.x0_ = aX0;
|
||||||
|
gradient.y0_ = aY0;
|
||||||
|
gradient.x1_ = aX1;
|
||||||
|
gradient.y1_ = aY1;
|
||||||
|
return gradient;
|
||||||
|
};
|
||||||
|
|
||||||
|
contextPrototype.createRadialGradient = function(aX0, aY0, aR0,
|
||||||
|
aX1, aY1, aR1) {
|
||||||
|
var gradient = new CanvasGradient_('gradientradial');
|
||||||
|
gradient.x0_ = aX0;
|
||||||
|
gradient.y0_ = aY0;
|
||||||
|
gradient.r0_ = aR0;
|
||||||
|
gradient.x1_ = aX1;
|
||||||
|
gradient.y1_ = aY1;
|
||||||
|
gradient.r1_ = aR1;
|
||||||
|
return gradient;
|
||||||
|
};
|
||||||
|
|
||||||
|
contextPrototype.drawImage = function(image, var_args) {
|
||||||
|
var dx, dy, dw, dh, sx, sy, sw, sh;
|
||||||
|
|
||||||
|
// to find the original width we overide the width and height
|
||||||
|
var oldRuntimeWidth = image.runtimeStyle.width;
|
||||||
|
var oldRuntimeHeight = image.runtimeStyle.height;
|
||||||
|
image.runtimeStyle.width = 'auto';
|
||||||
|
image.runtimeStyle.height = 'auto';
|
||||||
|
|
||||||
|
// get the original size
|
||||||
|
var w = image.width;
|
||||||
|
var h = image.height;
|
||||||
|
|
||||||
|
// and remove overides
|
||||||
|
image.runtimeStyle.width = oldRuntimeWidth;
|
||||||
|
image.runtimeStyle.height = oldRuntimeHeight;
|
||||||
|
|
||||||
|
if (arguments.length == 3) {
|
||||||
|
dx = arguments[1];
|
||||||
|
dy = arguments[2];
|
||||||
|
sx = sy = 0;
|
||||||
|
sw = dw = w;
|
||||||
|
sh = dh = h;
|
||||||
|
} else if (arguments.length == 5) {
|
||||||
|
dx = arguments[1];
|
||||||
|
dy = arguments[2];
|
||||||
|
dw = arguments[3];
|
||||||
|
dh = arguments[4];
|
||||||
|
sx = sy = 0;
|
||||||
|
sw = w;
|
||||||
|
sh = h;
|
||||||
|
} else if (arguments.length == 9) {
|
||||||
|
sx = arguments[1];
|
||||||
|
sy = arguments[2];
|
||||||
|
sw = arguments[3];
|
||||||
|
sh = arguments[4];
|
||||||
|
dx = arguments[5];
|
||||||
|
dy = arguments[6];
|
||||||
|
dw = arguments[7];
|
||||||
|
dh = arguments[8];
|
||||||
|
} else {
|
||||||
|
throw Error('Invalid number of arguments');
|
||||||
|
}
|
||||||
|
|
||||||
|
var d = this.getCoords_(dx, dy);
|
||||||
|
|
||||||
|
var w2 = sw / 2;
|
||||||
|
var h2 = sh / 2;
|
||||||
|
|
||||||
|
var vmlStr = [];
|
||||||
|
|
||||||
|
var W = 10;
|
||||||
|
var H = 10;
|
||||||
|
|
||||||
|
// For some reason that I've now forgotten, using divs didn't work
|
||||||
|
vmlStr.push(' <g_vml_:group',
|
||||||
|
' coordsize="', Z * W, ',', Z * H, '"',
|
||||||
|
' coordorigin="0,0"' ,
|
||||||
|
' style="width:', W, 'px;height:', H, 'px;position:absolute;');
|
||||||
|
|
||||||
|
// If filters are necessary (rotation exists), create them
|
||||||
|
// filters are bog-slow, so only create them if abbsolutely necessary
|
||||||
|
// The following check doesn't account for skews (which don't exist
|
||||||
|
// in the canvas spec (yet) anyway.
|
||||||
|
|
||||||
|
if (this.m_[0][0] != 1 || this.m_[0][1]) {
|
||||||
|
var filter = [];
|
||||||
|
|
||||||
|
// Note the 12/21 reversal
|
||||||
|
filter.push('M11=', this.m_[0][0], ',',
|
||||||
|
'M12=', this.m_[1][0], ',',
|
||||||
|
'M21=', this.m_[0][1], ',',
|
||||||
|
'M22=', this.m_[1][1], ',',
|
||||||
|
'Dx=', mr(d.x / Z), ',',
|
||||||
|
'Dy=', mr(d.y / Z), '');
|
||||||
|
|
||||||
|
// Bounding box calculation (need to minimize displayed area so that
|
||||||
|
// filters don't waste time on unused pixels.
|
||||||
|
var max = d;
|
||||||
|
var c2 = this.getCoords_(dx + dw, dy);
|
||||||
|
var c3 = this.getCoords_(dx, dy + dh);
|
||||||
|
var c4 = this.getCoords_(dx + dw, dy + dh);
|
||||||
|
|
||||||
|
max.x = m.max(max.x, c2.x, c3.x, c4.x);
|
||||||
|
max.y = m.max(max.y, c2.y, c3.y, c4.y);
|
||||||
|
|
||||||
|
vmlStr.push('padding:0 ', mr(max.x / Z), 'px ', mr(max.y / Z),
|
||||||
|
'px 0;filter:progid:DXImageTransform.Microsoft.Matrix(',
|
||||||
|
filter.join(''), ", sizingmethod='clip');")
|
||||||
|
} else {
|
||||||
|
vmlStr.push('top:', mr(d.y / Z), 'px;left:', mr(d.x / Z), 'px;');
|
||||||
|
}
|
||||||
|
|
||||||
|
vmlStr.push(' ">' ,
|
||||||
|
'<g_vml_:image src="', image.src, '"',
|
||||||
|
' style="width:', Z * dw, 'px;',
|
||||||
|
' height:', Z * dh, 'px;"',
|
||||||
|
' cropleft="', sx / w, '"',
|
||||||
|
' croptop="', sy / h, '"',
|
||||||
|
' cropright="', (w - sx - sw) / w, '"',
|
||||||
|
' cropbottom="', (h - sy - sh) / h, '"',
|
||||||
|
' />',
|
||||||
|
'</g_vml_:group>');
|
||||||
|
|
||||||
|
this.element_.insertAdjacentHTML('BeforeEnd',
|
||||||
|
vmlStr.join(''));
|
||||||
|
};
|
||||||
|
|
||||||
|
contextPrototype.stroke = function(aFill) {
|
||||||
|
var lineStr = [];
|
||||||
|
var lineOpen = false;
|
||||||
|
var a = processStyle(aFill ? this.fillStyle : this.strokeStyle);
|
||||||
|
var color = a.color;
|
||||||
|
var opacity = a.alpha * this.globalAlpha;
|
||||||
|
|
||||||
|
var W = 10;
|
||||||
|
var H = 10;
|
||||||
|
|
||||||
|
lineStr.push('<g_vml_:shape',
|
||||||
|
' filled="', !!aFill, '"',
|
||||||
|
' style="position:absolute;width:', W, 'px;height:', H, 'px;"',
|
||||||
|
' coordorigin="0 0" coordsize="', Z * W, ' ', Z * H, '"',
|
||||||
|
' stroked="', !aFill, '"',
|
||||||
|
' path="');
|
||||||
|
|
||||||
|
var newSeq = false;
|
||||||
|
var min = {x: null, y: null};
|
||||||
|
var max = {x: null, y: null};
|
||||||
|
|
||||||
|
for (var i = 0; i < this.currentPath_.length; i++) {
|
||||||
|
var p = this.currentPath_[i];
|
||||||
|
var c;
|
||||||
|
|
||||||
|
switch (p.type) {
|
||||||
|
case 'moveTo':
|
||||||
|
c = p;
|
||||||
|
lineStr.push(' m ', mr(p.x), ',', mr(p.y));
|
||||||
|
break;
|
||||||
|
case 'lineTo':
|
||||||
|
lineStr.push(' l ', mr(p.x), ',', mr(p.y));
|
||||||
|
break;
|
||||||
|
case 'close':
|
||||||
|
lineStr.push(' x ');
|
||||||
|
p = null;
|
||||||
|
break;
|
||||||
|
case 'bezierCurveTo':
|
||||||
|
lineStr.push(' c ',
|
||||||
|
mr(p.cp1x), ',', mr(p.cp1y), ',',
|
||||||
|
mr(p.cp2x), ',', mr(p.cp2y), ',',
|
||||||
|
mr(p.x), ',', mr(p.y));
|
||||||
|
break;
|
||||||
|
case 'at':
|
||||||
|
case 'wa':
|
||||||
|
lineStr.push(' ', p.type, ' ',
|
||||||
|
mr(p.x - this.arcScaleX_ * p.radius), ',',
|
||||||
|
mr(p.y - this.arcScaleY_ * p.radius), ' ',
|
||||||
|
mr(p.x + this.arcScaleX_ * p.radius), ',',
|
||||||
|
mr(p.y + this.arcScaleY_ * p.radius), ' ',
|
||||||
|
mr(p.xStart), ',', mr(p.yStart), ' ',
|
||||||
|
mr(p.xEnd), ',', mr(p.yEnd));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: Following is broken for curves due to
|
||||||
|
// move to proper paths.
|
||||||
|
|
||||||
|
// Figure out dimensions so we can do gradient fills
|
||||||
|
// properly
|
||||||
|
if (p) {
|
||||||
|
if (min.x == null || p.x < min.x) {
|
||||||
|
min.x = p.x;
|
||||||
|
}
|
||||||
|
if (max.x == null || p.x > max.x) {
|
||||||
|
max.x = p.x;
|
||||||
|
}
|
||||||
|
if (min.y == null || p.y < min.y) {
|
||||||
|
min.y = p.y;
|
||||||
|
}
|
||||||
|
if (max.y == null || p.y > max.y) {
|
||||||
|
max.y = p.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lineStr.push(' ">');
|
||||||
|
|
||||||
|
if (!aFill) {
|
||||||
|
var lineWidth = this.lineScale_ * this.lineWidth;
|
||||||
|
|
||||||
|
// VML cannot correctly render a line if the width is less than 1px.
|
||||||
|
// In that case, we dilute the color to make the line look thinner.
|
||||||
|
if (lineWidth < 1) {
|
||||||
|
opacity *= lineWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
lineStr.push(
|
||||||
|
'<g_vml_:stroke',
|
||||||
|
' opacity="', opacity, '"',
|
||||||
|
' joinstyle="', this.lineJoin, '"',
|
||||||
|
' miterlimit="', this.miterLimit, '"',
|
||||||
|
' endcap="', processLineCap(this.lineCap), '"',
|
||||||
|
' weight="', lineWidth, 'px"',
|
||||||
|
' color="', color, '" />'
|
||||||
|
);
|
||||||
|
} else if (typeof this.fillStyle == 'object') {
|
||||||
|
var fillStyle = this.fillStyle;
|
||||||
|
var angle = 0;
|
||||||
|
var focus = {x: 0, y: 0};
|
||||||
|
|
||||||
|
// additional offset
|
||||||
|
var shift = 0;
|
||||||
|
// scale factor for offset
|
||||||
|
var expansion = 1;
|
||||||
|
|
||||||
|
if (fillStyle.type_ == 'gradient') {
|
||||||
|
var x0 = fillStyle.x0_ / this.arcScaleX_;
|
||||||
|
var y0 = fillStyle.y0_ / this.arcScaleY_;
|
||||||
|
var x1 = fillStyle.x1_ / this.arcScaleX_;
|
||||||
|
var y1 = fillStyle.y1_ / this.arcScaleY_;
|
||||||
|
var p0 = this.getCoords_(x0, y0);
|
||||||
|
var p1 = this.getCoords_(x1, y1);
|
||||||
|
var dx = p1.x - p0.x;
|
||||||
|
var dy = p1.y - p0.y;
|
||||||
|
angle = Math.atan2(dx, dy) * 180 / Math.PI;
|
||||||
|
|
||||||
|
// The angle should be a non-negative number.
|
||||||
|
if (angle < 0) {
|
||||||
|
angle += 360;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Very small angles produce an unexpected result because they are
|
||||||
|
// converted to a scientific notation string.
|
||||||
|
if (angle < 1e-6) {
|
||||||
|
angle = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var p0 = this.getCoords_(fillStyle.x0_, fillStyle.y0_);
|
||||||
|
var width = max.x - min.x;
|
||||||
|
var height = max.y - min.y;
|
||||||
|
focus = {
|
||||||
|
x: (p0.x - min.x) / width,
|
||||||
|
y: (p0.y - min.y) / height
|
||||||
|
};
|
||||||
|
|
||||||
|
width /= this.arcScaleX_ * Z;
|
||||||
|
height /= this.arcScaleY_ * Z;
|
||||||
|
var dimension = m.max(width, height);
|
||||||
|
shift = 2 * fillStyle.r0_ / dimension;
|
||||||
|
expansion = 2 * fillStyle.r1_ / dimension - shift;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to sort the color stops in ascending order by offset,
|
||||||
|
// otherwise IE won't interpret it correctly.
|
||||||
|
var stops = fillStyle.colors_;
|
||||||
|
stops.sort(function(cs1, cs2) {
|
||||||
|
return cs1.offset - cs2.offset;
|
||||||
|
});
|
||||||
|
|
||||||
|
var length = stops.length;
|
||||||
|
var color1 = stops[0].color;
|
||||||
|
var color2 = stops[length - 1].color;
|
||||||
|
var opacity1 = stops[0].alpha * this.globalAlpha;
|
||||||
|
var opacity2 = stops[length - 1].alpha * this.globalAlpha;
|
||||||
|
|
||||||
|
var colors = [];
|
||||||
|
for (var i = 0; i < length; i++) {
|
||||||
|
var stop = stops[i];
|
||||||
|
colors.push(stop.offset * expansion + shift + ' ' + stop.color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// When colors attribute is used, the meanings of opacity and o:opacity2
|
||||||
|
// are reversed.
|
||||||
|
lineStr.push('<g_vml_:fill type="', fillStyle.type_, '"',
|
||||||
|
' method="none" focus="100%"',
|
||||||
|
' color="', color1, '"',
|
||||||
|
' color2="', color2, '"',
|
||||||
|
' colors="', colors.join(','), '"',
|
||||||
|
' opacity="', opacity2, '"',
|
||||||
|
' g_o_:opacity2="', opacity1, '"',
|
||||||
|
' angle="', angle, '"',
|
||||||
|
' focusposition="', focus.x, ',', focus.y, '" />');
|
||||||
|
} else {
|
||||||
|
lineStr.push('<g_vml_:fill color="', color, '" opacity="', opacity,
|
||||||
|
'" />');
|
||||||
|
}
|
||||||
|
|
||||||
|
lineStr.push('</g_vml_:shape>');
|
||||||
|
|
||||||
|
this.element_.insertAdjacentHTML('beforeEnd', lineStr.join(''));
|
||||||
|
};
|
||||||
|
|
||||||
|
contextPrototype.fill = function() {
|
||||||
|
this.stroke(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
contextPrototype.closePath = function() {
|
||||||
|
this.currentPath_.push({type: 'close'});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
contextPrototype.getCoords_ = function(aX, aY) {
|
||||||
|
var m = this.m_;
|
||||||
|
return {
|
||||||
|
x: Z * (aX * m[0][0] + aY * m[1][0] + m[2][0]) - Z2,
|
||||||
|
y: Z * (aX * m[0][1] + aY * m[1][1] + m[2][1]) - Z2
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
contextPrototype.save = function() {
|
||||||
|
var o = {};
|
||||||
|
copyState(this, o);
|
||||||
|
this.aStack_.push(o);
|
||||||
|
this.mStack_.push(this.m_);
|
||||||
|
this.m_ = matrixMultiply(createMatrixIdentity(), this.m_);
|
||||||
|
};
|
||||||
|
|
||||||
|
contextPrototype.restore = function() {
|
||||||
|
copyState(this.aStack_.pop(), this);
|
||||||
|
this.m_ = this.mStack_.pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
function matrixIsFinite(m) {
|
||||||
|
for (var j = 0; j < 3; j++) {
|
||||||
|
for (var k = 0; k < 2; k++) {
|
||||||
|
if (!isFinite(m[j][k]) || isNaN(m[j][k])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setM(ctx, m, updateLineScale) {
|
||||||
|
if (!matrixIsFinite(m)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ctx.m_ = m;
|
||||||
|
|
||||||
|
if (updateLineScale) {
|
||||||
|
// Get the line scale.
|
||||||
|
// Determinant of this.m_ means how much the area is enlarged by the
|
||||||
|
// transformation. So its square root can be used as a scale factor
|
||||||
|
// for width.
|
||||||
|
var det = m[0][0] * m[1][1] - m[0][1] * m[1][0];
|
||||||
|
ctx.lineScale_ = sqrt(abs(det));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contextPrototype.translate = function(aX, aY) {
|
||||||
|
var m1 = [
|
||||||
|
[1, 0, 0],
|
||||||
|
[0, 1, 0],
|
||||||
|
[aX, aY, 1]
|
||||||
|
];
|
||||||
|
|
||||||
|
setM(this, matrixMultiply(m1, this.m_), false);
|
||||||
|
};
|
||||||
|
|
||||||
|
contextPrototype.rotate = function(aRot) {
|
||||||
|
var c = mc(aRot);
|
||||||
|
var s = ms(aRot);
|
||||||
|
|
||||||
|
var m1 = [
|
||||||
|
[c, s, 0],
|
||||||
|
[-s, c, 0],
|
||||||
|
[0, 0, 1]
|
||||||
|
];
|
||||||
|
|
||||||
|
setM(this, matrixMultiply(m1, this.m_), false);
|
||||||
|
};
|
||||||
|
|
||||||
|
contextPrototype.scale = function(aX, aY) {
|
||||||
|
this.arcScaleX_ *= aX;
|
||||||
|
this.arcScaleY_ *= aY;
|
||||||
|
var m1 = [
|
||||||
|
[aX, 0, 0],
|
||||||
|
[0, aY, 0],
|
||||||
|
[0, 0, 1]
|
||||||
|
];
|
||||||
|
|
||||||
|
setM(this, matrixMultiply(m1, this.m_), true);
|
||||||
|
};
|
||||||
|
|
||||||
|
contextPrototype.transform = function(m11, m12, m21, m22, dx, dy) {
|
||||||
|
var m1 = [
|
||||||
|
[m11, m12, 0],
|
||||||
|
[m21, m22, 0],
|
||||||
|
[dx, dy, 1]
|
||||||
|
];
|
||||||
|
|
||||||
|
setM(this, matrixMultiply(m1, this.m_), true);
|
||||||
|
};
|
||||||
|
|
||||||
|
contextPrototype.setTransform = function(m11, m12, m21, m22, dx, dy) {
|
||||||
|
var m = [
|
||||||
|
[m11, m12, 0],
|
||||||
|
[m21, m22, 0],
|
||||||
|
[dx, dy, 1]
|
||||||
|
];
|
||||||
|
|
||||||
|
setM(this, m, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
/******** STUBS ********/
|
||||||
|
contextPrototype.clip = function() {
|
||||||
|
// TODO: Implement
|
||||||
|
};
|
||||||
|
|
||||||
|
contextPrototype.arcTo = function() {
|
||||||
|
// TODO: Implement
|
||||||
|
};
|
||||||
|
|
||||||
|
contextPrototype.createPattern = function() {
|
||||||
|
return new CanvasPattern_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Gradient / Pattern Stubs
|
||||||
|
function CanvasGradient_(aType) {
|
||||||
|
this.type_ = aType;
|
||||||
|
this.x0_ = 0;
|
||||||
|
this.y0_ = 0;
|
||||||
|
this.r0_ = 0;
|
||||||
|
this.x1_ = 0;
|
||||||
|
this.y1_ = 0;
|
||||||
|
this.r1_ = 0;
|
||||||
|
this.colors_ = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) {
|
||||||
|
aColor = processStyle(aColor);
|
||||||
|
this.colors_.push({offset: aOffset,
|
||||||
|
color: aColor.color,
|
||||||
|
alpha: aColor.alpha});
|
||||||
|
};
|
||||||
|
|
||||||
|
function CanvasPattern_() {}
|
||||||
|
|
||||||
|
// set up externs
|
||||||
|
G_vmlCanvasManager = G_vmlCanvasManager_;
|
||||||
|
CanvasRenderingContext2D = CanvasRenderingContext2D_;
|
||||||
|
CanvasGradient = CanvasGradient_;
|
||||||
|
CanvasPattern = CanvasPattern_;
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
||||||
|
} // if
|
499
js/libs/html5shiv-printshiv.js
Normal file
499
js/libs/html5shiv-printshiv.js
Normal file
@ -0,0 +1,499 @@
|
|||||||
|
/**
|
||||||
|
* @preserve HTML5 Shiv v3.6.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
|
||||||
|
*/
|
||||||
|
;(function(window, document) {
|
||||||
|
/*jshint evil:true */
|
||||||
|
/** version */
|
||||||
|
var version = '3.6.2';
|
||||||
|
|
||||||
|
/** Preset options */
|
||||||
|
var options = window.html5 || {};
|
||||||
|
|
||||||
|
/** Used to skip problem elements */
|
||||||
|
var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
|
||||||
|
|
||||||
|
/** Not all elements can be cloned in IE **/
|
||||||
|
var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;
|
||||||
|
|
||||||
|
/** Detect whether the browser supports default html5 styles */
|
||||||
|
var supportsHtml5Styles;
|
||||||
|
|
||||||
|
/** Name of the expando, to work with multiple documents or to re-shiv one document */
|
||||||
|
var expando = '_html5shiv';
|
||||||
|
|
||||||
|
/** The id for the the documents expando */
|
||||||
|
var expanID = 0;
|
||||||
|
|
||||||
|
/** Cached data for each document */
|
||||||
|
var expandoData = {};
|
||||||
|
|
||||||
|
/** Detect whether the browser supports unknown elements */
|
||||||
|
var supportsUnknownElements;
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
try {
|
||||||
|
var a = document.createElement('a');
|
||||||
|
a.innerHTML = '<xyz></xyz>';
|
||||||
|
//if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles
|
||||||
|
supportsHtml5Styles = ('hidden' in a);
|
||||||
|
|
||||||
|
supportsUnknownElements = a.childNodes.length == 1 || (function() {
|
||||||
|
// assign a false positive if unable to shiv
|
||||||
|
(document.createElement)('a');
|
||||||
|
var frag = document.createDocumentFragment();
|
||||||
|
return (
|
||||||
|
typeof frag.cloneNode == 'undefined' ||
|
||||||
|
typeof frag.createDocumentFragment == 'undefined' ||
|
||||||
|
typeof frag.createElement == 'undefined'
|
||||||
|
);
|
||||||
|
}());
|
||||||
|
} catch(e) {
|
||||||
|
// assign a false positive if detection fails => unable to shiv
|
||||||
|
supportsHtml5Styles = true;
|
||||||
|
supportsUnknownElements = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}());
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a style sheet with the given CSS text and adds it to the document.
|
||||||
|
* @private
|
||||||
|
* @param {Document} ownerDocument The document.
|
||||||
|
* @param {String} cssText The CSS text.
|
||||||
|
* @returns {StyleSheet} The style element.
|
||||||
|
*/
|
||||||
|
function addStyleSheet(ownerDocument, cssText) {
|
||||||
|
var p = ownerDocument.createElement('p'),
|
||||||
|
parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
|
||||||
|
|
||||||
|
p.innerHTML = 'x<style>' + cssText + '</style>';
|
||||||
|
return parent.insertBefore(p.lastChild, parent.firstChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value of `html5.elements` as an array.
|
||||||
|
* @private
|
||||||
|
* @returns {Array} An array of shived element node names.
|
||||||
|
*/
|
||||||
|
function getElements() {
|
||||||
|
var elements = html5.elements;
|
||||||
|
return typeof elements == 'string' ? elements.split(' ') : elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the data associated to the given document
|
||||||
|
* @private
|
||||||
|
* @param {Document} ownerDocument The document.
|
||||||
|
* @returns {Object} An object of data.
|
||||||
|
*/
|
||||||
|
function getExpandoData(ownerDocument) {
|
||||||
|
var data = expandoData[ownerDocument[expando]];
|
||||||
|
if (!data) {
|
||||||
|
data = {};
|
||||||
|
expanID++;
|
||||||
|
ownerDocument[expando] = expanID;
|
||||||
|
expandoData[expanID] = data;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns a shived element for the given nodeName and document
|
||||||
|
* @memberOf html5
|
||||||
|
* @param {String} nodeName name of the element
|
||||||
|
* @param {Document} ownerDocument The context document.
|
||||||
|
* @returns {Object} The shived element.
|
||||||
|
*/
|
||||||
|
function createElement(nodeName, ownerDocument, data){
|
||||||
|
if (!ownerDocument) {
|
||||||
|
ownerDocument = document;
|
||||||
|
}
|
||||||
|
if(supportsUnknownElements){
|
||||||
|
return ownerDocument.createElement(nodeName);
|
||||||
|
}
|
||||||
|
if (!data) {
|
||||||
|
data = getExpandoData(ownerDocument);
|
||||||
|
}
|
||||||
|
var node;
|
||||||
|
|
||||||
|
if (data.cache[nodeName]) {
|
||||||
|
node = data.cache[nodeName].cloneNode();
|
||||||
|
} else if (saveClones.test(nodeName)) {
|
||||||
|
node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
|
||||||
|
} else {
|
||||||
|
node = data.createElem(nodeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Avoid adding some elements to fragments in IE < 9 because
|
||||||
|
// * Attributes like `name` or `type` cannot be set/changed once an element
|
||||||
|
// is inserted into a document/fragment
|
||||||
|
// * Link elements with `src` attributes that are inaccessible, as with
|
||||||
|
// a 403 response, will cause the tab/window to crash
|
||||||
|
// * Script elements appended to fragments will execute when their `src`
|
||||||
|
// or `text` property is set
|
||||||
|
return node.canHaveChildren && !reSkip.test(nodeName) ? data.frag.appendChild(node) : node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns a shived DocumentFragment for the given document
|
||||||
|
* @memberOf html5
|
||||||
|
* @param {Document} ownerDocument The context document.
|
||||||
|
* @returns {Object} The shived DocumentFragment.
|
||||||
|
*/
|
||||||
|
function createDocumentFragment(ownerDocument, data){
|
||||||
|
if (!ownerDocument) {
|
||||||
|
ownerDocument = document;
|
||||||
|
}
|
||||||
|
if(supportsUnknownElements){
|
||||||
|
return ownerDocument.createDocumentFragment();
|
||||||
|
}
|
||||||
|
data = data || getExpandoData(ownerDocument);
|
||||||
|
var clone = data.frag.cloneNode(),
|
||||||
|
i = 0,
|
||||||
|
elems = getElements(),
|
||||||
|
l = elems.length;
|
||||||
|
for(;i<l;i++){
|
||||||
|
clone.createElement(elems[i]);
|
||||||
|
}
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shivs the `createElement` and `createDocumentFragment` methods of the document.
|
||||||
|
* @private
|
||||||
|
* @param {Document|DocumentFragment} ownerDocument The document.
|
||||||
|
* @param {Object} data of the document.
|
||||||
|
*/
|
||||||
|
function shivMethods(ownerDocument, data) {
|
||||||
|
if (!data.cache) {
|
||||||
|
data.cache = {};
|
||||||
|
data.createElem = ownerDocument.createElement;
|
||||||
|
data.createFrag = ownerDocument.createDocumentFragment;
|
||||||
|
data.frag = data.createFrag();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ownerDocument.createElement = function(nodeName) {
|
||||||
|
//abort shiv
|
||||||
|
if (!html5.shivMethods) {
|
||||||
|
return data.createElem(nodeName);
|
||||||
|
}
|
||||||
|
return createElement(nodeName, ownerDocument, data);
|
||||||
|
};
|
||||||
|
|
||||||
|
ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' +
|
||||||
|
'var n=f.cloneNode(),c=n.createElement;' +
|
||||||
|
'h.shivMethods&&(' +
|
||||||
|
// unroll the `createElement` calls
|
||||||
|
getElements().join().replace(/\w+/g, function(nodeName) {
|
||||||
|
data.createElem(nodeName);
|
||||||
|
data.frag.createElement(nodeName);
|
||||||
|
return 'c("' + nodeName + '")';
|
||||||
|
}) +
|
||||||
|
');return n}'
|
||||||
|
)(html5, data.frag);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shivs the given document.
|
||||||
|
* @memberOf html5
|
||||||
|
* @param {Document} ownerDocument The document to shiv.
|
||||||
|
* @returns {Document} The shived document.
|
||||||
|
*/
|
||||||
|
function shivDocument(ownerDocument) {
|
||||||
|
if (!ownerDocument) {
|
||||||
|
ownerDocument = document;
|
||||||
|
}
|
||||||
|
var data = getExpandoData(ownerDocument);
|
||||||
|
|
||||||
|
if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) {
|
||||||
|
data.hasCSS = !!addStyleSheet(ownerDocument,
|
||||||
|
// corrects block display not defined in IE6/7/8/9
|
||||||
|
'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}' +
|
||||||
|
// adds styling not present in IE6/7/8/9
|
||||||
|
'mark{background:#FF0;color:#000}' +
|
||||||
|
// hides non-rendered elements
|
||||||
|
'template{display:none}'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!supportsUnknownElements) {
|
||||||
|
shivMethods(ownerDocument, data);
|
||||||
|
}
|
||||||
|
return ownerDocument;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The `html5` object is exposed so that more elements can be shived and
|
||||||
|
* existing shiving can be detected on iframes.
|
||||||
|
* @type Object
|
||||||
|
* @example
|
||||||
|
*
|
||||||
|
* // options can be changed before the script is included
|
||||||
|
* html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false };
|
||||||
|
*/
|
||||||
|
var html5 = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array or space separated string of node names of the elements to shiv.
|
||||||
|
* @memberOf html5
|
||||||
|
* @type Array|String
|
||||||
|
*/
|
||||||
|
'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* current version of html5shiv
|
||||||
|
*/
|
||||||
|
'version': version,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A flag to indicate that the HTML5 style sheet should be inserted.
|
||||||
|
* @memberOf html5
|
||||||
|
* @type Boolean
|
||||||
|
*/
|
||||||
|
'shivCSS': (options.shivCSS !== false),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is equal to true if a browser supports creating unknown/HTML5 elements
|
||||||
|
* @memberOf html5
|
||||||
|
* @type boolean
|
||||||
|
*/
|
||||||
|
'supportsUnknownElements': supportsUnknownElements,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A flag to indicate that the document's `createElement` and `createDocumentFragment`
|
||||||
|
* methods should be overwritten.
|
||||||
|
* @memberOf html5
|
||||||
|
* @type Boolean
|
||||||
|
*/
|
||||||
|
'shivMethods': (options.shivMethods !== false),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A string to describe the type of `html5` object ("default" or "default print").
|
||||||
|
* @memberOf html5
|
||||||
|
* @type String
|
||||||
|
*/
|
||||||
|
'type': 'default',
|
||||||
|
|
||||||
|
// shivs the document according to the specified `html5` object options
|
||||||
|
'shivDocument': shivDocument,
|
||||||
|
|
||||||
|
//creates a shived element
|
||||||
|
createElement: createElement,
|
||||||
|
|
||||||
|
//creates a shived documentFragment
|
||||||
|
createDocumentFragment: createDocumentFragment
|
||||||
|
};
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// expose html5
|
||||||
|
window.html5 = html5;
|
||||||
|
|
||||||
|
// shiv the document
|
||||||
|
shivDocument(document);
|
||||||
|
|
||||||
|
/*------------------------------- Print Shiv -------------------------------*/
|
||||||
|
|
||||||
|
/** Used to filter media types */
|
||||||
|
var reMedia = /^$|\b(?:all|print)\b/;
|
||||||
|
|
||||||
|
/** Used to namespace printable elements */
|
||||||
|
var shivNamespace = 'html5shiv';
|
||||||
|
|
||||||
|
/** Detect whether the browser supports shivable style sheets */
|
||||||
|
var supportsShivableSheets = !supportsUnknownElements && (function() {
|
||||||
|
// assign a false negative if unable to shiv
|
||||||
|
var docEl = document.documentElement;
|
||||||
|
return !(
|
||||||
|
typeof document.namespaces == 'undefined' ||
|
||||||
|
typeof document.parentWindow == 'undefined' ||
|
||||||
|
typeof docEl.applyElement == 'undefined' ||
|
||||||
|
typeof docEl.removeNode == 'undefined' ||
|
||||||
|
typeof window.attachEvent == 'undefined'
|
||||||
|
);
|
||||||
|
}());
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps all HTML5 elements in the given document with printable elements.
|
||||||
|
* (eg. the "header" element is wrapped with the "html5shiv:header" element)
|
||||||
|
* @private
|
||||||
|
* @param {Document} ownerDocument The document.
|
||||||
|
* @returns {Array} An array wrappers added.
|
||||||
|
*/
|
||||||
|
function addWrappers(ownerDocument) {
|
||||||
|
var node,
|
||||||
|
nodes = ownerDocument.getElementsByTagName('*'),
|
||||||
|
index = nodes.length,
|
||||||
|
reElements = RegExp('^(?:' + getElements().join('|') + ')$', 'i'),
|
||||||
|
result = [];
|
||||||
|
|
||||||
|
while (index--) {
|
||||||
|
node = nodes[index];
|
||||||
|
if (reElements.test(node.nodeName)) {
|
||||||
|
result.push(node.applyElement(createWrapper(node)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a printable wrapper for the given element.
|
||||||
|
* @private
|
||||||
|
* @param {Element} element The element.
|
||||||
|
* @returns {Element} The wrapper.
|
||||||
|
*/
|
||||||
|
function createWrapper(element) {
|
||||||
|
var node,
|
||||||
|
nodes = element.attributes,
|
||||||
|
index = nodes.length,
|
||||||
|
wrapper = element.ownerDocument.createElement(shivNamespace + ':' + element.nodeName);
|
||||||
|
|
||||||
|
// copy element attributes to the wrapper
|
||||||
|
while (index--) {
|
||||||
|
node = nodes[index];
|
||||||
|
node.specified && wrapper.setAttribute(node.nodeName, node.nodeValue);
|
||||||
|
}
|
||||||
|
// copy element styles to the wrapper
|
||||||
|
wrapper.style.cssText = element.style.cssText;
|
||||||
|
return wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shivs the given CSS text.
|
||||||
|
* (eg. header{} becomes html5shiv\:header{})
|
||||||
|
* @private
|
||||||
|
* @param {String} cssText The CSS text to shiv.
|
||||||
|
* @returns {String} The shived CSS text.
|
||||||
|
*/
|
||||||
|
function shivCssText(cssText) {
|
||||||
|
var pair,
|
||||||
|
parts = cssText.split('{'),
|
||||||
|
index = parts.length,
|
||||||
|
reElements = RegExp('(^|[\\s,>+~])(' + getElements().join('|') + ')(?=[[\\s,>+~#.:]|$)', 'gi'),
|
||||||
|
replacement = '$1' + shivNamespace + '\\:$2';
|
||||||
|
|
||||||
|
while (index--) {
|
||||||
|
pair = parts[index] = parts[index].split('}');
|
||||||
|
pair[pair.length - 1] = pair[pair.length - 1].replace(reElements, replacement);
|
||||||
|
parts[index] = pair.join('}');
|
||||||
|
}
|
||||||
|
return parts.join('{');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the given wrappers, leaving the original elements.
|
||||||
|
* @private
|
||||||
|
* @params {Array} wrappers An array of printable wrappers.
|
||||||
|
*/
|
||||||
|
function removeWrappers(wrappers) {
|
||||||
|
var index = wrappers.length;
|
||||||
|
while (index--) {
|
||||||
|
wrappers[index].removeNode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shivs the given document for print.
|
||||||
|
* @memberOf html5
|
||||||
|
* @param {Document} ownerDocument The document to shiv.
|
||||||
|
* @returns {Document} The shived document.
|
||||||
|
*/
|
||||||
|
function shivPrint(ownerDocument) {
|
||||||
|
var shivedSheet,
|
||||||
|
wrappers,
|
||||||
|
data = getExpandoData(ownerDocument),
|
||||||
|
namespaces = ownerDocument.namespaces,
|
||||||
|
ownerWindow = ownerDocument.parentWindow;
|
||||||
|
|
||||||
|
if (!supportsShivableSheets || ownerDocument.printShived) {
|
||||||
|
return ownerDocument;
|
||||||
|
}
|
||||||
|
if (typeof namespaces[shivNamespace] == 'undefined') {
|
||||||
|
namespaces.add(shivNamespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeSheet() {
|
||||||
|
clearTimeout(data._removeSheetTimer);
|
||||||
|
if (shivedSheet) {
|
||||||
|
shivedSheet.removeNode(true);
|
||||||
|
}
|
||||||
|
shivedSheet= null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ownerWindow.attachEvent('onbeforeprint', function() {
|
||||||
|
|
||||||
|
removeSheet();
|
||||||
|
|
||||||
|
var imports,
|
||||||
|
length,
|
||||||
|
sheet,
|
||||||
|
collection = ownerDocument.styleSheets,
|
||||||
|
cssText = [],
|
||||||
|
index = collection.length,
|
||||||
|
sheets = Array(index);
|
||||||
|
|
||||||
|
// convert styleSheets collection to an array
|
||||||
|
while (index--) {
|
||||||
|
sheets[index] = collection[index];
|
||||||
|
}
|
||||||
|
// concat all style sheet CSS text
|
||||||
|
while ((sheet = sheets.pop())) {
|
||||||
|
// IE does not enforce a same origin policy for external style sheets...
|
||||||
|
// but has trouble with some dynamically created stylesheets
|
||||||
|
if (!sheet.disabled && reMedia.test(sheet.media)) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
imports = sheet.imports;
|
||||||
|
length = imports.length;
|
||||||
|
} catch(er){
|
||||||
|
length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (index = 0; index < length; index++) {
|
||||||
|
sheets.push(imports[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
cssText.push(sheet.cssText);
|
||||||
|
} catch(er){}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// wrap all HTML5 elements with printable elements and add the shived style sheet
|
||||||
|
cssText = shivCssText(cssText.reverse().join(''));
|
||||||
|
wrappers = addWrappers(ownerDocument);
|
||||||
|
shivedSheet = addStyleSheet(ownerDocument, cssText);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
ownerWindow.attachEvent('onafterprint', function() {
|
||||||
|
// remove wrappers, leaving the original elements, and remove the shived style sheet
|
||||||
|
removeWrappers(wrappers);
|
||||||
|
clearTimeout(data._removeSheetTimer);
|
||||||
|
data._removeSheetTimer = setTimeout(removeSheet, 500);
|
||||||
|
});
|
||||||
|
|
||||||
|
ownerDocument.printShived = true;
|
||||||
|
return ownerDocument;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// expose API
|
||||||
|
html5.type += ' print';
|
||||||
|
html5.shivPrint = shivPrint;
|
||||||
|
|
||||||
|
// shiv for print
|
||||||
|
shivPrint(document);
|
||||||
|
|
||||||
|
}(this, document));
|
301
js/libs/html5shiv.js
vendored
Normal file
301
js/libs/html5shiv.js
vendored
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
/**
|
||||||
|
* @preserve HTML5 Shiv v3.6.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
|
||||||
|
*/
|
||||||
|
;(function(window, document) {
|
||||||
|
/*jshint evil:true */
|
||||||
|
/** version */
|
||||||
|
var version = '3.6.2';
|
||||||
|
|
||||||
|
/** Preset options */
|
||||||
|
var options = window.html5 || {};
|
||||||
|
|
||||||
|
/** Used to skip problem elements */
|
||||||
|
var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
|
||||||
|
|
||||||
|
/** Not all elements can be cloned in IE **/
|
||||||
|
var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;
|
||||||
|
|
||||||
|
/** Detect whether the browser supports default html5 styles */
|
||||||
|
var supportsHtml5Styles;
|
||||||
|
|
||||||
|
/** Name of the expando, to work with multiple documents or to re-shiv one document */
|
||||||
|
var expando = '_html5shiv';
|
||||||
|
|
||||||
|
/** The id for the the documents expando */
|
||||||
|
var expanID = 0;
|
||||||
|
|
||||||
|
/** Cached data for each document */
|
||||||
|
var expandoData = {};
|
||||||
|
|
||||||
|
/** Detect whether the browser supports unknown elements */
|
||||||
|
var supportsUnknownElements;
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
try {
|
||||||
|
var a = document.createElement('a');
|
||||||
|
a.innerHTML = '<xyz></xyz>';
|
||||||
|
//if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles
|
||||||
|
supportsHtml5Styles = ('hidden' in a);
|
||||||
|
|
||||||
|
supportsUnknownElements = a.childNodes.length == 1 || (function() {
|
||||||
|
// assign a false positive if unable to shiv
|
||||||
|
(document.createElement)('a');
|
||||||
|
var frag = document.createDocumentFragment();
|
||||||
|
return (
|
||||||
|
typeof frag.cloneNode == 'undefined' ||
|
||||||
|
typeof frag.createDocumentFragment == 'undefined' ||
|
||||||
|
typeof frag.createElement == 'undefined'
|
||||||
|
);
|
||||||
|
}());
|
||||||
|
} catch(e) {
|
||||||
|
// assign a false positive if detection fails => unable to shiv
|
||||||
|
supportsHtml5Styles = true;
|
||||||
|
supportsUnknownElements = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}());
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a style sheet with the given CSS text and adds it to the document.
|
||||||
|
* @private
|
||||||
|
* @param {Document} ownerDocument The document.
|
||||||
|
* @param {String} cssText The CSS text.
|
||||||
|
* @returns {StyleSheet} The style element.
|
||||||
|
*/
|
||||||
|
function addStyleSheet(ownerDocument, cssText) {
|
||||||
|
var p = ownerDocument.createElement('p'),
|
||||||
|
parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
|
||||||
|
|
||||||
|
p.innerHTML = 'x<style>' + cssText + '</style>';
|
||||||
|
return parent.insertBefore(p.lastChild, parent.firstChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value of `html5.elements` as an array.
|
||||||
|
* @private
|
||||||
|
* @returns {Array} An array of shived element node names.
|
||||||
|
*/
|
||||||
|
function getElements() {
|
||||||
|
var elements = html5.elements;
|
||||||
|
return typeof elements == 'string' ? elements.split(' ') : elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the data associated to the given document
|
||||||
|
* @private
|
||||||
|
* @param {Document} ownerDocument The document.
|
||||||
|
* @returns {Object} An object of data.
|
||||||
|
*/
|
||||||
|
function getExpandoData(ownerDocument) {
|
||||||
|
var data = expandoData[ownerDocument[expando]];
|
||||||
|
if (!data) {
|
||||||
|
data = {};
|
||||||
|
expanID++;
|
||||||
|
ownerDocument[expando] = expanID;
|
||||||
|
expandoData[expanID] = data;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns a shived element for the given nodeName and document
|
||||||
|
* @memberOf html5
|
||||||
|
* @param {String} nodeName name of the element
|
||||||
|
* @param {Document} ownerDocument The context document.
|
||||||
|
* @returns {Object} The shived element.
|
||||||
|
*/
|
||||||
|
function createElement(nodeName, ownerDocument, data){
|
||||||
|
if (!ownerDocument) {
|
||||||
|
ownerDocument = document;
|
||||||
|
}
|
||||||
|
if(supportsUnknownElements){
|
||||||
|
return ownerDocument.createElement(nodeName);
|
||||||
|
}
|
||||||
|
if (!data) {
|
||||||
|
data = getExpandoData(ownerDocument);
|
||||||
|
}
|
||||||
|
var node;
|
||||||
|
|
||||||
|
if (data.cache[nodeName]) {
|
||||||
|
node = data.cache[nodeName].cloneNode();
|
||||||
|
} else if (saveClones.test(nodeName)) {
|
||||||
|
node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
|
||||||
|
} else {
|
||||||
|
node = data.createElem(nodeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Avoid adding some elements to fragments in IE < 9 because
|
||||||
|
// * Attributes like `name` or `type` cannot be set/changed once an element
|
||||||
|
// is inserted into a document/fragment
|
||||||
|
// * Link elements with `src` attributes that are inaccessible, as with
|
||||||
|
// a 403 response, will cause the tab/window to crash
|
||||||
|
// * Script elements appended to fragments will execute when their `src`
|
||||||
|
// or `text` property is set
|
||||||
|
return node.canHaveChildren && !reSkip.test(nodeName) ? data.frag.appendChild(node) : node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns a shived DocumentFragment for the given document
|
||||||
|
* @memberOf html5
|
||||||
|
* @param {Document} ownerDocument The context document.
|
||||||
|
* @returns {Object} The shived DocumentFragment.
|
||||||
|
*/
|
||||||
|
function createDocumentFragment(ownerDocument, data){
|
||||||
|
if (!ownerDocument) {
|
||||||
|
ownerDocument = document;
|
||||||
|
}
|
||||||
|
if(supportsUnknownElements){
|
||||||
|
return ownerDocument.createDocumentFragment();
|
||||||
|
}
|
||||||
|
data = data || getExpandoData(ownerDocument);
|
||||||
|
var clone = data.frag.cloneNode(),
|
||||||
|
i = 0,
|
||||||
|
elems = getElements(),
|
||||||
|
l = elems.length;
|
||||||
|
for(;i<l;i++){
|
||||||
|
clone.createElement(elems[i]);
|
||||||
|
}
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shivs the `createElement` and `createDocumentFragment` methods of the document.
|
||||||
|
* @private
|
||||||
|
* @param {Document|DocumentFragment} ownerDocument The document.
|
||||||
|
* @param {Object} data of the document.
|
||||||
|
*/
|
||||||
|
function shivMethods(ownerDocument, data) {
|
||||||
|
if (!data.cache) {
|
||||||
|
data.cache = {};
|
||||||
|
data.createElem = ownerDocument.createElement;
|
||||||
|
data.createFrag = ownerDocument.createDocumentFragment;
|
||||||
|
data.frag = data.createFrag();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ownerDocument.createElement = function(nodeName) {
|
||||||
|
//abort shiv
|
||||||
|
if (!html5.shivMethods) {
|
||||||
|
return data.createElem(nodeName);
|
||||||
|
}
|
||||||
|
return createElement(nodeName, ownerDocument, data);
|
||||||
|
};
|
||||||
|
|
||||||
|
ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' +
|
||||||
|
'var n=f.cloneNode(),c=n.createElement;' +
|
||||||
|
'h.shivMethods&&(' +
|
||||||
|
// unroll the `createElement` calls
|
||||||
|
getElements().join().replace(/\w+/g, function(nodeName) {
|
||||||
|
data.createElem(nodeName);
|
||||||
|
data.frag.createElement(nodeName);
|
||||||
|
return 'c("' + nodeName + '")';
|
||||||
|
}) +
|
||||||
|
');return n}'
|
||||||
|
)(html5, data.frag);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shivs the given document.
|
||||||
|
* @memberOf html5
|
||||||
|
* @param {Document} ownerDocument The document to shiv.
|
||||||
|
* @returns {Document} The shived document.
|
||||||
|
*/
|
||||||
|
function shivDocument(ownerDocument) {
|
||||||
|
if (!ownerDocument) {
|
||||||
|
ownerDocument = document;
|
||||||
|
}
|
||||||
|
var data = getExpandoData(ownerDocument);
|
||||||
|
|
||||||
|
if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) {
|
||||||
|
data.hasCSS = !!addStyleSheet(ownerDocument,
|
||||||
|
// corrects block display not defined in IE6/7/8/9
|
||||||
|
'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}' +
|
||||||
|
// adds styling not present in IE6/7/8/9
|
||||||
|
'mark{background:#FF0;color:#000}' +
|
||||||
|
// hides non-rendered elements
|
||||||
|
'template{display:none}'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!supportsUnknownElements) {
|
||||||
|
shivMethods(ownerDocument, data);
|
||||||
|
}
|
||||||
|
return ownerDocument;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The `html5` object is exposed so that more elements can be shived and
|
||||||
|
* existing shiving can be detected on iframes.
|
||||||
|
* @type Object
|
||||||
|
* @example
|
||||||
|
*
|
||||||
|
* // options can be changed before the script is included
|
||||||
|
* html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false };
|
||||||
|
*/
|
||||||
|
var html5 = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array or space separated string of node names of the elements to shiv.
|
||||||
|
* @memberOf html5
|
||||||
|
* @type Array|String
|
||||||
|
*/
|
||||||
|
'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* current version of html5shiv
|
||||||
|
*/
|
||||||
|
'version': version,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A flag to indicate that the HTML5 style sheet should be inserted.
|
||||||
|
* @memberOf html5
|
||||||
|
* @type Boolean
|
||||||
|
*/
|
||||||
|
'shivCSS': (options.shivCSS !== false),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is equal to true if a browser supports creating unknown/HTML5 elements
|
||||||
|
* @memberOf html5
|
||||||
|
* @type boolean
|
||||||
|
*/
|
||||||
|
'supportsUnknownElements': supportsUnknownElements,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A flag to indicate that the document's `createElement` and `createDocumentFragment`
|
||||||
|
* methods should be overwritten.
|
||||||
|
* @memberOf html5
|
||||||
|
* @type Boolean
|
||||||
|
*/
|
||||||
|
'shivMethods': (options.shivMethods !== false),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A string to describe the type of `html5` object ("default" or "default print").
|
||||||
|
* @memberOf html5
|
||||||
|
* @type String
|
||||||
|
*/
|
||||||
|
'type': 'default',
|
||||||
|
|
||||||
|
// shivs the document according to the specified `html5` object options
|
||||||
|
'shivDocument': shivDocument,
|
||||||
|
|
||||||
|
//creates a shived element
|
||||||
|
createElement: createElement,
|
||||||
|
|
||||||
|
//creates a shived documentFragment
|
||||||
|
createDocumentFragment: createDocumentFragment
|
||||||
|
};
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// expose html5
|
||||||
|
window.html5 = html5;
|
||||||
|
|
||||||
|
// shiv the document
|
||||||
|
shivDocument(document);
|
||||||
|
|
||||||
|
}(this, document));
|
154
js/previewRendering_v01.js
Normal file
154
js/previewRendering_v01.js
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
//*
|
||||||
|
var preview;
|
||||||
|
var previewCtx;
|
||||||
|
|
||||||
|
var svgPathRegExp = /[LM]\d* \d*/ig;
|
||||||
|
var svgPathParamsRegExp = /([LM])(\d*) (\d*)/;
|
||||||
|
|
||||||
|
var prevRedrawTime = new Date().getTime();
|
||||||
|
var redrawInterval = 1000 / 20; // ms
|
||||||
|
|
||||||
|
function initPreviewRendering() {
|
||||||
|
console.log("f:initPreviewRendering()");
|
||||||
|
|
||||||
|
preview = document.getElementById('preview');
|
||||||
|
previewCtx = preview.getContext('2d');
|
||||||
|
|
||||||
|
redrawPreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
//var numLayers = 100; //50
|
||||||
|
var numLayers = 100; // 100
|
||||||
|
var globalScale = 0.3; // global scale of preview (width preview / width canvas)
|
||||||
|
var globalAlpha = 0.20; // global alpha of preview
|
||||||
|
var scaleY = 0.4; // additional vertical scale per path for 3d effect
|
||||||
|
var viewerScale = 0.65; // additional scale to fit into preview nicely (otherwise is fills out totally)
|
||||||
|
var strokeWidth = 2; //4;
|
||||||
|
//var rStep = Math.PI/40; //Math.PI/40; //
|
||||||
|
var rStep = Math.PI/45; // Math.PI/180; //Math.PI/40; //
|
||||||
|
var yStep = 3; //6;
|
||||||
|
//var svgWidth = 500; // 650 //parseInt($(svg).css("width"));
|
||||||
|
//var svgHeight = 450; //450; //parseInt($(svg).css("height"));
|
||||||
|
var layerCX = (canvasWidth / 2) * globalScale; // defined in canvasDrawing_v01.js
|
||||||
|
var layerCY = (canvasHeight / 2) * globalScale; // defined in canvasDrawing_v01.js
|
||||||
|
var layerOffsetY= 330;
|
||||||
|
var prevX = 0;
|
||||||
|
var prevY = 0;
|
||||||
|
var highlight = true; //highlight bottom, middle and top layers
|
||||||
|
|
||||||
|
var linesRaw = "";
|
||||||
|
function redrawPreview() {
|
||||||
|
//*/
|
||||||
|
//TODO
|
||||||
|
/*
|
||||||
|
het up/down en twist left/right gaat nu wat traag. Juist dat gaat veel sneller met de toDataURL oplossing
|
||||||
|
Is het een idee om op het einde van een touchevent wel de image versie te renderen maar tijdens het tekenen
|
||||||
|
niet?
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (_points.length < 2) return;
|
||||||
|
|
||||||
|
var y = 0;
|
||||||
|
var r = 0;
|
||||||
|
|
||||||
|
//preview.width = preview.width;
|
||||||
|
previewCtx.clearRect(0, 0, preview.width, preview.height);
|
||||||
|
previewCtx.lineWidth = strokeWidth;
|
||||||
|
previewCtx.strokeStyle = '#f00'; //"rgba(255,255,0,0)";
|
||||||
|
|
||||||
|
for(var i = 0; i < numLayers; i++) {
|
||||||
|
|
||||||
|
if(i == 0 || i == Math.floor(numLayers/2) || i == numLayers-1){
|
||||||
|
previewCtx.globalAlpha = 1;
|
||||||
|
} else {
|
||||||
|
previewCtx.globalAlpha = globalAlpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
previewCtx.save();
|
||||||
|
|
||||||
|
previewCtx.translate(layerCX, layerOffsetY + layerCY + y);
|
||||||
|
// previewCtx.setTransform(1, 0, 0, scaleY, layerCX, layerOffsetY+layerCY+y);
|
||||||
|
previewCtx.scale(viewerScale, scaleY * viewerScale);
|
||||||
|
previewCtx.rotate(r);
|
||||||
|
previewCtx.translate((-doodleTransform[0]) * (globalScale * doodleTransform[2]), (-doodleTransform[1]) * (globalScale * doodleTransform[3]));
|
||||||
|
// previewCtx.translate(-layerCX,-layerCY);
|
||||||
|
// previewCtx.translate(-doodleTransform[0] * globalScale, -doodleTransform[1] * globalScale);
|
||||||
|
|
||||||
|
// previewCtx.setTransform(doodleTransform[2], 0, 0, doodleTransform[3], 0, 0);
|
||||||
|
|
||||||
|
var adjustedDoodlePoint = centeredAndScaledDoodlePoint(_points[0]);
|
||||||
|
|
||||||
|
previewCtx.beginPath();
|
||||||
|
previewCtx.moveTo(adjustedDoodlePoint.x, adjustedDoodlePoint.y);
|
||||||
|
for(var j = 1; j < _points.length; j++) {
|
||||||
|
adjustedDoodlePoint = centeredAndScaledDoodlePoint(_points[j])
|
||||||
|
previewCtx.lineTo(adjustedDoodlePoint.x, adjustedDoodlePoint.y);
|
||||||
|
}
|
||||||
|
previewCtx.stroke();
|
||||||
|
|
||||||
|
y -= yStep;
|
||||||
|
r += rStep;
|
||||||
|
previewCtx.restore();
|
||||||
|
}
|
||||||
|
previewCtx.globalAlpha = globalAlpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
function centeredAndScaledDoodlePoint(p) {
|
||||||
|
var obj = { x: 0, y: 0};
|
||||||
|
|
||||||
|
obj.x = (p[0] - ((doodleBounds[2] - doodleBounds[0])/2)) * (globalScale * doodleTransform[2]);
|
||||||
|
obj.y = (p[1] - ((doodleBounds[3] - doodleBounds[1])/2)) * (globalScale * doodleTransform[3]);
|
||||||
|
// obj.x = (p[0] - (doodleBounds[2] - doodleBounds[0])) * (globalScale * doodleTransform[2]);
|
||||||
|
// obj.y = (p[1] - (doodleBounds[3] - doodleBounds[1])) * (globalScale * doodleTransform[3]);
|
||||||
|
// obj.x = (p[0] - doodleTransform[0]) * (globalScale * doodleTransform[2]);
|
||||||
|
// obj.y = (p[1] - doodleTransform[1]) * (globalScale * doodleTransform[3]);
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
function updatePreview(x, y, move) {
|
||||||
|
x *= globalScale;
|
||||||
|
y *= globalScale;
|
||||||
|
|
||||||
|
if(!move) {
|
||||||
|
var tY = 0;
|
||||||
|
var r = 0;
|
||||||
|
|
||||||
|
if(!highlight) {
|
||||||
|
previewCtx.globalAlpha = globalAlpha;
|
||||||
|
previewCtx.beginPath();
|
||||||
|
}
|
||||||
|
for(var i=0;i<numLayers;i++) {
|
||||||
|
|
||||||
|
if(highlight && (i == 0 || i == numLayers/2 || i == numLayers-1)){
|
||||||
|
previewCtx.stroke();
|
||||||
|
previewCtx.globalAlpha = 1;
|
||||||
|
previewCtx.beginPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
previewCtx.save();
|
||||||
|
previewCtx.translate(layerCX,layerOffsetY+layerCY+tY);
|
||||||
|
previewCtx.scale(1, scaleY)
|
||||||
|
previewCtx.rotate(r);
|
||||||
|
previewCtx.translate(-layerCX,-layerCY);
|
||||||
|
|
||||||
|
previewCtx.moveTo(prevX,prevY);
|
||||||
|
previewCtx.lineTo(x,y);
|
||||||
|
|
||||||
|
tY -= yStep;
|
||||||
|
r += rStep;
|
||||||
|
previewCtx.restore();
|
||||||
|
|
||||||
|
if(highlight && (i == 0 || i == numLayers/2 || i == numLayers-1)){
|
||||||
|
previewCtx.stroke();
|
||||||
|
previewCtx.globalAlpha = globalAlpha;
|
||||||
|
previewCtx.beginPath();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
previewCtx.stroke();
|
||||||
|
prevX = x;
|
||||||
|
prevY = y;
|
||||||
|
}
|
||||||
|
//*/
|
46
js/settings.js
Normal file
46
js/settings.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
var objectHeight = 20;
|
||||||
|
var layerHeight = .2;
|
||||||
|
var wallThickness = .5;
|
||||||
|
var hop = 0;
|
||||||
|
var speed = 70;
|
||||||
|
var travelSpeed = 200;
|
||||||
|
var enableTraveling = true;
|
||||||
|
var filamentThickness = 2.89;
|
||||||
|
var minScale = .3;
|
||||||
|
var maxScale = 1;
|
||||||
|
var shape = "%";
|
||||||
|
var twists = 0;
|
||||||
|
var useSubLayers = true;
|
||||||
|
var debug = false;
|
||||||
|
var loglevel = 2;
|
||||||
|
var zOffset = 0;
|
||||||
|
var serverport = 8888;
|
||||||
|
var autoLoadImage = "hand.txt";
|
||||||
|
var loadOffset = [0, 0]; // x en y ?
|
||||||
|
var showWarmUp = true;
|
||||||
|
var loopAlways = false;
|
||||||
|
var firstLayerSlow = true;
|
||||||
|
var useSubpathColors = false;
|
||||||
|
var autoWarmUp = true;
|
||||||
|
var maxObjectHeight = 150;
|
||||||
|
var maxScaleDifference = .1;
|
||||||
|
var frameRate = 60;
|
||||||
|
var quitOnEscape = true;
|
||||||
|
var screenToMillimeterScale = .3; // 0.3
|
||||||
|
var targetTemperature = 230;
|
||||||
|
var simplifyiterations = 10;
|
||||||
|
var simplifyminNumPoints = 15;
|
||||||
|
var simplifyminDistance = 3;
|
||||||
|
var retractionspeed = 50;
|
||||||
|
var retractionminDistance = 5;
|
||||||
|
var retractionamount = 3;
|
||||||
|
var sideis3D = true;
|
||||||
|
var sidevisible = true;
|
||||||
|
var sidebounds = [900, 210, 131, 390];
|
||||||
|
var sideborder = [880, 169, 2, 471];
|
||||||
|
var windowbounds = [0, 0, 800, 500];
|
||||||
|
var windowcenter = true;
|
||||||
|
var windowfullscreen = false;
|
||||||
|
var autoWarmUpCommand = "M104 S230";
|
||||||
|
var checkTemperatureInterval = 3;
|
||||||
|
var autoWarmUpDelay = 3;
|
Loading…
Reference in New Issue
Block a user