Created
November 4, 2014 00:34
-
-
Save gekowa/d515bb4c3941f6123a53 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var blockSize = 2; | |
function Montage(canvas) { | |
document._MontageObj = this; | |
IsBlack=function(c){ | |
var white=(c.R==0 && c.G==0 && c.B==0 && c.A==0) || (c.R>250 && c.G>250 && c.B>250); | |
return !white; | |
}; | |
this.OnProgress = null; | |
this.OnFinish = null; | |
this.Direction=0; | |
this.MaxFont=60; | |
this.MinFont = 8; | |
this.Canvas = canvas; | |
this.PathLayer = document.createElement("canvas"); | |
this.Progress = 0; | |
this.Ctx = this.Canvas.getContext("2d"); | |
this.PathCtx = this.PathLayer.getContext("2d"); | |
this.PathCtx.fillStyle="black"; | |
this.Image = new Image(); | |
this.Image.Montage = this; | |
this.ImageUrl = ""; | |
this.Angles = [0, 90]; | |
this.Fonts = ["Chiller", "CopperplateGothicStd-32AB", "ITCEDSCR"]; | |
this.Colors = ["#003E5F", "#025D8C", "#107FDB", "#23B0DB", "#1693A5"]; | |
this.Text = "Everybody Google News Web"; | |
this.Words=[]; | |
this.Image.onload = function () { | |
this.Montage.PathLayer.width = this.Montage.Canvas.width = this.width; | |
this.Montage.PathLayer.height = this.Montage.Canvas.height = this.height; | |
this.Montage.PathCtx.drawImage(this, 0, 0); | |
//this.Montage.Ctx.drawImage(this, 0, 0); | |
this.Montage.GetPath(); | |
this.Montage.PathReady = true; | |
if (this.CallBack != undefined && this.CallBack != null) { | |
this.CallBack(); | |
} | |
}; | |
this.Words = []; | |
this.DrawText = function (textBlock, x, y) { | |
var l, t; | |
var p; | |
this.Words[this.Words.length] = {Text:textBlock,X:x*blockSize,Y:y *blockSize}; | |
for (var i = 0; i < textBlock.PotWidth; i++) { | |
l = x + i; | |
for (var j = 0; j < textBlock.PotHeight; j++) { | |
t = y + j; | |
if (textBlock.Pots[i][j].Black) { | |
try { | |
this.Pots[l][t].Blank = false; | |
this.Pots[l][t].Black = true; | |
} | |
catch (e) { | |
var m = e; | |
} | |
} | |
} | |
} | |
}; | |
this.Rend = function () { | |
this.Ctx.clearRect(0, 0, this.Canvas.width, this.Canvas.height); | |
for (var i = 0; i < this.Words.length; i++) { | |
var word = this.Words[i]; | |
this.Ctx.drawImage(word.Text.Image, word.X , word.Y ); | |
} | |
if (this.OnFinish != undefined && this.OnFinish != null) { | |
this.OnFinish(); | |
} | |
} | |
this.ExportIndex = 0; | |
this.GetPrintImageEX = function (callback) { | |
var ratio = 4; | |
if (this.ExportIndex == 0) { | |
this.ExportCallback = callback; | |
document.Canvas = null; | |
this.ExportCanvas = document.createElement("canvas"); | |
this.ExportCanvas.width = this.Image.width * ratio; | |
this.ExportCanvas.height = this.Image.height * ratio; | |
this.ExportCtx = this.ExportCanvas.getContext("2d"); | |
} | |
var word = this.Words[this.ExportIndex]; | |
var biger = this.GetText(word.Text.Word, word.Text.FontSize, word.Text.FontFamily, word.Text.Color, word.Text.Angle, ratio); | |
this.ExportCtx.drawImage(biger.Image, word.X * ratio, word.Y * ratio); | |
this.ExportIndex++; | |
if (this.ExportIndex < this.Words.length) { | |
if (this.OnProgress != undefined && this.OnProgress != null) { | |
var p = this.ExportIndex * 100 / this.Words.length; | |
this.Progress = p; | |
setTimeout(this.OnProgress, 0); | |
} | |
setTimeout(function () { document._MontageObj.GetPrintImageEX(); }, 0); | |
} | |
else { | |
if (this.OnProgress != undefined && this.OnProgress != null) { | |
this.Progress = 100; | |
setTimeout(this.OnProgress, 0); | |
} | |
var data = this.ExportCanvas.toDataURL("image/png"); | |
this.ExportCallback(data); | |
this.ExportCtx = 0; | |
} | |
}; | |
this.GetPrintImage = function (ratio) { | |
document.Canvas = null; | |
var canvas = document.createElement("canvas"); | |
canvas.width = this.Image.width * ratio; | |
canvas.height = this.Image.height * ratio; | |
var ctx = canvas.getContext("2d"); | |
for (var i = 0; i < this.Words.length; i++) { | |
var word = this.Words[i]; | |
var biger = this.GetText(word.Text.Word, word.Text.FontSize, word.Text.FontFamily, word.Text.Color, word.Text.Angle, ratio); | |
ctx.drawImage(biger.Image, word.X * ratio, word.Y * ratio); | |
} | |
var data = canvas.toDataURL("image/png"); | |
// var img = document.createElement("img"); | |
// img.src = data; | |
return data; | |
}; | |
this.ChangeColor = function (colors) { | |
this.Colors = colors; | |
document.Canvas = null; | |
this.Ctx.clearRect(0, 0, this.Canvas.width, this.Canvas.height); | |
for (var i = 0; i < this.Words.length; i++) { | |
var word = this.Words[i]; | |
word.Text = this.GetText(word.Text.Word, word.Text.FontSize, word.Text.FontFamily, colors[parseInt(Math.random()*colors.length)], word.Text.Angle); | |
this.Ctx.drawImage(word.Text.Image, word.X, word.Y); | |
} | |
if (this.OnFinish != undefined && this.OnFinish != null) { | |
this.OnFinish(); | |
} | |
} | |
this.GetPath = function () { | |
var imageData = this.PathCtx.getImageData(0, 0, this.Image.width, this.Image.height); | |
var Colors = []; | |
this.Words = []; | |
this.PotWidth = this.Image.width / blockSize; | |
if (this.Image.width % blockSize > 0) this.PotWidth++; | |
this.PotHeight = this.Image.height / blockSize; | |
if (this.Image.height % blockSize > 0) this.PotHeight++; | |
var l = this.PotWidth, t = this.PotHeight, r = 0, b = 0; | |
this.Pots = []; | |
for (var i = 0; i < this.PotWidth; i++) { | |
var col = []; | |
for (var j = 0; j < this.PotHeight; j++) { | |
var blank = true; | |
for (var x = i * blockSize; x < i * blockSize + blockSize; x++) { | |
if (x >= this.Image.width) { | |
continue; | |
} | |
for (var y = j * blockSize; y < j * blockSize + blockSize; y++) { | |
if (y > this.Image.height) continue; | |
var pos = x + y * this.Image.width; | |
var color = { | |
R: imageData.data[pos * 4], | |
G: imageData.data[pos * 4 + 1], | |
B: imageData.data[pos * 4 + 2], | |
A: imageData.data[pos * 4 + 3], | |
X: x, | |
Y: y | |
}; | |
color.Black = IsBlack(color); | |
if (color.Black == false) { | |
blank = false; | |
break; | |
} | |
else { | |
color.Blank == true; | |
} | |
} | |
if (!blank) break; | |
} | |
var p = { Blank: blank, X: i, Y: j, Black: !blank }; | |
col[j] = p; | |
if (p.Blank) { | |
if (i < l) { | |
l = i; | |
} | |
if (i > r) { | |
r = i; | |
} | |
if (j < t) { | |
t = j; | |
} | |
if (j > b) { | |
b = j; | |
} | |
} | |
} | |
this.Pots[i] = col; | |
} | |
this.L = l; | |
this.T = t; | |
this.B = b; | |
this.R = r; | |
}; | |
this.Refresh = function () { | |
this.GetPath(); | |
this.AddText(); | |
}; | |
this.fontsize = 48; | |
this.AddTextEx = function () { | |
var fonts = this.Fonts; | |
var words = this.Text.split(" "); | |
var angles = this.Angles; | |
var colors = this.Colors; | |
if (this.fontsize >= this.MinFont) { | |
for (var k in words) { | |
var word = words[k]; | |
if (word == "") continue; | |
var c = colors[parseInt(Math.random() * colors.length)]; | |
var degree = angles[parseInt(Math.random() * angles.length)]; | |
var font = fonts[parseInt(Math.random() * fonts.length )]; | |
var txt = this.GetText(word, this.fontsize, font, c, degree); // this.GetText(word, fontsize, font, c, degree); | |
var l = this.L + parseInt(Math.random() * (this.R - this.L + 1)); | |
var t = this.T + parseInt(Math.random() * (this.B - this.T + 1)); | |
var pos = this.FindPlace(txt, l, t); | |
var times = this.MaxFont / this.fontsize; | |
while (pos != null) { | |
this.DrawText(txt, pos.X, pos.Y); | |
if (times-- > 0) { | |
l = this.L + parseInt(Math.random() * (this.R - this.L + 1)); | |
t = this.T + parseInt(Math.random() * (this.B - this.T + 1)); | |
pos = this.FindPlace(txt, l, t); | |
} | |
else { | |
break; | |
} | |
} | |
} | |
if (this.OnProgress != undefined && this.OnProgress != null) { | |
var p = (this.MaxFont - this.fontsize + 1) * 100 / (this.MaxFont - this.MinFont + 1); | |
setTimeout(this.OnProgress, 0); | |
this.Progress = p; | |
} | |
this.fontsize -= 2; | |
setTimeout(function () { document._MontageObj.AddTextEx(); }, 0); | |
} | |
else { | |
this.Rend(); | |
this.fontsize = this.MaxFont; | |
} | |
} | |
this.AddText = function (word) { | |
this.Words = []; | |
document.Canvas = null; | |
if (this.OnProgress != undefined && this.OnProgress != null) { | |
this.fontsize = this.MaxFont; | |
this.AddTextEx(); | |
return; | |
} | |
var fontsize = 48; | |
var fonts = this.Fonts; | |
var words = this.Text.split(" "); | |
var angles = this.Angles; | |
var colors = this.Colors; | |
for (fontsize = this.MaxFont; fontsize >= this.MinFont; fontsize -= 2) { | |
for (var k in words) { | |
var word = words[k]; | |
var c = colors[parseInt(Math.random() * colors.length)]; | |
var degree = angles[parseInt(Math.random() * angles.length)]; | |
var font = fonts[parseInt(Math.random() * fonts.length)]; | |
var txt = this.GetText(word, fontsize, font, c, degree); // this.GetText(word, fontsize, font, c, degree); | |
var l = this.L + parseInt(Math.random() * (this.R - this.L + 1)); | |
var t = this.T + parseInt(Math.random() * (this.B - this.T + 1)); | |
var pos = this.FindPlace(txt, l, t); | |
var times = this.MaxFont / this.fontsize; | |
while (pos != null) { | |
this.DrawText(txt, pos.X, pos.Y); | |
if (times-- > 0) { | |
l = this.L + parseInt(Math.random() * (this.R - this.L + 1)); | |
t = this.T + parseInt(Math.random() * (this.B - this.T + 1)); | |
pos = this.FindPlace(txt, l, t); | |
} | |
else { | |
break; | |
} | |
} | |
} | |
if (this.OnProgress != undefined && this.OnProgress != null) { | |
this.Progress = p; | |
} | |
} | |
this.Rend(); | |
}; | |
this.FindPlace=function(text,x,y){ | |
if (this.Direction == 0) | |
{ | |
//find to left | |
for (var i = x ; i >= this.L; i -= 2) | |
{ | |
if (this.Canput(text, i, y)) | |
{ | |
return { X : i, Y : y }; | |
} | |
} | |
} | |
this.Direction = 1; | |
//find to right | |
if (this.Direction == 1) | |
{ | |
for (var i = x +1; i <= this.R - text.PotWidth; i++) | |
{ | |
if (this.Canput(text, i, y)) | |
{ | |
return { X : i, Y : y }; | |
} | |
} | |
} | |
this.Direction = 2; | |
//find to top | |
if (this.Direction == 2) | |
{ | |
for (var j = y - 1; j >= this.T; j--) | |
{ | |
for (var i = x - 1; i >= this.L; i--) | |
{ | |
if (this.Canput(text, i, j)) | |
{ | |
return { X : i, Y :j }; | |
} | |
} | |
for (var i = x + 1; i <= this.R - text.PotWidth; i++) | |
{ | |
if (this.Canput(text, i, j)) | |
{ | |
return { X : i, Y :j }; | |
} | |
} | |
} | |
} | |
this.Direction = 3; | |
//find to bottom | |
if (this.Direction == 3) | |
{ | |
for (var j = y + 1; j <= this.B - text.PotHeight; j++) | |
{ | |
for (var i = x - 1; i >= this.L; i--) | |
{ | |
if (this.Canput(text, i, j)) | |
{ | |
return { X : i, Y :j }; | |
} | |
} | |
for (var i = x + 1; i <= this.R - text.PotWidth; i++) | |
{ | |
if (this.Canput(text, i, j)) | |
{ | |
return { X: i, Y: j }; | |
} | |
} | |
} | |
} | |
this.Direction = 0; | |
return null; | |
} | |
this.LoadPath = function (url,callBack) { | |
this.ImageReady = false; | |
this.Image.src = url; | |
this.Image.CallBack=callBack; | |
} | |
this.Canput = function (textBlock, left, top) { | |
for (var i = 0; i < textBlock.PotWidth; i++) { | |
for (var j = 0; j < textBlock.PotHeight; j++) { | |
if (textBlock.Pots[i][j].Black) { | |
if (left + i > this.R) return false; | |
if (top + j > this.B) return false; | |
if (this.Pots[left + i][top + j].Black) { | |
return false; | |
} | |
//check blank | |
if (i <= textBlock.PotWidth / 2) { | |
if (left + i > this.L) { | |
if (this.Pots[left + i - 1][top + j].Black) { | |
return false; | |
} | |
} | |
} | |
else if (i > textBlock.PotWidth / 2) { | |
if (left + i < this.R) { | |
if (this.Pots[left + i + 1][top + j].Black) { | |
return false; | |
} | |
} | |
} | |
if (j < textBlock.PotHeight / 2) { | |
if (top + j > this.T) { | |
if (this.Pots[left + i][top + j - 1].Black) { | |
return false; | |
} | |
} | |
} | |
else if (top + j < this.B) { | |
if (this.Pots[left + i][top + j + 1].Black) { | |
return false; | |
} | |
} | |
} | |
} | |
} | |
return true; | |
} | |
this.GetImage = function (imageData) { | |
var temp = document.createElement("canvas"); | |
temp.width = imageData.width; | |
temp.height = imageData.height; | |
var ctx = temp.getContext("2d"); | |
ctx.putImageData(imageData, 0, 0); | |
var data = temp.toDataURL("image/png"); | |
var img = document.createElement("img"); | |
img.src = data; | |
img.width = 266; | |
return img; | |
}; | |
this.GetText = function (word, size, font, color, angle, ratio) { | |
if (ratio == null || ratio == undefined) ratio = 1; | |
if (document.Canvas == undefined || document.Canvas == null) { | |
var canvas = document.createElement("canvas"); | |
canvas.width = 1000 * ratio; | |
canvas.height = 1000 * ratio; | |
document.Canvas = canvas.getContext("2d"); | |
document.Canvas.imageSmoothingEnabled = true; | |
document.Canvas.translate(500 * ratio, 500 * ratio); | |
document.Canvas.textBaseline = "top"; | |
} | |
var Canvas = document.Canvas; | |
var s = parseInt(size * ratio); | |
Canvas.font = s + "px " + font; | |
Canvas.fillStyle = color; | |
var pos = Canvas.measureText(word); | |
pos.height = s; | |
var d = pos.width + pos.height; | |
Canvas.save(); | |
if (angle != 0) { | |
Canvas.rotate(angle * Math.PI / 180); | |
} | |
Canvas.fillText(word, 0, 0); | |
Canvas.restore(); | |
var imageData = Canvas.getImageData(500 * ratio - d, 500 * ratio - d, 2 * d, 2 * d); | |
var l = imageData.width, r = 0, b = 0, t = imageData.height; | |
for (var i = 0; i < imageData.width; i++) { | |
for (var j = 0; j < imageData.height; j++) { | |
var pos = (j * imageData.width + i) * 4; | |
if (imageData.data[pos + 3] > 0) { | |
if (i < l) { | |
l = i; | |
} | |
if (r < i) { | |
r = i; | |
} | |
if (b < j) { | |
b = j; | |
} | |
if (t > j) { | |
t = j; | |
} | |
} | |
} | |
} | |
var bl = parseInt(2 * ratio); | |
l -= bl; | |
r += bl; | |
t -= bl; | |
b += bl; | |
imageData = Canvas.getImageData(500 * ratio - d + l, 500 * ratio - d + t, r + 1 - l, b + 1 - t); | |
Canvas.clearRect(-d, -d, 2 * d, 2 * d); | |
var Text = {}; | |
Text.Image = this.GetImage(imageData); | |
Text.Word = word; | |
Text.FontSize = size; | |
Text.FontFamily = font; | |
Text.Width = imageData.width; | |
Text.Height = imageData.height; | |
Text.Color = color; | |
Text.Angle = angle; | |
Text.Pots = []; | |
Text.PotWidth = 0; | |
Text.PotHeight = 0; | |
Text.PotWidth = parseInt(Text.Width / blockSize); | |
if (Text.Width % blockSize > 0) Text.PotWidth++; | |
Text.PotHeight = parseInt(Text.Height / blockSize); | |
if (Text.Height % blockSize > 0) Text.PotHeight++; | |
//get pots | |
Text.Pots = []; | |
for (var i = 0; i < Text.PotWidth; i++) { | |
var col = []; | |
for (var j = 0; j < Text.PotHeight; j++) { | |
var blank = true; | |
for (var x = i * blockSize; x < i * blockSize + blockSize; x++) { | |
if (x >= this.Width) { | |
continue; | |
} | |
for (var y = j * blockSize; y < j * blockSize + blockSize; y++) { | |
if (y >= this.Height) continue; | |
var pos = y * Text.Width + x; | |
if (imageData.data[pos * 4 + 3] > 0) { | |
blank = false; | |
break; | |
} | |
} | |
if (!blank) break; | |
} | |
var p = { Blank: blank, X: i, Y: j, Black: !blank }; | |
col[j] = p; | |
} | |
Text.Pots[i] = col; | |
} | |
return Text; | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment