first try with svg rendering

dev-2.0-svg
Michael Aschauer 2017-01-19 23:00:37 +01:00
rodzic 47dbbcfe31
commit b262cf2fa0
10 zmienionych plików z 4259 dodań i 252 usunięć

Wyświetl plik

@ -3,7 +3,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>TurtleStitch </title>
<link rel="shortcut icon" href="stitchcode/favicon-32x32.png" type="image/png">
<link rel="shortcut icon" href="stitchcode/favicon-32x32.png" type="image/png" />
<script type="text/javascript" src="morphic.js"></script>
<script type="text/javascript" src="widgets.js"></script>
<script type="text/javascript" src="blocks.js"></script>
@ -19,15 +19,24 @@
<script type="text/javascript" src="locale.js"></script>
<script type="text/javascript" src="cloud.js"></script>
<script type="text/javascript" src="sha512.js"></script>
<script type="text/javascript" src="stitchcode/jquery.js"></script>
<script type="text/javascript" src="stitchcode/Filesaver.js"></script>
<script type="text/javascript" src="stitchcode/tstitch.js"></script>
<script type="text/javascript" src="stitchcode/canvg/rgbcolor.js"></script>
<script type="text/javascript" src="stitchcode/canvg/StackBlur.js"></script>
<script type="text/javascript" src="stitchcode/canvg/canvg.js"></script>
<script type="text/javascript" src="stitchcode/tstools.js"></script>
<script type="text/javascript" src="stitchcode/commandCache.js"></script>
<script type="text/javascript" src="stitchcode/turtlestitch.js"></script>
<script type="text/javascript" src="stitchcode/blocks.js"></script>
<script type="text/javascript" src="stitchcode/objects.js"></script>
<script type="text/javascript" src="stitchcode/gui.js"></script>
<script type="text/javascript" src="stitchcode/gui-cloud.js"></script>
<script type="text/javascript" src="stitchcode/cloud.js"></script>
<script type="text/javascript">
var world;
window.onload = function () {
@ -40,11 +49,29 @@
requestAnimationFrame(loop);
world.doOneCycle();
}
</script>
</script>
</head>
<body style="margin: 0;">
<canvas id="world" tabindex="1" style="position: absolute;"></canvas>
<div name="bug" id="bug" style="background:white;font-size:70%;position:absolute;
width:100%;height:10%;top:90%;overflow:auto;display:none"></div>
<canvas width="480" height="360" id="svg" style="background:white;
position:absolute;right:0;bottom:0;width:480px;height:360px;
border:1px solid #c0c0c0"></canvas>
<div id="svg2" style="background:white;font-size:60%;position:absolute;
width:480px;height:360px;left:34%;bottom:0;
border:1px solid #c0c0c0;
display:none" ></div>
<div name="debug" id="debug" style="background:white;font-size:60%;position:absolute;
width:33%;height:20%;left:33%;bottom:0;overflow:auto;border:1px solid #c0c0c0;
"></div>
<textarea id="code" width="480" height="360" style="background:white;font-size:60%;position:absolute;
width:33%;height:20%;left:0;bottom:0;overflow:auto;border:1px solid #c0c0c0"></textarea>
</body>
</html>

Wyświetl plik

@ -0,0 +1,633 @@
/*
StackBlur - a fast almost Gaussian Blur For Canvas
Version: 0.5
Author: Mario Klingemann
Contact: mario@quasimondo.com
Website: http://www.quasimondo.com/StackBlurForCanvas
Twitter: @quasimondo
In case you find this class useful - especially in commercial projects -
I am not totally unhappy for a small donation to my PayPal account
mario@quasimondo.de
Or support me on flattr:
https://flattr.com/thing/72791/StackBlur-a-fast-almost-Gaussian-Blur-Effect-for-CanvasJavascript
Copyright (c) 2010 Mario Klingemann
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
var mul_table = [
512,512,456,512,328,456,335,512,405,328,271,456,388,335,292,512,
454,405,364,328,298,271,496,456,420,388,360,335,312,292,273,512,
482,454,428,405,383,364,345,328,312,298,284,271,259,496,475,456,
437,420,404,388,374,360,347,335,323,312,302,292,282,273,265,512,
497,482,468,454,441,428,417,405,394,383,373,364,354,345,337,328,
320,312,305,298,291,284,278,271,265,259,507,496,485,475,465,456,
446,437,428,420,412,404,396,388,381,374,367,360,354,347,341,335,
329,323,318,312,307,302,297,292,287,282,278,273,269,265,261,512,
505,497,489,482,475,468,461,454,447,441,435,428,422,417,411,405,
399,394,389,383,378,373,368,364,359,354,350,345,341,337,332,328,
324,320,316,312,309,305,301,298,294,291,287,284,281,278,274,271,
268,265,262,259,257,507,501,496,491,485,480,475,470,465,460,456,
451,446,442,437,433,428,424,420,416,412,408,404,400,396,392,388,
385,381,377,374,370,367,363,360,357,354,350,347,344,341,338,335,
332,329,326,323,320,318,315,312,310,307,304,302,299,297,294,292,
289,287,285,282,280,278,275,273,271,269,267,265,263,261,259];
var shg_table = [
9, 11, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17,
17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23,
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24 ];
function premultiplyAlpha(imageData)
{
var pixels = imageData.data;
var size = imageData.width * imageData.height * 4;
for (var i=0; i<size; i+=4)
{
var a = pixels[i+3] / 255;
pixels[i ] *= a;
pixels[i+1] *= a;
pixels[i+2] *= a;
}
}
function unpremultiplyAlpha(imageData)
{
var pixels = imageData.data;
var size = imageData.width * imageData.height * 4;
for (var i=0; i<size; i+=4)
{
var a = pixels[i+3];
if (a != 0)
{
a = 255 / a;
pixels[i ] *= a;
pixels[i+1] *= a;
pixels[i+2] *= a;
}
}
}
function stackBlurImage( imageID, canvasID, radius, blurAlphaChannel )
{
var img = document.getElementById( imageID );
var w = img.naturalWidth;
var h = img.naturalHeight;
var canvas = document.getElementById( canvasID );
canvas.style.width = w + "px";
canvas.style.height = h + "px";
canvas.width = w;
canvas.height = h;
var context = canvas.getContext("2d");
context.clearRect( 0, 0, w, h );
context.drawImage( img, 0, 0 );
if ( isNaN(radius) || radius < 1 ) return;
if ( blurAlphaChannel )
stackBlurCanvasRGBA( canvasID, 0, 0, w, h, radius );
else
stackBlurCanvasRGB( canvasID, 0, 0, w, h, radius );
}
function stackBlurCanvasRGBA( id, top_x, top_y, width, height, radius )
{
if ( isNaN(radius) || radius < 1 ) return;
radius |= 0;
var canvas = document.getElementById( id );
var context = canvas.getContext("2d");
var imageData;
try {
try {
imageData = context.getImageData( top_x, top_y, width, height );
} catch(e) {
// NOTE: this part is supposedly only needed if you want to work with local files
// so it might be okay to remove the whole try/catch block and just use
// imageData = context.getImageData( top_x, top_y, width, height );
try {
netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
imageData = context.getImageData( top_x, top_y, width, height );
} catch(e) {
alert("Cannot access local image");
throw new Error("unable to access local image data: " + e);
return;
}
}
} catch(e) {
alert("Cannot access image");
throw new Error("unable to access image data: " + e);
}
premultiplyAlpha(imageData);
var pixels = imageData.data;
var x, y, i, p, yp, yi, yw, r_sum, g_sum, b_sum, a_sum,
r_out_sum, g_out_sum, b_out_sum, a_out_sum,
r_in_sum, g_in_sum, b_in_sum, a_in_sum,
pr, pg, pb, pa, rbs;
var div = radius + radius + 1;
var w4 = width << 2;
var widthMinus1 = width - 1;
var heightMinus1 = height - 1;
var radiusPlus1 = radius + 1;
var sumFactor = radiusPlus1 * ( radiusPlus1 + 1 ) / 2;
var stackStart = new BlurStack();
var stack = stackStart;
for ( i = 1; i < div; i++ )
{
stack = stack.next = new BlurStack();
if ( i == radiusPlus1 ) var stackEnd = stack;
}
stack.next = stackStart;
var stackIn = null;
var stackOut = null;
yw = yi = 0;
var mul_sum = mul_table[radius];
var shg_sum = shg_table[radius];
for ( y = 0; y < height; y++ )
{
r_in_sum = g_in_sum = b_in_sum = a_in_sum = r_sum = g_sum = b_sum = a_sum = 0;
r_out_sum = radiusPlus1 * ( pr = pixels[yi] );
g_out_sum = radiusPlus1 * ( pg = pixels[yi+1] );
b_out_sum = radiusPlus1 * ( pb = pixels[yi+2] );
a_out_sum = radiusPlus1 * ( pa = pixels[yi+3] );
r_sum += sumFactor * pr;
g_sum += sumFactor * pg;
b_sum += sumFactor * pb;
a_sum += sumFactor * pa;
stack = stackStart;
for( i = 0; i < radiusPlus1; i++ )
{
stack.r = pr;
stack.g = pg;
stack.b = pb;
stack.a = pa;
stack = stack.next;
}
for( i = 1; i < radiusPlus1; i++ )
{
p = yi + (( widthMinus1 < i ? widthMinus1 : i ) << 2 );
r_sum += ( stack.r = ( pr = pixels[p])) * ( rbs = radiusPlus1 - i );
g_sum += ( stack.g = ( pg = pixels[p+1])) * rbs;
b_sum += ( stack.b = ( pb = pixels[p+2])) * rbs;
a_sum += ( stack.a = ( pa = pixels[p+3])) * rbs;
r_in_sum += pr;
g_in_sum += pg;
b_in_sum += pb;
a_in_sum += pa;
stack = stack.next;
}
stackIn = stackStart;
stackOut = stackEnd;
for ( x = 0; x < width; x++ )
{
pixels[yi] = (r_sum * mul_sum) >> shg_sum;
pixels[yi+1] = (g_sum * mul_sum) >> shg_sum;
pixels[yi+2] = (b_sum * mul_sum) >> shg_sum;
pixels[yi+3] = (a_sum * mul_sum) >> shg_sum;
r_sum -= r_out_sum;
g_sum -= g_out_sum;
b_sum -= b_out_sum;
a_sum -= a_out_sum;
r_out_sum -= stackIn.r;
g_out_sum -= stackIn.g;
b_out_sum -= stackIn.b;
a_out_sum -= stackIn.a;
p = ( yw + ( ( p = x + radius + 1 ) < widthMinus1 ? p : widthMinus1 ) ) << 2;
r_in_sum += ( stackIn.r = pixels[p]);
g_in_sum += ( stackIn.g = pixels[p+1]);
b_in_sum += ( stackIn.b = pixels[p+2]);
a_in_sum += ( stackIn.a = pixels[p+3]);
r_sum += r_in_sum;
g_sum += g_in_sum;
b_sum += b_in_sum;
a_sum += a_in_sum;
stackIn = stackIn.next;
r_out_sum += ( pr = stackOut.r );
g_out_sum += ( pg = stackOut.g );
b_out_sum += ( pb = stackOut.b );
a_out_sum += ( pa = stackOut.a );
r_in_sum -= pr;
g_in_sum -= pg;
b_in_sum -= pb;
a_in_sum -= pa;
stackOut = stackOut.next;
yi += 4;
}
yw += width;
}
for ( x = 0; x < width; x++ )
{
g_in_sum = b_in_sum = a_in_sum = r_in_sum = g_sum = b_sum = a_sum = r_sum = 0;
yi = x << 2;
r_out_sum = radiusPlus1 * ( pr = pixels[yi]);
g_out_sum = radiusPlus1 * ( pg = pixels[yi+1]);
b_out_sum = radiusPlus1 * ( pb = pixels[yi+2]);
a_out_sum = radiusPlus1 * ( pa = pixels[yi+3]);
r_sum += sumFactor * pr;
g_sum += sumFactor * pg;
b_sum += sumFactor * pb;
a_sum += sumFactor * pa;
stack = stackStart;
for( i = 0; i < radiusPlus1; i++ )
{
stack.r = pr;
stack.g = pg;
stack.b = pb;
stack.a = pa;
stack = stack.next;
}
yp = width;
for( i = 1; i <= radius; i++ )
{
yi = ( yp + x ) << 2;
r_sum += ( stack.r = ( pr = pixels[yi])) * ( rbs = radiusPlus1 - i );
g_sum += ( stack.g = ( pg = pixels[yi+1])) * rbs;
b_sum += ( stack.b = ( pb = pixels[yi+2])) * rbs;
a_sum += ( stack.a = ( pa = pixels[yi+3])) * rbs;
r_in_sum += pr;
g_in_sum += pg;
b_in_sum += pb;
a_in_sum += pa;
stack = stack.next;
if( i < heightMinus1 )
{
yp += width;
}
}
yi = x;
stackIn = stackStart;
stackOut = stackEnd;
for ( y = 0; y < height; y++ )
{
p = yi << 2;
pixels[p] = (r_sum * mul_sum) >> shg_sum;
pixels[p+1] = (g_sum * mul_sum) >> shg_sum;
pixels[p+2] = (b_sum * mul_sum) >> shg_sum;
pixels[p+3] = (a_sum * mul_sum) >> shg_sum;
r_sum -= r_out_sum;
g_sum -= g_out_sum;
b_sum -= b_out_sum;
a_sum -= a_out_sum;
r_out_sum -= stackIn.r;
g_out_sum -= stackIn.g;
b_out_sum -= stackIn.b;
a_out_sum -= stackIn.a;
p = ( x + (( ( p = y + radiusPlus1) < heightMinus1 ? p : heightMinus1 ) * width )) << 2;
r_sum += ( r_in_sum += ( stackIn.r = pixels[p]));
g_sum += ( g_in_sum += ( stackIn.g = pixels[p+1]));
b_sum += ( b_in_sum += ( stackIn.b = pixels[p+2]));
a_sum += ( a_in_sum += ( stackIn.a = pixels[p+3]));
stackIn = stackIn.next;
r_out_sum += ( pr = stackOut.r );
g_out_sum += ( pg = stackOut.g );
b_out_sum += ( pb = stackOut.b );
a_out_sum += ( pa = stackOut.a );
r_in_sum -= pr;
g_in_sum -= pg;
b_in_sum -= pb;
a_in_sum -= pa;
stackOut = stackOut.next;
yi += width;
}
}
unpremultiplyAlpha(imageData);
context.putImageData( imageData, top_x, top_y );
}
function stackBlurCanvasRGB( id, top_x, top_y, width, height, radius )
{
if ( isNaN(radius) || radius < 1 ) return;
radius |= 0;
var canvas = document.getElementById( id );
var context = canvas.getContext("2d");
var imageData;
try {
try {
imageData = context.getImageData( top_x, top_y, width, height );
} catch(e) {
// NOTE: this part is supposedly only needed if you want to work with local files
// so it might be okay to remove the whole try/catch block and just use
// imageData = context.getImageData( top_x, top_y, width, height );
try {
netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
imageData = context.getImageData( top_x, top_y, width, height );
} catch(e) {
alert("Cannot access local image");
throw new Error("unable to access local image data: " + e);
return;
}
}
} catch(e) {
alert("Cannot access image");
throw new Error("unable to access image data: " + e);
}
var pixels = imageData.data;
var x, y, i, p, yp, yi, yw, r_sum, g_sum, b_sum,
r_out_sum, g_out_sum, b_out_sum,
r_in_sum, g_in_sum, b_in_sum,
pr, pg, pb, rbs;
var div = radius + radius + 1;
var w4 = width << 2;
var widthMinus1 = width - 1;
var heightMinus1 = height - 1;
var radiusPlus1 = radius + 1;
var sumFactor = radiusPlus1 * ( radiusPlus1 + 1 ) / 2;
var stackStart = new BlurStack();
var stack = stackStart;
for ( i = 1; i < div; i++ )
{
stack = stack.next = new BlurStack();
if ( i == radiusPlus1 ) var stackEnd = stack;
}
stack.next = stackStart;
var stackIn = null;
var stackOut = null;
yw = yi = 0;
var mul_sum = mul_table[radius];
var shg_sum = shg_table[radius];
for ( y = 0; y < height; y++ )
{
r_in_sum = g_in_sum = b_in_sum = r_sum = g_sum = b_sum = 0;
r_out_sum = radiusPlus1 * ( pr = pixels[yi] );
g_out_sum = radiusPlus1 * ( pg = pixels[yi+1] );
b_out_sum = radiusPlus1 * ( pb = pixels[yi+2] );
r_sum += sumFactor * pr;
g_sum += sumFactor * pg;
b_sum += sumFactor * pb;
stack = stackStart;
for( i = 0; i < radiusPlus1; i++ )
{
stack.r = pr;
stack.g = pg;
stack.b = pb;
stack = stack.next;
}
for( i = 1; i < radiusPlus1; i++ )
{
p = yi + (( widthMinus1 < i ? widthMinus1 : i ) << 2 );
r_sum += ( stack.r = ( pr = pixels[p])) * ( rbs = radiusPlus1 - i );
g_sum += ( stack.g = ( pg = pixels[p+1])) * rbs;
b_sum += ( stack.b = ( pb = pixels[p+2])) * rbs;
r_in_sum += pr;
g_in_sum += pg;
b_in_sum += pb;
stack = stack.next;
}
stackIn = stackStart;
stackOut = stackEnd;
for ( x = 0; x < width; x++ )
{
pixels[yi] = (r_sum * mul_sum) >> shg_sum;
pixels[yi+1] = (g_sum * mul_sum) >> shg_sum;
pixels[yi+2] = (b_sum * mul_sum) >> shg_sum;
r_sum -= r_out_sum;
g_sum -= g_out_sum;
b_sum -= b_out_sum;
r_out_sum -= stackIn.r;
g_out_sum -= stackIn.g;
b_out_sum -= stackIn.b;
p = ( yw + ( ( p = x + radius + 1 ) < widthMinus1 ? p : widthMinus1 ) ) << 2;
r_in_sum += ( stackIn.r = pixels[p]);
g_in_sum += ( stackIn.g = pixels[p+1]);
b_in_sum += ( stackIn.b = pixels[p+2]);
r_sum += r_in_sum;
g_sum += g_in_sum;
b_sum += b_in_sum;
stackIn = stackIn.next;
r_out_sum += ( pr = stackOut.r );
g_out_sum += ( pg = stackOut.g );
b_out_sum += ( pb = stackOut.b );
r_in_sum -= pr;
g_in_sum -= pg;
b_in_sum -= pb;
stackOut = stackOut.next;
yi += 4;
}
yw += width;
}
for ( x = 0; x < width; x++ )
{
g_in_sum = b_in_sum = r_in_sum = g_sum = b_sum = r_sum = 0;
yi = x << 2;
r_out_sum = radiusPlus1 * ( pr = pixels[yi]);
g_out_sum = radiusPlus1 * ( pg = pixels[yi+1]);
b_out_sum = radiusPlus1 * ( pb = pixels[yi+2]);
r_sum += sumFactor * pr;
g_sum += sumFactor * pg;
b_sum += sumFactor * pb;
stack = stackStart;
for( i = 0; i < radiusPlus1; i++ )
{
stack.r = pr;
stack.g = pg;
stack.b = pb;
stack = stack.next;
}
yp = width;
for( i = 1; i <= radius; i++ )
{
yi = ( yp + x ) << 2;
r_sum += ( stack.r = ( pr = pixels[yi])) * ( rbs = radiusPlus1 - i );
g_sum += ( stack.g = ( pg = pixels[yi+1])) * rbs;
b_sum += ( stack.b = ( pb = pixels[yi+2])) * rbs;
r_in_sum += pr;
g_in_sum += pg;
b_in_sum += pb;
stack = stack.next;
if( i < heightMinus1 )
{
yp += width;
}
}
yi = x;
stackIn = stackStart;
stackOut = stackEnd;
for ( y = 0; y < height; y++ )
{
p = yi << 2;
pixels[p] = (r_sum * mul_sum) >> shg_sum;
pixels[p+1] = (g_sum * mul_sum) >> shg_sum;
pixels[p+2] = (b_sum * mul_sum) >> shg_sum;
r_sum -= r_out_sum;
g_sum -= g_out_sum;
b_sum -= b_out_sum;
r_out_sum -= stackIn.r;
g_out_sum -= stackIn.g;
b_out_sum -= stackIn.b;
p = ( x + (( ( p = y + radiusPlus1) < heightMinus1 ? p : heightMinus1 ) * width )) << 2;
r_sum += ( r_in_sum += ( stackIn.r = pixels[p]));
g_sum += ( g_in_sum += ( stackIn.g = pixels[p+1]));
b_sum += ( b_in_sum += ( stackIn.b = pixels[p+2]));
stackIn = stackIn.next;
r_out_sum += ( pr = stackOut.r );
g_out_sum += ( pg = stackOut.g );
b_out_sum += ( pb = stackOut.b );
r_in_sum -= pr;
g_in_sum -= pg;
b_in_sum -= pb;
stackOut = stackOut.next;
yi += width;
}
}
context.putImageData( imageData, top_x, top_y );
}
function BlurStack()
{
this.r = 0;
this.g = 0;
this.b = 0;
this.a = 0;
this.next = null;
}

Plik diff jest za duży Load Diff

Wyświetl plik

@ -0,0 +1,288 @@
/**
* A class to parse color values
* @author Stoyan Stefanov <sstoo@gmail.com>
* @link http://www.phpied.com/rgb-color-parser-in-javascript/
* @license Use it if you like it
*/
function RGBColor(color_string)
{
this.ok = false;
// strip any leading #
if (color_string.charAt(0) == '#') { // remove # if any
color_string = color_string.substr(1,6);
}
color_string = color_string.replace(/ /g,'');
color_string = color_string.toLowerCase();
// before getting into regexps, try simple matches
// and overwrite the input
var simple_colors = {
aliceblue: 'f0f8ff',
antiquewhite: 'faebd7',
aqua: '00ffff',
aquamarine: '7fffd4',
azure: 'f0ffff',
beige: 'f5f5dc',
bisque: 'ffe4c4',
black: '000000',
blanchedalmond: 'ffebcd',
blue: '0000ff',
blueviolet: '8a2be2',
brown: 'a52a2a',
burlywood: 'deb887',
cadetblue: '5f9ea0',
chartreuse: '7fff00',
chocolate: 'd2691e',
coral: 'ff7f50',
cornflowerblue: '6495ed',
cornsilk: 'fff8dc',
crimson: 'dc143c',
cyan: '00ffff',
darkblue: '00008b',
darkcyan: '008b8b',
darkgoldenrod: 'b8860b',
darkgray: 'a9a9a9',
darkgreen: '006400',
darkkhaki: 'bdb76b',
darkmagenta: '8b008b',
darkolivegreen: '556b2f',
darkorange: 'ff8c00',
darkorchid: '9932cc',
darkred: '8b0000',
darksalmon: 'e9967a',
darkseagreen: '8fbc8f',
darkslateblue: '483d8b',
darkslategray: '2f4f4f',
darkturquoise: '00ced1',
darkviolet: '9400d3',
deeppink: 'ff1493',
deepskyblue: '00bfff',
dimgray: '696969',
dodgerblue: '1e90ff',
feldspar: 'd19275',
firebrick: 'b22222',
floralwhite: 'fffaf0',
forestgreen: '228b22',
fuchsia: 'ff00ff',
gainsboro: 'dcdcdc',
ghostwhite: 'f8f8ff',
gold: 'ffd700',
goldenrod: 'daa520',
gray: '808080',
green: '008000',
greenyellow: 'adff2f',
honeydew: 'f0fff0',
hotpink: 'ff69b4',
indianred : 'cd5c5c',
indigo : '4b0082',
ivory: 'fffff0',
khaki: 'f0e68c',
lavender: 'e6e6fa',
lavenderblush: 'fff0f5',
lawngreen: '7cfc00',
lemonchiffon: 'fffacd',
lightblue: 'add8e6',
lightcoral: 'f08080',
lightcyan: 'e0ffff',
lightgoldenrodyellow: 'fafad2',
lightgrey: 'd3d3d3',
lightgreen: '90ee90',
lightpink: 'ffb6c1',
lightsalmon: 'ffa07a',
lightseagreen: '20b2aa',
lightskyblue: '87cefa',
lightslateblue: '8470ff',
lightslategray: '778899',
lightsteelblue: 'b0c4de',
lightyellow: 'ffffe0',
lime: '00ff00',
limegreen: '32cd32',
linen: 'faf0e6',
magenta: 'ff00ff',
maroon: '800000',
mediumaquamarine: '66cdaa',
mediumblue: '0000cd',
mediumorchid: 'ba55d3',
mediumpurple: '9370d8',
mediumseagreen: '3cb371',
mediumslateblue: '7b68ee',
mediumspringgreen: '00fa9a',
mediumturquoise: '48d1cc',
mediumvioletred: 'c71585',
midnightblue: '191970',
mintcream: 'f5fffa',
mistyrose: 'ffe4e1',
moccasin: 'ffe4b5',
navajowhite: 'ffdead',
navy: '000080',
oldlace: 'fdf5e6',
olive: '808000',
olivedrab: '6b8e23',
orange: 'ffa500',
orangered: 'ff4500',
orchid: 'da70d6',
palegoldenrod: 'eee8aa',
palegreen: '98fb98',
paleturquoise: 'afeeee',
palevioletred: 'd87093',
papayawhip: 'ffefd5',
peachpuff: 'ffdab9',
peru: 'cd853f',
pink: 'ffc0cb',
plum: 'dda0dd',
powderblue: 'b0e0e6',
purple: '800080',
red: 'ff0000',
rosybrown: 'bc8f8f',
royalblue: '4169e1',
saddlebrown: '8b4513',
salmon: 'fa8072',
sandybrown: 'f4a460',
seagreen: '2e8b57',
seashell: 'fff5ee',
sienna: 'a0522d',
silver: 'c0c0c0',
skyblue: '87ceeb',
slateblue: '6a5acd',
slategray: '708090',
snow: 'fffafa',
springgreen: '00ff7f',
steelblue: '4682b4',
tan: 'd2b48c',
teal: '008080',
thistle: 'd8bfd8',
tomato: 'ff6347',
turquoise: '40e0d0',
violet: 'ee82ee',
violetred: 'd02090',
wheat: 'f5deb3',
white: 'ffffff',
whitesmoke: 'f5f5f5',
yellow: 'ffff00',
yellowgreen: '9acd32'
};
for (var key in simple_colors) {
if (color_string == key) {
color_string = simple_colors[key];
}
}
// emd of simple type-in colors
// array of color definition objects
var color_defs = [
{
re: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,
example: ['rgb(123, 234, 45)', 'rgb(255,234,245)'],
process: function (bits){
return [
parseInt(bits[1]),
parseInt(bits[2]),
parseInt(bits[3])
];
}
},
{
re: /^(\w{2})(\w{2})(\w{2})$/,
example: ['#00ff00', '336699'],
process: function (bits){
return [
parseInt(bits[1], 16),
parseInt(bits[2], 16),
parseInt(bits[3], 16)
];
}
},
{
re: /^(\w{1})(\w{1})(\w{1})$/,
example: ['#fb0', 'f0f'],
process: function (bits){
return [
parseInt(bits[1] + bits[1], 16),
parseInt(bits[2] + bits[2], 16),
parseInt(bits[3] + bits[3], 16)
];
}
}
];
// search through the definitions to find a match
for (var i = 0; i < color_defs.length; i++) {
var re = color_defs[i].re;
var processor = color_defs[i].process;
var bits = re.exec(color_string);
if (bits) {
channels = processor(bits);
this.r = channels[0];
this.g = channels[1];
this.b = channels[2];
this.ok = true;
}
}
// validate/cleanup values
this.r = (this.r < 0 || isNaN(this.r)) ? 0 : ((this.r > 255) ? 255 : this.r);
this.g = (this.g < 0 || isNaN(this.g)) ? 0 : ((this.g > 255) ? 255 : this.g);
this.b = (this.b < 0 || isNaN(this.b)) ? 0 : ((this.b > 255) ? 255 : this.b);
// some getters
this.toRGB = function () {
return 'rgb(' + this.r + ', ' + this.g + ', ' + this.b + ')';
}
this.toHex = function () {
var r = this.r.toString(16);
var g = this.g.toString(16);
var b = this.b.toString(16);
if (r.length == 1) r = '0' + r;
if (g.length == 1) g = '0' + g;
if (b.length == 1) b = '0' + b;
return '#' + r + g + b;
}
// help
this.getHelpXML = function () {
var examples = new Array();
// add regexps
for (var i = 0; i < color_defs.length; i++) {
var example = color_defs[i].example;
for (var j = 0; j < example.length; j++) {
examples[examples.length] = example[j];
}
}
// add type-in colors
for (var sc in simple_colors) {
examples[examples.length] = sc;
}
var xml = document.createElement('ul');
xml.setAttribute('id', 'rgbcolor-examples');
for (var i = 0; i < examples.length; i++) {
try {
var list_item = document.createElement('li');
var list_color = new RGBColor(examples[i]);
var example_div = document.createElement('div');
example_div.style.cssText =
'margin: 3px; '
+ 'border: 1px solid black; '
+ 'background:' + list_color.toHex() + '; '
+ 'color:' + list_color.toHex()
;
example_div.appendChild(document.createTextNode('test'));
var list_item_value = document.createTextNode(
' ' + examples[i] + ' -> ' + list_color.toRGB() + ' -> ' + list_color.toHex()
);
list_item.appendChild(example_div);
list_item.appendChild(list_item_value);
xml.appendChild(list_item);
} catch(e){}
}
return xml;
}
}

Wyświetl plik

@ -35,7 +35,7 @@ modules.cloud = '2015-January-12';
// Global stuff
var Cloud;
var SnapCloud = new Cloud(
tStitch.getBaseURL()+ '../cloud'
tstools.getBaseURL()+ '../cloud'
);
// Cloud /////////////////////////////////////////////////////////////

Wyświetl plik

@ -0,0 +1,171 @@
function CommandCache() {
this.clear();
}
CommandCache.prototype.addMoveTo= function(x,y,penState) {
this.cache.push(
{
"cmd":"move",
"x":x,
"y":-y,
"penDown":penState,
}
);
if (this.count === 0) {
this.minX = x;
this.minY = y;
this.maxX = x;
this.maxY = y;
} else {
if (x < this.minX) this.minX = x;
if (x > this.maxX) this.maxX = x;
if (y < this.minY) this.minY = y;
if (y > this.maxY) this.maxY = y;
}
this.count++;
//if (DEBUG) tstools.debug_msg("add move to" + x + " " + y + " " + penState );
};
CommandCache.prototype.hasSteps = function() {
return this.count > 0;
};
CommandCache.prototype.addColorChange= function(color) {
this.cache.push(
{
"cmd":"color",
"value":color,
}
);
};
CommandCache.prototype.clear = function() {
this.cache = [];
this.minX = 0;
this.minY = 0;
this.maxX = 0;
this.maxY = 0;
this.count = 0;
this.initX = 0;
this.initY = 0;
this.w = 480;
this.h = 360;
this.scale = 1;
};
CommandCache.prototype.initPosition = function(x,y) {
this.initX = x;
this.initY = y;
};
CommandCache.prototype.setScale = function(s) {
this.scale = s;
if (DEBUG) tstools.debug_msg("zoom to scale "+ s );
};
CommandCache.prototype.zoomIn = function() {
this.scale += 0.1;
if (DEBUG) tstools.debug_msg("zoom to scale "+this.scale );
};
CommandCache.prototype.zoomOut = function() {
if (this.scale > 0.15)
this.scale -= 0.1;
if (DEBUG) tstools.debug_msg("zoom to scale "+ this.scale );
};
CommandCache.prototype.setDimensions = function(x,y) {
this.w = x;
this.h = y;
};
CommandCache.prototype.renderGrid = function(size=50) {
return '<defs>' +
'<pattern id="grid" width="'+size+'" height="'+size+'" patternUnits="userSpaceOnUse">' +
'<path d="M '+size+' 0 L 0 0 0 '+size+'" fill="none" stroke="gray" stroke-width="0.5"/>' +
'</pattern>' +
'</defs>';
};
CommandCache.prototype.toSVG = function() {
//var svgStr = "<?xml version=\"1.0\" standalone=\"no\"?>\n";
//svgStr += "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \n\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n";
svgStr = '<svg width="' + this.w +'" height="' +this.h + '"' +
' viewBox="' + (-1 * this.w / 2 * this.scale) + ' ' +
(-1 * this.h / 2 * this.scale) + ' ' +
(this.w* this.scale) + ' ' +
(this.h* this.scale)+ '"\n';
svgStr += ' xmlns="http://www.w3.org/2000/svg" version="1.1">\n';
svgStr += '<title>Embroidery export</title>\n';
svgStr += this.renderGrid();
svgStr += '<rect x="' + (-1 * this.w / 2 * this.scale) +
'" y="' + (-1 * this.h / 2 * this.scale) +
'" width="100%" height="100%" fill="url(#grid)" />';
hasFirst = false;
tagOpen = false;
for (var i=0; i < this.cache.length; i++) {
if (this.cache[i].cmd == "move") {
stitch = this.cache[i];
if (!hasFirst) {
if (stitch.penDown) {
svgStr += '<path fill="none" stroke="black" d="M ' +
this.initX +
' ' +
this.initY ;
hasFirst = true;
tagOpen = true;
} else {
svgStr += '<path stroke="red" stroke-dasharray="4 4" d="M ' +
this.initX +
' ' +
this.initY +
' L ' +
(stitch.x) +
' ' +
(stitch.y) +
'" />\n' ;
hasFirst = true;
}
} else {
if (this.cache[i].penDown ) {
if (!this.cache[i-1].penDown ) {
svgStr +=' <path fill="none" stroke="black" d="M ' +
(this.cache[i-1].x) +
' ' +
(this.cache[i-1].y) +
' L ' +
(stitch.x) +
' ' +
(stitch.y);
}
svgStr += ' L ' +
(stitch.x) +
' ' +
(stitch.y);
tagOpen = true;
} else {
svgStr += '<path stroke="red" stroke-dasharray="4 4" d="M ' +
(this.cache[i-1].x) +
' ' +
(this.cache[i-1].y) +
' L ' +
(stitch.x) +
' ' +
(stitch.y) +
'" />\n' ;
}
}
}
}
if (tagOpen) svgStr += '" />\n';
svgStr += '</svg>\n';
return svgStr;
};

Wyświetl plik

@ -652,9 +652,8 @@ IDE_Morph.prototype.createStatusDisplay = function () {
this.statusDisplay.lastWatcherUpdate = Date.now();
this.statusDisplay.watcherUpdateFrequency = 250;
/*
// Buttons and toggles
var toogleShowStitchButton = new ToggleMorph(
'checkbox',
null,
@ -684,7 +683,7 @@ IDE_Morph.prototype.createStatusDisplay = function () {
elements.push(toogleShowJumpsButton);
*/
elements.forEach(function(each) { myself.statusDisplay.addElement(each) });
};

Wyświetl plik

@ -1,259 +1,56 @@
/* Sprite */
// modified SpriteMorph turtle functions
// SpriteMorph motion primitives
// modified SpriteMorph turtlestitch functions
SpriteMorph.prototype.origForward = SpriteMorph.prototype.forward;
SpriteMorph.prototype.forward = function (steps) {
var dest,
dist = steps * this.parent.scale || 0;
oldpos = this.position();
if (dist >= 0) {
dest = this.position().distanceAngle(dist, this.heading);
} else {
dest = this.position().distanceAngle(
Math.abs(dist),
(this.heading - 180)
);
}
this.setPosition(dest);
this.positionTalkBubble();
//this.drawLineX(dest);
tx = dest.x - this.parent.topLeft().x;
ty = dest.y - this.parent.topLeft().y;
tjump = !this.isDown;
if (tStitch.isFirst()) {
origx = oldpos.x - this.parent.topLeft().x;
origy = oldpos.y - this.parent.topLeft().y;
tStitch.addPoint(origx , origy ,true);
//alert("first");
//alert("orig: " + origx + "," + origy+ " tx/ty: " + tx + ", "+ ty + " - "+ this.position());
}
tStitch.addPoint(tx,ty,tjump);
//alert("move to: " + tx + "x" + ty + " - isJump = " + tjump);
oldx = this.xPosition();
oldy = this.yPosition();
this.origForward(steps);
if (!cmdCache.hasSteps())
cmdCache.initPosition(oldx, oldy);
cmdCache.addMoveTo(this.xPosition() , this.yPosition() , this.isDown);
this.reDrawTrails();
};
SpriteMorph.prototype.origGotoXY = SpriteMorph.prototype.gotoXY;
SpriteMorph.prototype.gotoXY = function (x, y, justMe) {
var stage = this.parentThatIsA(StageMorph),
newX,
newY,
dest;
newX = stage.center().x + (+x || 0) * stage.scale;
newY = stage.center().y - (+y || 0) * stage.scale;
oldX = this.position().x / stage.scale - stage.center().x + this.extent().x/2;
oldY = -(this.position().y / stage.scale - stage.center().y + this.extent().y/2);
if (this.costume) {
dest = new Point(newX, newY).subtract(this.rotationOffset);
oldx = this.xPosition();
oldy = this.yPosition();
console.log("jump in place - don't add.");
this.origGotoXY(x, y, justMe);
if ( Math.abs(this.xPosition()-oldx)<=1 && Math.abs(this.yPosition()-oldy)<=1 ) {
console.log("jump in place - don't add.");
} else {
dest = new Point(newX, newY).subtract(this.extent().divideBy(2));
}
this.setPosition(dest, justMe);
this.positionTalkBubble();
tx = dest.x - this.parent.topLeft().x;
ty = dest.y - this.parent.topLeft().y;
tjump = !this.isDown;
if ( Math.abs(x-oldX)<=1.1 && Math.abs(y-oldY)<=1.1 ) {
if (tStitch.debug)
console.log("jump in place - don't add.");
} else {
if (tStitch.debug)
console.log("gotoXY "+ x + "," + y + " from: + " + oldX + "," + oldY);
tStitch.addPoint(tx,ty,tjump);
if (!cmdCache.hasSteps())
cmdCache.initPosition(oldx, oldy);
cmdCache.addMoveTo(this.xPosition() , this.yPosition() , this.isDown);
this.reDrawTrails();
}
};
// SpriteMorph drawing:
SpriteMorph.prototype.drawLine = function (start, dest) {
var stagePos = this.parent.bounds.origin,
stageScale = this.parent.scale,
context = this.parent.penTrails().getContext('2d'),
from = start.subtract(stagePos).divideBy(stageScale),
to = dest.subtract(stagePos).divideBy(stageScale),
damagedFrom = from.multiplyBy(stageScale).add(stagePos),
damagedTo = to.multiplyBy(stageScale).add(stagePos),
damaged = damagedFrom.rectangle(damagedTo).expandBy(
Math.max(this.size * stageScale / 2, 1)
).intersect(this.parent.visibleBounds()).spread();
if (this.isDown) {
context.lineWidth = this.size;
context.strokeStyle = this.color.toString();
if (this.useFlatLineEnds) {
context.lineCap = 'butt';
context.lineJoin = 'miter';
} else {
context.lineCap = 'round';
context.lineJoin = 'round';
}
context.beginPath();
context.moveTo(from.x, from.y);
context.lineTo(to.x, to.y);
context.stroke();
if (this.isWarped === false) {
this.world().broken.push(damaged);
}
}
};
SpriteMorph.prototype.drawJumpLine = function (start, dest) {
var stagePos = this.parent.bounds.origin,
stageScale = this.parent.scale,
context = this.parent.penTrails().getContext('2d'),
from = start.subtract(stagePos).divideBy(stageScale),
to = dest.subtract(stagePos).divideBy(stageScale),
damagedFrom = from.multiplyBy(stageScale).add(stagePos),
damagedTo = to.multiplyBy(stageScale).add(stagePos),
damaged = damagedFrom.rectangle(damagedTo).expandBy(
Math.max(this.size * stageScale / 2, 1)
).intersect(this.parent.visibleBounds()).spread();
context.lineWidth = this.size;
context.strokeStyle = new Color(255, 0, 0).toString();
context.lineCap = 'round';
context.lineJoin = 'round';
context.beginPath();
context.moveTo(from.x, from.y);
context.lineTo(to.x, to.y);
context.stroke();
if (this.isWarped === false) {
this.world().broken.push(damaged);
}
};
SpriteMorph.prototype.drawStitch = function (dest) {
//dest = dest.subtract(this.topLeft());
var s = tStitch.draw_stitch_len;
var stagePos = this.parent.bounds.origin,
stageScale = this.parent.scale,
context = this.parent.penTrails().getContext('2d'),
to = dest.subtract(stagePos).divideBy(stageScale),
damagedFrom = new Point(to.x-s,to.y-s).multiplyBy(stageScale).add(stagePos),
damagedTo = new Point(to.x+s,to.y+s).multiplyBy(stageScale).add(stagePos),
damaged = damagedFrom.rectangle(damagedTo).expandBy(
Math.max(this.size * stageScale / 2, 1)
).intersect(this.parent.visibleBounds()).spread();
context.lineWidth = this.size;
context.strokeStyle = new Color(0, 0, 255).toString();
context.lineCap = 'round';
context.lineJoin = 'round';
context.beginPath();
context.moveTo(to.x - s, to.y - s );
context.lineTo(to.x + s, to.y + s);
context.stroke();
context.beginPath();
context.moveTo(to.x - s, to.y + s);
context.lineTo(to.x + s, to.y - s);
context.stroke();
if (this.isWarped === false) {
this.world().broken.push(damaged);
}
};
SpriteMorph.prototype.origClear = SpriteMorph.prototype.clear;
SpriteMorph.prototype.clear = function () {
this.origClear();
cmdCache.clear();
this.reDrawTrails();
};
SpriteMorph.prototype.reDrawTrails = function () {
this.parent.clearPenTrails();
tStitch.clearPoints();
if (tStitch.debug) {
tStitch.debug_msg("",true);
}
reDraw(this.parent.penTrails());
};
/* Stage */
// modified StageMorph turtlestitch functions
// SpriteMorph motion - adjustments due to nesting
SpriteMorph.prototype.moveBy = function (delta, justMe) {
// override the inherited default to make sure my parts follow
// unless it's justMe (a correction)
var start = this.isDown && !justMe && this.parent ?
this.rotationCenter() : null;
// add stitch controls
if (this.parent) {
if (this.parent.penTrails()) {
origin = this.rotationCenter();
}
}
SpriteMorph.uber.moveBy.call(this, delta);
// add stitch controls
if (this.parent) {
if (this.parent.penTrails() && origin.x > 100) {
//alert(origin.x);
if (tStitch.draw_stitches) {
this.drawStitch(this.rotationCenter());
}
if (tStitch.draw_jumps && !this.isDown) {
this.drawJumpLine(origin,this.rotationCenter());
}
}
}
if (start) {
this.drawLine(start, this.rotationCenter());
}
if (!justMe) {
this.parts.forEach(function (part) {
part.moveBy(delta);
});
StageMorph.prototype.referencePos = null;
StageMorph.prototype.mouseScroll = function (y, x) {
if (y > 0) {
cmdCache.zoomOut();
} else if (y < 0) {
cmdCache.zoomIn();
}
this.clearPenTrails();
reDraw(this.penTrails());
};
/*
// Definition of new block categories
SpriteMorph.prototype.categories =
[
'motion',
'control',
'shapes',
'colors',
'sensing',
'operators',
'variables',
'lists',
'my blocks'
];
SpriteMorph.prototype.blockColor = {
motion : new Color(74, 108, 212),
shapes : new Color(143, 86, 227),
colors : new Color(207, 74, 217),
sound : new Color(207, 74, 217), // we need to keep this color for the zoom blocks dialog
control : new Color(230, 168, 34),
sensing : new Color(4, 148, 220),
operators : new Color(98, 194, 19),
variables : new Color(243, 118, 29),
lists : new Color(217, 77, 17),
other : new Color(150, 150, 150),
'my blocks': new Color(150, 150, 60),
};
// now move also "make a block to 'my blocks'
*/

Wyświetl plik

@ -0,0 +1,21 @@
var tstools = {};
tstools.getBaseURL = function () {
var url = location.href; // entire url including querystring - also: window.location.href;
if (url.lastIndexOf('#') > 0) {
url = url.substring(0, url.lastIndexOf('#'));
}
url = url.substring(0, url.lastIndexOf('/'));
return url + "/";
};
tstools.debug_msg = function (st, clear=false) {
o = new String();
if (!clear) {
o = document.getElementById("debug").innerHTML;
} else {
o = "";
}
o = st + "<br />" + o;
document.getElementById("debug").innerHTML = o;
};

Wyświetl plik

@ -0,0 +1,18 @@
cmdCache = new CommandCache();
DEBUG = true;
function reDraw(cnv) {
//load a svg snippet in the canvas with id = 'svg'
canvas = document.getElementById('svg');
//document.getElementById("code").innerHTML = cmdCache.toSVG();
//document.getElementById("svg2").innerHTML = cmdCache.toSVG();
//canvg(document.getElementById('svg'), cmdCache.toSVG());
canvg(cnv, cmdCache.toSVG());
//var cnv = caller.parent.penTrails();
//var ctx = cnv.getContext('2d');
//ctx.drawSvg(cmdCache.toSVG(), 0, 0, cnv.width, cnv.height);
}