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