mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-07 14:05:52 +01:00
add image diff
This commit is contained in:
@@ -100,7 +100,8 @@ object JGitUtil {
|
|||||||
def isDifferentFromAuthor: Boolean = authorName != committerName || authorEmailAddress != committerEmailAddress
|
def isDifferentFromAuthor: Boolean = authorName != committerName || authorEmailAddress != committerEmailAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
case class DiffInfo(changeType: ChangeType, oldPath: String, newPath: String, oldContent: Option[String], newContent: Option[String])
|
case class DiffInfo(changeType: ChangeType, oldPath: String, newPath: String, oldContent: Option[String], newContent: Option[String],
|
||||||
|
oldIsImage: Boolean, newIsImage: Boolean, oldObjectId: Option[String], newObjectId: Option[String])
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The file content data for the file content view of the repository viewer.
|
* The file content data for the file content view of the repository viewer.
|
||||||
@@ -459,11 +460,13 @@ object JGitUtil {
|
|||||||
treeWalk.addTree(revCommit.getTree)
|
treeWalk.addTree(revCommit.getTree)
|
||||||
val buffer = new scala.collection.mutable.ListBuffer[DiffInfo]()
|
val buffer = new scala.collection.mutable.ListBuffer[DiffInfo]()
|
||||||
while(treeWalk.next){
|
while(treeWalk.next){
|
||||||
|
val newIsImage = FileUtil.isImage(treeWalk.getPathString)
|
||||||
buffer.append((if(!fetchContent){
|
buffer.append((if(!fetchContent){
|
||||||
DiffInfo(ChangeType.ADD, null, treeWalk.getPathString, None, None)
|
DiffInfo(ChangeType.ADD, null, treeWalk.getPathString, None, None, false, newIsImage, None, Option(treeWalk.getObjectId(0)).map(_.name))
|
||||||
} else {
|
} else {
|
||||||
DiffInfo(ChangeType.ADD, null, treeWalk.getPathString, None,
|
DiffInfo(ChangeType.ADD, null, treeWalk.getPathString, None,
|
||||||
JGitUtil.getContentFromId(git, treeWalk.getObjectId(0), false).filter(FileUtil.isText).map(convertFromByteArray))
|
JGitUtil.getContentFromId(git, treeWalk.getObjectId(0), false).filter(FileUtil.isText).map(convertFromByteArray),
|
||||||
|
false, newIsImage, None, Option(treeWalk.getObjectId(0)).map(_.name))
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
(buffer.toList, None)
|
(buffer.toList, None)
|
||||||
@@ -483,12 +486,15 @@ object JGitUtil {
|
|||||||
import scala.collection.JavaConverters._
|
import scala.collection.JavaConverters._
|
||||||
git.getRepository.getConfig.setString("diff", null, "renames", "copies")
|
git.getRepository.getConfig.setString("diff", null, "renames", "copies")
|
||||||
git.diff.setNewTree(newTreeIter).setOldTree(oldTreeIter).call.asScala.map { diff =>
|
git.diff.setNewTree(newTreeIter).setOldTree(oldTreeIter).call.asScala.map { diff =>
|
||||||
if(!fetchContent || FileUtil.isImage(diff.getOldPath) || FileUtil.isImage(diff.getNewPath)){
|
val oldIsImage = FileUtil.isImage(diff.getOldPath)
|
||||||
DiffInfo(diff.getChangeType, diff.getOldPath, diff.getNewPath, None, None)
|
val newIsImage = FileUtil.isImage(diff.getNewPath)
|
||||||
|
if(!fetchContent || oldIsImage || newIsImage){
|
||||||
|
DiffInfo(diff.getChangeType, diff.getOldPath, diff.getNewPath, None, None, oldIsImage, newIsImage, Option(diff.getOldId).map(_.name), Option(diff.getNewId).map(_.name))
|
||||||
} else {
|
} else {
|
||||||
DiffInfo(diff.getChangeType, diff.getOldPath, diff.getNewPath,
|
DiffInfo(diff.getChangeType, diff.getOldPath, diff.getNewPath,
|
||||||
JGitUtil.getContentFromId(git, diff.getOldId.toObjectId, false).filter(FileUtil.isText).map(convertFromByteArray),
|
JGitUtil.getContentFromId(git, diff.getOldId.toObjectId, false).filter(FileUtil.isText).map(convertFromByteArray),
|
||||||
JGitUtil.getContentFromId(git, diff.getNewId.toObjectId, false).filter(FileUtil.isText).map(convertFromByteArray))
|
JGitUtil.getContentFromId(git, diff.getNewId.toObjectId, false).filter(FileUtil.isText).map(convertFromByteArray),
|
||||||
|
oldIsImage, newIsImage, Option(diff.getOldId).map(_.name), Option(diff.getNewId).map(_.name))
|
||||||
}
|
}
|
||||||
}.toList
|
}.toList
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,13 +90,32 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="padding: 0;">
|
<td style="padding: 0;">
|
||||||
@if(diff.newContent != None || diff.oldContent != None){
|
@if(diff.oldObjectId == diff.newObjectId){
|
||||||
|
<div class="diff-same">File renamed without changes</div>
|
||||||
|
} else { @if(diff.newContent != None || diff.oldContent != None){
|
||||||
<div id="diffText-@i" class="diffText"></div>
|
<div id="diffText-@i" class="diffText"></div>
|
||||||
<textarea id="newText-@i" style="display: none;" data-file-name="@diff.oldPath">@diff.newContent.getOrElse("")</textarea>
|
<textarea id="newText-@i" style="display: none;" data-file-name="@diff.oldPath">@diff.newContent.getOrElse("")</textarea>
|
||||||
<textarea id="oldText-@i" style="display: none;" data-file-name="@diff.newPath">@diff.oldContent.getOrElse("")</textarea>
|
<textarea id="oldText-@i" style="display: none;" data-file-name="@diff.newPath">@diff.oldContent.getOrElse("")</textarea>
|
||||||
|
} else { @if(diff.newIsImage || diff.oldIsImage){
|
||||||
|
<div class="diff-image-render diff2up">
|
||||||
|
@if(oldCommitId.isDefined && diff.oldIsImage){
|
||||||
|
<div class="diff-image-frame diff-old"><img src="@url(repository)/blob/@oldCommitId.get/@diff.oldPath?raw=true" class="diff-image" onload="onLoadedDiffImages(this)" style="display:none" /></div>
|
||||||
} else {
|
} else {
|
||||||
|
@if(diff.changeType != ChangeType.ADD){
|
||||||
Not supported
|
Not supported
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@if(newCommitId.isDefined && diff.newIsImage){
|
||||||
|
<div class="diff-image-frame diff-new"><img src="@url(repository)/blob/@newCommitId.get/@diff.newPath?raw=true" class="diff-image" onload="onLoadedDiffImages(this)" style="display:none" /></div>
|
||||||
|
} else {
|
||||||
|
@if(diff.changeType != ChangeType.DELETE){
|
||||||
|
Not supported
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
} else {
|
||||||
|
Not supported
|
||||||
|
} } }
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@@ -1151,6 +1151,149 @@ table.diff tbody tr.not-diff:hover td{
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
letter-spacing: 0px;
|
letter-spacing: 0px;
|
||||||
}
|
}
|
||||||
|
.diff-same{
|
||||||
|
background: #DDD;
|
||||||
|
color: #BBB;
|
||||||
|
font-size: 16px;
|
||||||
|
padding: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
/* ------- for imageDiff */
|
||||||
|
.diff-image-frame{
|
||||||
|
display: table-cell;
|
||||||
|
*float: left; /* for ie7 */
|
||||||
|
vertical-align: middle;
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
.diff-image-frame.diff-old{
|
||||||
|
padding-right: 2px;
|
||||||
|
}
|
||||||
|
.diff-image-frame.diff-new{
|
||||||
|
padding-left: 2px;
|
||||||
|
}
|
||||||
|
.diff-image-frame .diff-meta{
|
||||||
|
margin-top: 12px;
|
||||||
|
color: #999;
|
||||||
|
font-family: Helvetica,arial,freesans,clean,sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
.diff-image-frame.diff-old .diff-meta .diff{
|
||||||
|
color: #bd2c00;
|
||||||
|
}
|
||||||
|
.diff-image-frame.diff-new .diff-meta .diff{
|
||||||
|
color: #55a532;
|
||||||
|
}
|
||||||
|
.diff-image-frame img{
|
||||||
|
max-height: 410px;
|
||||||
|
max-width: 410px;
|
||||||
|
background: url(../images/checker.png);
|
||||||
|
}
|
||||||
|
.diff-image-render.diff2up{
|
||||||
|
width:100%;
|
||||||
|
text-align: center;
|
||||||
|
display: table;
|
||||||
|
}
|
||||||
|
.diff-image-frame.diff-new img{
|
||||||
|
border: 1px solid #55a532;
|
||||||
|
}
|
||||||
|
.diff-image-frame.diff-old img{
|
||||||
|
border: 1px solid #bd2c00;
|
||||||
|
}
|
||||||
|
.diff-image-stack{
|
||||||
|
position: relative;
|
||||||
|
background: #EEE;
|
||||||
|
padding-top: 20px;
|
||||||
|
}
|
||||||
|
.diff-image-stack .diff-old,
|
||||||
|
.diff-image-stack .diff-new{
|
||||||
|
position:absolute;
|
||||||
|
overflow: hidden;
|
||||||
|
margin:0 20px;
|
||||||
|
}
|
||||||
|
.diff-image-stack img {
|
||||||
|
max-width: none;
|
||||||
|
background: url(../images/checker.png);
|
||||||
|
}
|
||||||
|
.diff-image-stack .diff-new{
|
||||||
|
border: 1px solid #55a532;
|
||||||
|
background: #EEE;
|
||||||
|
}
|
||||||
|
.diff-image-stack .diff-old{
|
||||||
|
border: 1px solid #bd2c00;
|
||||||
|
}
|
||||||
|
.diff-swipe-handle{
|
||||||
|
position:absolute;
|
||||||
|
margin-left: 325px;
|
||||||
|
left: 100px;
|
||||||
|
}
|
||||||
|
.diff-silde-bar{
|
||||||
|
width: 200px;
|
||||||
|
position: absolute;
|
||||||
|
left: 325px;
|
||||||
|
margin: 6px 0 0 7px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 1px solid gray;
|
||||||
|
height: 8px;
|
||||||
|
}
|
||||||
|
.image-diff-tools{
|
||||||
|
text-align: center;
|
||||||
|
padding: 4px;
|
||||||
|
background: #f7f7f7;
|
||||||
|
}
|
||||||
|
.image-diff-tools{
|
||||||
|
font-family: 'Helvetica Neue', Helvetica, arial, freesans, clean, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
background: #f7f7f7;
|
||||||
|
margin: 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.image-diff-tools li{
|
||||||
|
background: none;
|
||||||
|
display: inline;
|
||||||
|
cursor: pointer;
|
||||||
|
border-right: 1px solid #ccc;
|
||||||
|
padding: 0 5px;
|
||||||
|
position: relative;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
.image-diff-tools li:last-child{
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
.image-diff-tools li.active {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.no-canvas .need-canvas{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.diff-image-stack.swipe .diff-new{
|
||||||
|
border-right: 1px solid #888;
|
||||||
|
}
|
||||||
|
.diff-image-stack.swipe .diff-swipe-handle{
|
||||||
|
margin-left: 15px;
|
||||||
|
left: 410px;
|
||||||
|
}
|
||||||
|
.diff-image-stack.swipe .diff-silde-bar{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.diff-image-stack.onion .diff-silde-bar{
|
||||||
|
background: -ms-linear-gradient(left, #bd2c00 0%,#55a532 100%); /* IE10+ */
|
||||||
|
background: linear-gradient(to right, #bd2c00 0%,#55a532 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#bd2c00', endColorstr='#55a532',GradientType=1 ); /* IE6-9 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.diff-image-stack.blink .diff-silde-bar{
|
||||||
|
border-style: dotted;
|
||||||
|
background-image: linear-gradient(to right, #bd2c00, #bd2c00 50%, #55a532 50%, #55a532 100%);
|
||||||
|
background-size: 2px 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.diff-image-stack.difference {
|
||||||
|
padding-bottom: 18px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
/* Repository Settings */
|
/* Repository Settings */
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|||||||
BIN
src/main/webapp/assets/common/images/checker.png
Normal file
BIN
src/main/webapp/assets/common/images/checker.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 949 B |
@@ -334,3 +334,211 @@ $.extend(JsDiffRender.prototype,{
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
/****************************************************************************/
|
||||||
|
/* Diff */
|
||||||
|
/****************************************************************************/
|
||||||
|
// add naturalWidth and naturalHeight for ie 8
|
||||||
|
function setNatural(img) {
|
||||||
|
if(typeof img.naturalWidth == 'undefined'){
|
||||||
|
var tmp = new Image();
|
||||||
|
tmp.src = img.src;
|
||||||
|
img.naturalWidth = tmp.width;
|
||||||
|
img.naturalHeight = tmp.height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* onload handler
|
||||||
|
* @param img <img>
|
||||||
|
*/
|
||||||
|
function onLoadedDiffImages(img){
|
||||||
|
setNatural(img);
|
||||||
|
img = $(img);
|
||||||
|
img.show();
|
||||||
|
var tb = img.parents(".diff-image-render");
|
||||||
|
// Find images. If the image has not loaded yet, value is undefined.
|
||||||
|
var old = tb.find(".diff-old img.diff-image:visible")[0];
|
||||||
|
var neo = tb.find(".diff-new img.diff-image:visible")[0];
|
||||||
|
imageDiff.appendImageMeta(tb, old, neo);
|
||||||
|
if(old && neo){
|
||||||
|
imageDiff.createToolSelector(old, neo).appendTo(tb.parent());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var imageDiff ={
|
||||||
|
/** append image meta div after image nodes.
|
||||||
|
* @param tb <div class="diff-image-2up">
|
||||||
|
* @param old <img>||undefined
|
||||||
|
* @param neo <img>||undefined
|
||||||
|
*/
|
||||||
|
appendImageMeta:function(tb, old, neo){
|
||||||
|
old = old || {};
|
||||||
|
neo = neo || {};
|
||||||
|
tb.find(".diff-meta").remove();
|
||||||
|
// before loaded, image is not visible.
|
||||||
|
tb.find("img.diff-image:visible").each(function(){
|
||||||
|
var div = $('<p class="diff-meta"><b>W:</b><span class="w"></span> | <b>W:</b><span class="h"></span></p>');
|
||||||
|
div.find('.w').text(this.naturalWidth+"px").toggleClass("diff", old.naturalWidth != neo.naturalWidth);
|
||||||
|
div.find('.h').text(this.naturalHeight+"px").toggleClass("diff", old.naturalHeight != neo.naturalHeight);
|
||||||
|
div.appendTo(this.parentNode);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** check this browser can use canvas tag.
|
||||||
|
*/
|
||||||
|
hasCanvasSupport:function(){
|
||||||
|
if(!this.hasCanvasSupport.hasOwnProperty('resultCache')){
|
||||||
|
this.hasCanvasSupport.resultCache = (typeof $('<canvas>')[0].getContext)=='function';
|
||||||
|
}
|
||||||
|
return this.hasCanvasSupport.resultCache;
|
||||||
|
},
|
||||||
|
/** create toolbar
|
||||||
|
* @param old <img>
|
||||||
|
* @param neo <img>
|
||||||
|
* @return jQuery(<ul class="image-diff-tools">)
|
||||||
|
*/
|
||||||
|
createToolSelector:function(old, neo){
|
||||||
|
var self = this;
|
||||||
|
return $('<ul class="image-diff-tools">'+
|
||||||
|
'<li data-mode="diff2up" class="active">2-up</li>'+
|
||||||
|
'<li data-mode="swipe">Swipe</li>'+
|
||||||
|
'<li data-mode="onion">Onion Skin</li>'+
|
||||||
|
'<li data-mode="difference" class="need-canvas">Difference</li>'+
|
||||||
|
'<li data-mode="blink">Blink</li>'+
|
||||||
|
'</ul>')
|
||||||
|
.toggleClass('no-canvas', !this.hasCanvasSupport())
|
||||||
|
.on('click', 'li', function(e){
|
||||||
|
var td = $(this).parents("td");
|
||||||
|
$(e.delegateTarget).find('li').each(function(){ $(this).toggleClass('active',this == e.target); });
|
||||||
|
var mode = $(e.target).data('mode');
|
||||||
|
td.find(".diff-image-render").hide();
|
||||||
|
// create div if not created yet
|
||||||
|
if(td.find(".diff-image-render."+mode).show().length===0){
|
||||||
|
self[mode](old, neo).insertBefore(e.delegateTarget).addClass("diff-image-render");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** (private) calc size from images and css (const)
|
||||||
|
* @param old <img>
|
||||||
|
* @param neo <img>
|
||||||
|
*/
|
||||||
|
calcSizes:function(old, neo){
|
||||||
|
var maxWidth = 869 - 20 - 20 - 4; // set by css
|
||||||
|
var h = Math.min(Math.max(old.naturalHeight, neo.naturalHeight),maxWidth);
|
||||||
|
var w = Math.min(Math.max(old.naturalWidth, neo.naturalWidth),maxWidth);
|
||||||
|
var oldRate = Math.min(h/old.naturalHeight, w/old.naturalWidth);
|
||||||
|
var neoRate = Math.min(h/neo.naturalHeight, w/neo.naturalWidth);
|
||||||
|
var neoW = neo.naturalWidth*neoRate;
|
||||||
|
var neoH = neo.naturalHeight*neoRate;
|
||||||
|
var oldW = old.naturalWidth*oldRate;
|
||||||
|
var oldH = old.naturalHeight*oldRate;
|
||||||
|
var paddingLeft = (maxWidth/2)-Math.max(neoW,oldW)/2;
|
||||||
|
return {
|
||||||
|
height:Math.max(oldH, neoH),
|
||||||
|
width:w,
|
||||||
|
padding:paddingLeft,
|
||||||
|
paddingTop:20, // set by css
|
||||||
|
barWidth:200, // set by css
|
||||||
|
old:{ rate:oldRate, width:oldW, height:oldH },
|
||||||
|
neo:{ rate:neoRate, width:neoW, height:neoH }
|
||||||
|
};
|
||||||
|
},
|
||||||
|
/** (private) create div
|
||||||
|
* @param old <img>
|
||||||
|
* @param neo <img>
|
||||||
|
*/
|
||||||
|
stack:function(old, neo){
|
||||||
|
var size = this.calcSizes(old, neo);
|
||||||
|
var diffNew = $('<div class="diff-new">')
|
||||||
|
.append($("<img>").attr('src',neo.src).css({width:size.neo.width, height:size.neo.height}));
|
||||||
|
var diffOld = $('<div class="diff-old">')
|
||||||
|
.append($("<img>").attr('src',old.src).css({width:size.old.width, height:size.old.height}));
|
||||||
|
var handle = $('<span class="diff-swipe-handle icon icon-resize-horizontal"></span>')
|
||||||
|
.css({marginTop:size.height-5});
|
||||||
|
var bar = $('<hr class="diff-silde-bar">').css({top:size.height+size.paddingTop});
|
||||||
|
var div = $('<div class="diff-image-stack">')
|
||||||
|
.css({height:size.height+size.paddingTop, paddingLeft:size.padding})
|
||||||
|
.append(diffOld, diffNew, bar, handle);
|
||||||
|
return {
|
||||||
|
neo:diffNew,
|
||||||
|
old:diffOld,
|
||||||
|
size:size,
|
||||||
|
handle:handle,
|
||||||
|
bar:bar,
|
||||||
|
div:div,
|
||||||
|
/* add event listener 'on mousemove' */
|
||||||
|
onMoveHandleOnBar:function(callback){
|
||||||
|
div.on('mousemove',function(e){
|
||||||
|
var x = Math.max(Math.min((e.pageX - bar.offset().left), size.barWidth), 0);
|
||||||
|
handle.css({left:x});
|
||||||
|
callback(x, e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
/** create swipe box
|
||||||
|
* @param old <img>
|
||||||
|
* @param neo <img>
|
||||||
|
* @return jQuery(<div class="diff-image-stack swipe">)
|
||||||
|
*/
|
||||||
|
swipe:function(old, neo){
|
||||||
|
var stack = this.stack(old, neo);
|
||||||
|
function setX(x){
|
||||||
|
stack.neo.css({width:x});
|
||||||
|
stack.handle.css({left:x+stack.size.padding});
|
||||||
|
}
|
||||||
|
setX(stack.size.neo.width/2);
|
||||||
|
stack.div.on('mousemove',function(e){
|
||||||
|
setX(Math.max(Math.min(e.pageX - stack.neo.offset().left, stack.size.neo.width),0));
|
||||||
|
});
|
||||||
|
return stack.div.addClass('swipe');
|
||||||
|
},
|
||||||
|
/** create blink box
|
||||||
|
* @param old <img>
|
||||||
|
* @param neo <img>
|
||||||
|
* @return jQuery(<div class="diff-image-stack blink">)
|
||||||
|
*/
|
||||||
|
blink:function(old, neo){
|
||||||
|
var stack = this.stack(old, neo);
|
||||||
|
stack.onMoveHandleOnBar(function(x){
|
||||||
|
stack.neo.toggle(Math.floor(x) % 2 === 0);
|
||||||
|
});
|
||||||
|
return stack.div.addClass('blink');
|
||||||
|
},
|
||||||
|
/** create onion skin box
|
||||||
|
* @param old <img>
|
||||||
|
* @param neo <img>
|
||||||
|
* @return jQuery(<div class="diff-image-stack onion">)
|
||||||
|
*/
|
||||||
|
onion:function(old, neo){
|
||||||
|
var stack = this.stack(old, neo);
|
||||||
|
stack.neo.css({opacity:0.5});
|
||||||
|
stack.onMoveHandleOnBar(function(x){
|
||||||
|
stack.neo.css({opacity:x/stack.size.barWidth});
|
||||||
|
});
|
||||||
|
return stack.div.addClass('onion');
|
||||||
|
},
|
||||||
|
/** create difference box
|
||||||
|
* @param old <img>
|
||||||
|
* @param neo <img>
|
||||||
|
* @return jQuery(<div class="diff-image-stack difference">)
|
||||||
|
*/
|
||||||
|
difference:function(old, neo){
|
||||||
|
var size = this.calcSizes(old,neo);
|
||||||
|
var canvas = $('<canvas>').attr({width:size.width, height:size.height})[0];
|
||||||
|
var context = canvas.getContext('2d');
|
||||||
|
|
||||||
|
context.clearRect(0, 0, size.width, size.height);
|
||||||
|
context.drawImage(neo, 0, 0, size.neo.width, size.neo.height);
|
||||||
|
var neoData = context.getImageData(0, 0, size.neo.width, size.neo.height).data;
|
||||||
|
context.clearRect(0, 0, size.width, size.height);
|
||||||
|
|
||||||
|
context.drawImage(old, 0, 0, size.old.width, size.old.height);
|
||||||
|
var c = context.getImageData(0, 0, size.neo.width, size.neo.height);
|
||||||
|
var cData = c.data;
|
||||||
|
for (var i = cData.length -1; i>0; i --){
|
||||||
|
cData[i] = (i%4===3) ? Math.max(cData[i], neoData[i]) : Math.abs(cData[i] - neoData[i]);
|
||||||
|
}
|
||||||
|
context.putImageData(c, 0, 0);
|
||||||
|
|
||||||
|
return $('<div class="diff-image-stack difference">').append(canvas);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user