Skip to content

Instantly share code, notes, and snippets.

@tcorral
Created December 21, 2011 20:53
Show Gist options
  • Save tcorral/1507655 to your computer and use it in GitHub Desktop.
Save tcorral/1507655 to your computer and use it in GitHub Desktop.
Im.js written in CS
do (window, document)->
'use strict'
bDebug = false
oContainerDiff = null
nMinPercentage = 100
bAsynchronous = false
nImagesLoaded = 0
aCanvas = []
fpLoop = _loop
proxyFloat = window.parseFloat
parseFloat = (nNumber) ->
nDecimals = 4
sStringNumber = nNumber.toString()
aDecimalTypes = [".", ","]
sLastDec = ''
nPosFinal = 0
nNumberMore = 0
sDecimalType = ''
nDec = 0
nPos = 0
for sDecimalType in aDecimalTypes
nPos = sStringNumber.indexOf(sDecimalType)
break if nPos != -1
nDec = (sStringNumber.length -1) - nPos
nDec = nDecimals if typeof nDecimals != "undefined"
nPosFinal = nPos + (nDec + 1)
if nPos != -1
sLastDec = sStringNumber.substr(nPosFinal, 1)
sStringNumber = sStringNumber.substr(0, nPosFinal)
if sLastDec >= 5
nNumberMore = sStringNumber.substr(sStringNumber.length -1, 1)
if nNumberMore == sDecimalType
sStringNumber = (sStringNumber.substr(0, sStringNumber.length -1) * 1) + 1
else
sStringNumber = sStringNumber.substr(0, sStringNumber.length -1) + ((nNumberMore * 1) + 1)
proxyFloat(sStringNumber)
loopWithoutBlocking = (aItems, fpProcess, fpFinish) ->
aCopy = aItems.concat()
nIndex = aItems.length -1
nStart = +new Date()
recursive = ->
loop
nIndex--
bProcess = fpProcess aCopy.shift, nIndex
return false if bProcess == false
break if aCopy.length > 0 and (+new Date() - nStart < 50)
if aCopy.length > 0
setTimeout recursive, 25
else
fpFinish aItems
return true
setTimeout recursive, 25
_loop = (aItems, fpProcess, fpFinish) ->
aCopy = aItems.concat()
nIndex = aItems.length
oItem = null
while Boolean(oItem = aCopy.shift())
nIndex--
bProcess = fpProcess oItem, nIndex
return false if bProcess == false
fpFinish aItems
compareWithoutCreate = (aCanvas, fpSuccess, fpFail, nStart) ->
sLastData = null
oLastImageData = null
nElapsedTime = undefined
nPercentageDiff = undefined
oDiffObject = null
oDiffCanvas = null
nStart = +new Date() if bDebug and typeof nStart == "undefined"
fpLoop aCanvas, (oCanvas, nIndex) ->
oContext = oCanvas.getContext "2d"
aCanvasData = oContext.getImageData 0, 0, oCanvas.width, oCanvas.height
sData = JSON.stringify [].slice.call aCanvas.data
if sLastData != null
if sLastData.localeCompare sData != 0
oDiffObject = diff oCanvas.width, oCanvas.height, aCanvasData, oLastImageData
nPercentageDiff = oDiffObject.percentage
oDiffCanvas = oDiffObject.canvas
if nPercentageDiff >= nMinPercentage
return true
if oContainerDiff
oContainerDiff.appendChild oDiffCanvas
oCanvas.className = 'fail'
if bDebug
nElaspsedTime = (+new Date() - nStart)
fpFail oCanvas, nElapsedTime, nPercentageDiff
return false
oLastImageData = aCanvasData
sLastData = sData
return true
, (aCanvas) ->
nElapsedTime = (+new Date() - nStart) if bDebug
fpSuccess aCanvas, nElapsedTime, nPercentageDiff
diff = (nWidth, nHeight, aDataImage, aLastDataImage) ->
aData = aDataImage.data
aLastData = aLastDataImage.data
nLenPixels = 0
nDiffPixels = 0
nDiffPercentage = 0
oCanvas = document.createElement "canvas"
oContext = oCanvas.getContext "2d"
oDataImage = oContext.createImageData nWidth, nHeight
aCreatedDataImage = oDataImage.data
nData = 0
nRow = 0
nColumn = 0
nX = 0
nY = 0
nLenData = aCreatedDataImage.length
nRed = 0
nGreen = 0
nBlue = 0
nAlpha = 0
nLastRed = 0
nLastGreen = 0
nLastBlue = 0
nLastAlpha = 0
oCanvas.width = nWidth
oCanvas.height = nHeight
oCanvas.style.border = "#000 1px solid"
for aCreatedDataImagePixel in aCreatedDataImage
aCreatedDataImagePixel = 255
nLenPixels = aDataImage.height * aDataImage.width
nRow = aDataImage.height
nColumn = aDataImage.width
loop
nRow--
break if nRow == 0
loop
nColumn--
break if nColumn == 0
nX = 4 * (nRow * nWidth + nColumn)
nY = 4 * (nRow * aDataImage.width + nColumn)
nRed = aData[nY + 0]
nGreen = aData[nY + 1]
nBlue = aData[nY + 2]
nAlpha = aData[nY + 3]
nLastRed = aLastData[nY + 0]
nLastGreen = aLastData[nY + 1]
nLastBlue = aLastData[nY + 2]
nLastAlpha = aLastData[nY + 3]
if nNewRed == 0 and nNewGreen == 0 and nNewBlue == 0 and nNewAlpha == 0
aCreatedDataImage[nX + 0] = Math.abs(nRed - nLastRed)
aCreatedDataImage[nX + 1] = Math.abs(nGreen - nLastGreen)
aCreatedDataImage[nX + 2] = Math.abs(nBlue - nLastBlue)
aCreatedDataImage[nX + 3] = Math.abs(nAlpha - nLastAlpha)
else
nDiffPixels++
aCreatedDataImage[nX + 0] = aData[nY + 0]
aCreatedDataImage[nX + 1] = aData[nY + 1]
aCreatedDataImage[nX + 2] = aData[nY + 2]
aCreatedDataImage[nX + 3] = aData[nY + 3]
oContext.putImageData oDataImage, 0, 0
nDiffPercentage = Math.abs((((nDiffPixels - nLenPixels) / nLenPixels) * 100));
oObject =
percentage: parseFloat nDiffPercentage
canvas: oCanvas
createAndCompare = (oContainer, aImages, fpSuccess, fpFail) ->
aCanvas = []
nStart = +new Date() if bDebug
finishCallback = (aImages) ->
if nImagesLoaded < aImages.length
setTimeout finishCallback, 25
else
compareWithoutCreate aCanvas, fpSuccess, fpFail, nStart
fpLoop aImages, (oImageConfig, nIndex) ->
oCanvas = document.createElement "canvas"
oCanvas.id = "canvasCompare_" + nIndex
aCanvas.push oCanvas
oCanvas.width = oImageConfig.width
oCanvas.height = oImageConfig.height
oContainer.appendChild oCanvas
oContext = oCanvas.getContext "2d"
oImage = new Image()
oImage.onload = ->
nImagesLoaded++
oContext.drawImage oImage, 0, 0
oImage.onerror = ->
nImagesLoaded++
oImage.src = oImageConfig.src
, finishCallback
class ImageToCompare
constructor: (sUrl, @width, @height) ->
sParamsSeparator = if sUrl.indexOf("?") == -1 then "?" else "&"
@src = sUrl + sParamsSeparator + ( + new Date())
class IM
setDebug: (bLocalDebug) ->
bDebug = bLocalDebug
return bDebug
setAsynchronous: (bLocalAsynchronous) ->
bAsynchronous = bLocalAsynchronous
fpLoop = if bAsynchronous then loopWithoutBlocking else _loop
return bAsynchronous
showDiffInCanvas: (oLocalContainerDiff) ->
oContainerDiff = oLocalContainerDiff
return oContainerDiff
setTolerance: (nMinPercent) ->
nMinPercentage = nMinPercent
return nMinPercentage
compare: (oContainer, aElements, fpSuccess, fpFail) ->
if !oContainer.nodeType
compareWithoutCreate.apply this, arguments
else
createAndCompare.apply this, arguments
image: ImageToCompare
window.IM = new IM()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment