Yeah with Progression checked you have to have Grid checked as well as it has to use grid to show progression.
If Grid is checked it draws multiples in grid.
But if Progression is checked along with Grid then you'll see progression through the grid.
Oh found a bug(fixed it). (also hosted on
<html>
<div id="fb-root"></div>
<script async defer crossorigin="anonymous" src="https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v16.0&appId=2727991274101093&autoLogAppEvents=1" nonce="99M2cCnM"></script>
<h1>Tin Man Draw Page</h1>
<div class="fb-like" data-href="https://thelotteryforum.com/tin-man-draw.html" data-width="" data-layout="" data-action="" data-size="" data-share="true"></div><br/>
<script type="text/javascript">
colors = [["1","Blue Green","#199ebd"],
["2","Black","#232323"],
["3","Blue Violet","#7366bd"],
["4","Violet(Purple)","#926eae"],
["5","Green","#1cac78"],
["6","Blue","#1f75fe"],
["7","Yellow Green","#c5e384"],
["8","White","#ededed"],
["9","Yellow","#fce883"],
["10","Carnation Pink","#ffaacc"],
["11","Yellow Orange","#ffb653"],
["12","Red","#ee204d"],
["13","Brown","#b5674d"],
["14","Orange","#ff7538"],
["15","Red Orange","#ff5349"],
["16","Red Violet","#c0448f"],
["17","Gray","#95918c"],
["18","Cerulean","#1dacd6"],
["19","Indigo","#5d76cb"],
["20","Green Yellow","#f0e891"],
["21","Dandelion","#fddb6d"],
["22","Apricot","#fdd9b5"],
["23","Violet Red","#f75394"],
["24","Scarlet","#fc2847"],
["25","Wisteria","#cda4de"],
["26","Sky Blue","#80daeb"],
["27","Cadet Blue","#b0b7c6"],
["28","Timberwolf","#dbd7d2"],
["29","Melon","#fdbcb4"],
["30","Peach","#ffcfab"],
["31","Tan","#faa76c"],
["32","Chestnut","#bc5d58"],
];
var varyColorBy = 20; //value to vary each color by out of 255 (plus or minus this value). changed by textbox input later
var canvas,canvas2, ctx,ctx2, flag,canvas1,ctx1 = false,
prevX = 0,
currX = 0,
prevY = 0,
currY = 0,
dot_flag = false;
var color = colors[1][2];
var lineWidth = 2;
base = 70;
top = 10;
function drawcolors(){
ctx1.clearRect(0,0,canvas1.width,canvas1.height)
for (var x=0;x<16;x++){
ctx1.fillStyle = colors[x][2];
ctx1.fillRect(x*40,0,40,40);
}
for (var x=16;x<32;x++){
ctx1.fillStyle = colors[x][2];
ctx1.fillRect((x-16)*40,40,40,40);
}
ctx1.fillStyle = "rgb(0,0,0)";
ctx1.beginPath();
ctx1.lineTo(640,70);
ctx1.lineTo(760,10);
ctx1.lineTo(760,70);
ctx1.lineTo(640,70);
ctx1.closePath();
ctx1.fill();
//draw brush size
radius = lineWidth/2.0;
ctx1.globalAlpha=0.5;
ctx1.beginPath();
ctx1.fillStyle = "red";
ctx1.arc(640+lineWidth*2,70-radius,radius, 0, 2 * Math.PI);
ctx1.fill();
ctx1.globalAlpha=1.0;
ctx1.globalCompositeOperation = "xor";
ctx1.beginPath();
ctx1.arc(640+lineWidth*2,70-radius,radius, 0, 2 * Math.PI);
ctx1.stroke();
ctx1.globalCompositeOperation = "source-over";
//draw brush size with current color
ctx1.beginPath();
ctx1.arc(800,40,radius,0,2*Math.PI);
ctx1.fillStyle = color;
ctx1.fill();
}
img = 0;
function init() {
canvas1 = document.getElementById('canvas');
ctx1 = canvas1.getContext("2d");
canvas1.addEventListener("mousedown", function (e) {
choosexy('down', e)
}, false);
canvas = document.getElementById('can');
canvas2 = document.getElementById('can2');
canvas3 = document.getElementById('can3');
ctx = canvas.getContext("2d");
ctx2 = canvas2.getContext("2d");
ctx3 = canvas3.getContext("2d");
img = document.getElementById("img");
canvas.width = img.width;
canvas.height = img.height;
canvas2.width = canvas.width;
canvas2.height = canvas.height;
canvas3.width = canvas.width;
canvas3.height = canvas.height;
w = canvas.width;
h = canvas.height;
ph = document.getElementById('ph');
ph.style.top = parseInt(canvas.height)+100+"px";
canvas2.style.left = parseInt(canvas.width)+10+"px";
canvas3.style.left = (parseInt(canvas.width)+10)*2 + "px";
ctx.lineCap = "round";
ctx2.lineCap = "round";
canvas.addEventListener("mousemove", function (e) {
findxy('move', e)
}, false);
canvas.addEventListener("mousedown", function (e) {
findxy('down', e)
}, false);
canvas.addEventListener("mouseup", function (e) {
findxy('up', e)
}, false);
canvas.addEventListener("mouseout", function (e) {
findxy('out', e)
}, false);
drawcolors();
}
strokes = [];
multistrokes = [];
strokecount = -1;
function shuffle_(array) {
let currentIndex = array.length, randomIndex;
// While there remain elements to shuffle.
while (currentIndex != 0) {
// Pick a remaining element.
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
// And swap it with the current element.
[array[currentIndex], array[randomIndex]] = [
array[randomIndex], array[currentIndex]];
}
return array;
}
function componentToHex(c) {
var hex = c.toString(16);
return hex.length == 1 ? "0" + hex : hex;
}
function rgbToHex(r, g, b) {
return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
}
function rgbStrToHex(rgbstring){
rgb = rgbstring;
//rgb = "rgb(0,128,255)"
values = rgb.slice(4,-1).split(',');
return rgbToHex(parseInt(values[0]),parseInt(values[1]),parseInt(values[2]));
}
const hexToRgb = hex =>
hex.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i
,(m, r, g, b) => '#' + r + r + g + g + b + b)
.substring(1).match(/.{2}/g)
.map(x => parseInt(x, 16));
function width_(array){
halfsize = array.length/2.0;
currentlw = array[0][5];
c = array[0][4];
currentc = hexToRgb(c);
r = parseInt(currentc[0]);
g = parseInt(currentc[1]);
b = parseInt(currentc[2]);
if (document.getElementById('varycheckbox').checked){ //if it's check we vary random within varycolorby range
varColorBy = parseInt(document.getElementById('varycolorby').value);
r = Math.min(255,Math.max(0,r+Math.random()*varColorBy*2-varColorBy));
g = Math.min(255,Math.max(0,g+Math.random()*varColorBy*2-varColorBy));
b = Math.min(255,Math.max(0,b+Math.random()*varColorBy*2-varColorBy));
}
for (var i=0;i<array.length;i++){
angle = (90-Math.abs((halfsize)-i)/(halfsize)*90.0)/360.0*2.0*3.1415;
thislw = currentlw * 0.1 + Math.sin(angle)*currentlw*1.0;
array[i][5] = thislw;
currentc = hexToRgb(c);
//document.getElementById('debug').innerHTML += currentc + ",";
if (document.getElementById('varywithinstroke').checked){ //if it's check we vary random within varycolorby range
r = parseInt(currentc[0]);
g = parseInt(currentc[1]);
b = parseInt(currentc[2]);
varColorBy = parseInt(document.getElementById('varycolorby').value);
r = Math.min(255,Math.max(0,r+Math.random()*varColorBy*2-varColorBy));
g = Math.min(255,Math.max(0,g+Math.random()*varColorBy*2-varColorBy));
b = Math.min(255,Math.max(0,b+Math.random()*varColorBy*2-varColorBy));
}
maxbrightvalue = Math.max(r,g,b);
ubound = (Math.min(maxbrightvalue*1.3,255.0))/maxbrightvalue;
lbound = 0.8;
fraction = ubound - Math.sin(angle)*(ubound-lbound);
thisr = parseInt(r*fraction);
thisg = parseInt(g*fraction);
thisb = parseInt(b*fraction);
array[i][7] = thisr;
array[i][8] = thisg;
array[i][9] = thisb;
}
return array;
}
function angleOf(cx, cy, ex, ey) {//returns angle in degrees
var dy = ey - cy;
var dx = ex - cx;
var theta = Math.atan2(dy, dx); // range (-PI, PI]
//theta *= 180 / Math.PI; // rads to degs, range (-180, 180]
//if (theta < 0) theta = 360 + theta; // range [0, 360)
return theta;
}
function strokeShuffle(){
strokes2 = [];
lsc = -1;
thisstrokes = [];
for (var i=0;i<strokes.length;i++){
sc = strokes[i][6];
if (sc!=lsc){
if (thisstrokes.length > 0){
thisstrokes = shuffle_(thisstrokes.slice());
for (var j=0;j<thisstrokes.length;j++){
strokes2.push(thisstrokes[j].slice());
}
}
thisstrokes = [];
lsc = sc;
}
thisstrokes.push(strokes[i].slice());
}
if (thisstrokes.length > 0){
thisstrokes = shuffle_(thisstrokes.slice());
for (var j=0;j<thisstrokes.length;j++){
strokes2.push(thisstrokes[j].slice());
}
}
return strokes2;
}
function strokeWidth(strokes){
strokes2 = [];
lsc = -1;
thisstrokes = [];
for (var i=0;i<strokes.length;i++){
sc = strokes[i][6];
if (sc!=lsc || i == 0){
if (thisstrokes.length > 0){
thisstrokes = width_(thisstrokes.slice());
for (var j=0;j<thisstrokes.length;j++){
strokes2.push(thisstrokes[j].slice());
}
}
thisstrokes = [];
lsc = sc;
}
thisstrokes.push(strokes[i].slice());
}
if (thisstrokes.length > 0){
thisstrokes = width_(thisstrokes.slice());
for (var j=0;j<thisstrokes.length;j++){
strokes2.push(thisstrokes[j].slice());
}
}
return strokes2;
}
function draw2(){
ctx2.clearRect(0, 0, w, h);
for (var s=-1;s<multistrokes.length;s++){
lc = -1;
llw = -1;
lsc = -1;
//strokes2 = strokeWidth(strokes.slice());
if (s==-1){
strokes2 = strokeWidth(strokes.slice());
}else{
strokes2 = strokeWidth(multistrokes[s].slice());
}
for (var i=0;i<strokes2.length;i++){
dx1 = strokes2[i][0];
dy1 = strokes2[i][1];
dx2 = strokes2[i][2];
dy2 = strokes2[i][3];
dc = strokes2[i][4];
lw = strokes2[i][5];
sc = strokes2[i][6];
r = strokes2[i][7];
g = strokes2[i][8];
b = strokes2[i][9];
if (document.getElementById('offsetly').checked){
ox = (dx2-dx1) * (Math.random()*0.4+0.8)/2.0;
oy = (dy2-dy1) * (Math.random()*0.4+0.8)/2.0;
cx = (dx2+dx1)/2.0;
cy = (dy2+dy1)/2.0;
dx1 = cx - ox;
dy1 = cy - oy;
dx2 = cx + ox;
dy2 = cy + oy;
}
//if ((lc != dc) || (llw != lw) ||) { //if it's the first stroke we set lx and ly to start there
if (lsc != sc) { //if different stroke count
lx = dx1;
ly = dy1;
lc = dc;
llw = lw;
lsc = sc;
}
if (Math.random()>=0.0) {
if (document.getElementById('offsetly').checked){
nx = dx2-dx1;
ny = dy2-dy1;
dx1 = lx;
dy1 = ly;
dx2 = lx+nx;
dy2 = ly+ny;
}
if (document.getElementById('stroketype').value == "1"){ //regular stroke
ctx2.beginPath();
ctx2.moveTo(dx1,dy1);
ctx2.lineTo(dx2,dy2);
//ctx2.strokeStyle = dc;
ctx2.strokeStyle = "rgb("+r+","+g+","+b+")";
ctx2.lineWidth = lw;
ctx2.stroke();
ctx2.closePath();
}else if (document.getElementById('stroketype').value == "2"){ //circles
ctx2.beginPath();
cx = (dx1+dx2)/2;
cy = (dy1+dy1)/2;
//ctx2.strokeStyle = dc;
ctx2.strokeStyle = "rgb("+r+","+g+","+b+")";
//ctx2.lineWidth = lw;
ctx2.lineWidth = Math.max(1.0,lw/10.0);
ctx2.arc(cx,cy,lw/2.0,0,Math.PI*2);
ctx2.stroke();
ctx2.closePath();
}
lx = dx2;
ly = dy2;
}
}
}
}
function draw1(){
ctx.clearRect(0, 0, w, h);
for (var i=0;i<strokes.length;i++){
dx1 = strokes[i][0];
dy1 = strokes[i][1];
dx2 = strokes[i][2];
dy2 = strokes[i][3];
dc = strokes[i][4];
lw = strokes[i][5];
sc = strokes[i][6];
ctx.beginPath();
ctx.moveTo(dx1,dy1);
ctx.lineTo(dx2,dy2);
ctx.strokeStyle = dc;
ctx.lineWidth = lw;
ctx.stroke();
ctx.closePath();
}
if (document.getElementById('reflect').checked){
for (var j=0;j<multistrokes.length;j++){
stroke = multistrokes[j];
for (var i=0;i<stroke.length;i++){
dx1 = stroke[i][0];
dy1 = stroke[i][1];
dx2 = stroke[i][2];
dy2 = stroke[i][3];
dc = stroke[i][4];
lw = stroke[i][5];
sc = stroke[i][6];
ctx.beginPath();
ctx.moveTo(dx1,dy1);
ctx.lineTo(dx2,dy2);
ctx.strokeStyle = dc;
ctx.lineWidth = lw;
ctx.stroke();
ctx.closePath();
}
}
}
// ctx.beginPath();
// ctx.moveTo(prevX, prevY);
// ctx.lineTo(currX, currY);
// ctx.strokeStyle = color;
// ctx.lineWidth = lineWidth;
// ctx.stroke();
// ctx.closePath();
}
function draw3(){
ctx3.globalAlpha = 1.0;
ctx3.clearRect(0,0,canvas3.width,canvas3.height);
//ctx3.fillStyle= 'white';
//ctx3.fillRect(0,0,canvas3.width,canvas3.height);
progression = 0;
by = parseInt(document.getElementById("byValue").value);
if (document.getElementById("grid").checked && document.getElementById("progression").checked){
progressions = by * by;
progression = 1;
p = []; //progressions
savedstrokes = strokes.slice();
for (var i=1;i<=progressions;i++){
p.push(strokes.slice(0,Math.round(strokes.length/progressions*i)));
}
}
for (var i=1;i<=8;i++){
if (document.getElementById("grid").checked){
size = canvas.width/by;
n = 0;
for (var y=0;y<by;y++){
for (var x=0;x<by;x++){
if (progression==1){
strokes = p[n].slice();
draw(0); //to calculate multi strokes
}
n+=1;
draw2();
ctx3.globalAlpha = 1.0/(i+1);
ctx3.drawImage(canvas2,x*size,y*size,size,size);
}
}
}else{
draw2();
ctx3.globalAlpha = 1.0/(i+1);
ctx3.drawImage(canvas2,0,0);
}
}
if (progression==1){
strokes = savedstrokes.slice();
}
}
function drawCursor(clear = 0){
if (clear == 1){
ctx.clearRect(0,0,canvas.width,canvas.height);
//redisplay them all before drawing cursor
//ctx.globalAlpha=1.0;
//ctx.drawImage(img,0,0,canvas.width,canvas.height);
draw1();
ctx.globalAlpha=.5;
ctx.drawImage(img,0,0,canvas.width,canvas.height);
ctx.globalAlpha=1.0;
}
ctx.beginPath();
ctx.arc(currX,currY,lineWidth/2.0,0,Math.PI*2.0);
saveLineWith = ctx.lineWidth;
ctx.lineWidth = 1;
savestrokeStyle = ctx.strokeStyle;
ctx.strokeStyle = 'red';
ctx.globalCompositeOperation = "xor";
ctx.stroke();
ctx.globalCompositeOperation = "source-over";
ctx.strokeStyle = savestrokeStyle;
ctx.lineWidth = saveLineWith;
}
mirrors = 6;
function reflectthem(mirrors){
mirrors = parseInt(mirrors);
reflection = [];
mx = canvas.width/2.0;
my = canvas.height/2.0;
for (var i=0;i<strokes.length;i++){
reflection.push(strokes[i].slice());
reflection[i][0] = mx - (reflection[i][0] - mx);
reflection[i][2] = mx - (reflection[i][2] - mx);
}
multistrokes.push(reflection);
incang = 360.0/mirrors/360.0*2*Math.PI;
for (var a=1;a<mirrors;a++){
ref = [];
for (var i=0;i<strokes.length;i++){
ref.push(strokes[i].slice());
p1angle = angleOf(mx,my,ref[i][0],ref[i][1]);
p2angle = angleOf(mx,my,ref[i][2],ref[i][3]);
p1radius = ((ref[i][0]-mx)**2+(ref[i][1]-my)**2)**0.5;
p2radius = ((ref[i][2]-mx)**2+(ref[i][3]-my)**2)**0.5;
newangle1 = p1angle+a*incang;
newangle2 = p2angle+a*incang;
ref[i][0] = mx + p1radius * Math.cos(newangle1);
ref[i][1] = my + p1radius * Math.sin(newangle1);
ref[i][2] = mx + p2radius * Math.cos(newangle2);
ref[i][3] = my + p2radius * Math.sin(newangle2);
}
multistrokes.push(ref);
ref = [];
for (var i=0;i<strokes.length;i++){
ref.push(reflection[i].slice());
p1angle = angleOf(mx,my,ref[i][0],ref[i][1]);
p2angle = angleOf(mx,my,ref[i][2],ref[i][3]);
p1radius = ((ref[i][0]-mx)**2+(ref[i][1]-my)**2)**0.5;
p2radius = ((ref[i][2]-mx)**2+(ref[i][3]-my)**2)**0.5;
newangle1 = p1angle+a*incang;
newangle2 = p2angle+a*incang;
ref[i][0] = mx + p1radius * Math.cos(newangle1);
ref[i][1] = my + p1radius * Math.sin(newangle1);
ref[i][2] = mx + p2radius * Math.cos(newangle2);
ref[i][3] = my + p2radius * Math.sin(newangle2);
}
multistrokes.push(ref);
}
}
function draw(add = 1) {
// ctx.beginPath();
// ctx.moveTo(prevX, prevY);
// ctx.lineTo(currX, currY);
// ctx.strokeStyle = color;
// ctx.lineWidth = lineWidth;
// ctx.stroke();
// ctx.closePath();
if (color.includes("rgb")){color = rgbStrToHex(color);
} //always turn it into hex
rgbthis = hexToRgb(color);
if (add == 1){
strokes.push([prevX,prevY,currX,currY,color,lineWidth,strokecount,rgbthis[0],rgbthis[1],rgbthis[2]]); // save stroke information as we draw
}
if (document.getElementById('reflect').checked){
multistrokes = [];
mirrors = parseInt(document.getElementById('mirrors').value);
reflectthem(mirrors);
}else{
multistrokes = [];
}
draw1();
drawCursor();
ctx.globalAlpha=.5;
ctx.drawImage(img,0,0,canvas.width,canvas.height);
ctx.globalAlpha=1.0;
draw2();
}
function erase() {
var m = confirm("Want to clear");
if (m) {
strokes = [];
strokecount = -1;
ctx.clearRect(0, 0, w, h);
ctx2.clearRect(0, 0, w, h);
document.getElementById("canvasimg").style.display = "none";
}
}
function save() {
document.getElementById("canvasimg").style.border = "2px solid";
var dataURL = canvas.toDataURL();
document.getElementById("canvasimg").src = dataURL;
document.getElementById("canvasimg").style.display = "inline";
}
// function getMousePos(canvas, evt) {
// var rect = canvas.getBoundingClientRect();
// return {
// x: evt.clientX - rect.left,
// y: evt.clientY - rect.top
// };
// }
function choosexy(res, e) {
rect = canvas1.getBoundingClientRect();
if (res == 'down') {
prevX = currX;
prevY = currY;
// currX = e.clientX - canvas1.offsetLeft;
// currY = e.clientY - canvas1.offsetTop;
currX = e.clientX - rect.left;
currY = e.clientY - rect.top;
if (currX < 640){
pixel = ctx1.getImageData(currX, currY, 1, 1).data;
color = "rgb("+pixel[0]+","+pixel[1]+","+pixel[2]+")";
}else{
lineWidth = (currX - 640)/120 * (60);
}
drawcolors();
}
}
function findxy(res, e) {
rect = canvas.getBoundingClientRect();
if (res == 'down') {
prevX = currX;
prevY = currY;
// currX = e.clientX - canvas.offsetLeft;
// currY = e.clientY - canvas.offsetTop;
currX = e.clientX - rect.left;
currY = e.clientY - rect.top;
flag = true;
dot_flag = true;
if (dot_flag) {
ctx.beginPath();
ctx.fillStyle = color;
ctx.fillRect(currX, currY, 2, 2);
ctx.closePath();
ctx2.beginPath();
ctx2.fillStyle = color;
ctx2.fillRect(currX, currY, 2, 2);
ctx2.closePath();
dot_flag = false;
}
}
if (res == 'up' || res == "out") {
flag = false;
strokecount += 1; //increment stroke count
}
if (res == 'move') {
if (flag) {
prevX = currX;
prevY = currY;
// currX = e.clientX - canvas.offsetLeft;
// currY = e.clientY - canvas.offsetTop;
currX = e.clientX - rect.left;
currY = e.clientY - rect.top;
draw();
}else{
// currX = e.clientX - canvas.offsetLeft;
// currY = e.clientY - canvas.offsetTop;
currX = e.clientX - rect.left;
currY = e.clientY - rect.top;
drawCursor(1);
}
}
}
function animate(){
if (document.getElementById('animate').checked){
draw2();
}
}
setInterval(animate,100);
function loadimage(){
image = document.getElementById("img");
image.onload = function(){
init();
}
image.src = document.getElementById('src').value;
}
function save(){
localStorage.setItem("tracer_strokes", JSON.stringify(strokes));
}
function load(){
strokes = JSON.parse(localStorage.getItem("tracer_strokes"));
}
draw();
</script>
<body onload="init()">
<canvas id="canvas" width="840" height="80" style="position:absolute;top:100px;left:0px;border:1px solid"></canvas>
<table><tr><td><img src='square.jpg' id='img' width="2000px" style="position:absolute;top:180px;left:0px;border:2px solid;"><canvas id="can" width="1200" height="1200" style="position:absolute;top:180px;left:0px;border:2px solid;"></canvas></td><td><canvas id="can2" width="1200" height="960" style="position:absolute;top:180px;left:1200px;border:2px solid;"></td>
<td><canvas id="can3" width="1200" height="960" style="position:absolute;top:180px;left:2400px;border:2px solid;"></td></tr></table><br/>
<div id='ph' style="position:absolute;top:2300px;left:0%;">
<input type='submit' value='Clear' onclick='erase()'><br/>
<input type='checkbox' id='offsetly' value=''>Offsetly Drawn<br/>
<!-- <input type='checkbox' id='shuffle' value=''>Shuffle Stroke Parts<br/> -->
<input type="checkbox" id='animate' checked>Continuous Redraws<br/>
<input type="checkbox" id='varycheckbox' checked>Vary Color Channels by <input type='text' id='varycolorby' value='50' size=3>/255 - <input type="checkbox" id='varywithinstroke'>Vary Within Strokes<br/>
Image location/url:<input type='text' id='src' value='seagull.jpg'><input type='submit' onclick='loadimage()' value='Load Image'><br/>
<select id="stroketype"><option value="1" selected>Regular Stroke</option>
<option value="2">Circles</option>
</select>
<input type='checkbox' id='reflect' checked>Reflect <input type='text' id='mirrors' value='6' size=3> Mirrors<br/>
<input type='checkbox' id='grid' checked>Grid (of Multiples) of <input type='text' id='byValue' value='4' size=3> n by n Value<br/>
<input type='checkbox' id='progression' checked>Show Progression (when in Grid mode)<br/>
<input type='submit' value='Redraw Canvas3' onclick='draw3()'><br/>
<br/>
<input type='submit' value='Save to Local Storage' onclick='save()'><input type='submit' value='Load from Local Storage' onclick='load()'><br/>
<div id='debug'></div>
<hr>
<div id='donate'>
The NSI (not so important) stuff: If you find this js/html useful, feel free to use it but if you make money from it (I ask that <br>
you transfer $1 USD per sale to me through Paypal at oldtran@gmail.com). If you don't use Paypal, then don't worry about it. I understand<br/>
that there might be fees so maybe save it until you have more than 10 sales then transfer to me once and minus the fee. I would appreciate<br/>
this and maybe even add features in the future to this existing program.<br/><br/>
I also ask that you donate $1 per sale to GIMP foundation.<br/><br/>
I think it's a fair deal, as there is no risk to you for using it for free as much as you please, and only turn around and donate only when you've made sales.<br/>
</div>
</div>
</body>
</html>