Skip to content

Commit

Permalink
Cropped favorites thumbnails
Browse files Browse the repository at this point in the history
  • Loading branch information
prevostc committed Mar 4, 2015
1 parent 7ba7e9b commit 0258208
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 37 deletions.
14 changes: 14 additions & 0 deletions www/css/style.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
/* Empty. Add your own CSS if you like */
.canvas-container {
height: 100%;
}

.my-image-item{
left: 0;
right: 0;
}

.my-image-item img {
height: 100%;
}

.item-avatar.my-image-item img {
max-width: 150px;
max-height: 150px;
}
35 changes: 19 additions & 16 deletions www/js/controllers.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,25 @@
mapData.name = Faker.getMapName();
mapData.catchPhrase = Faker.getMapCatchPhrase();

// store generation metadata
mapData.harborGenerationPhrase = {
'separate-tiles': 'Separate Tiles (18 tiles)',
'coast-bars': 'Enclosing edges bars (6 long pieces)'
}[Settings.getHarborGenerationStrategy()];
mapData.fairnessPhrase = {
11: 'Fair',
12: 'Normal',
13: 'Unfair'
}[Settings.getTileTrioScoreLimit()];

$scope.mapData = mapData;
$scope.starred = false;
};

$scope.starred = false;
$scope.star = function() {
// resize image and save
var widthCoeff = 1/ (Math.max(width(), height()) / Image.getThumbnailWidth());
var heightCoeff = 1/ (Math.max(width(), height()) / Image.getThumbnailHeight());
Image.resizeBase64Uri($scope.mapData.thumbnailImageUri, function(resizedBase46Url) {
$scope.$apply(function(){
$scope.mapData.thumbnailImageUri = resizedBase46Url;
Favorites.save($scope.mapData);
$scope.starred = true;
});
},
widthCoeff * width(),
heightCoeff * height()
);
Favorites.save($scope.mapData);
$scope.starred = true;
};
})

Expand Down Expand Up @@ -118,7 +118,7 @@
};
})

.directive("map", function (Settings)
.directive("map", function (Settings, Image)
{
return {
restrict: 'E',
Expand Down Expand Up @@ -151,16 +151,19 @@
canvas.width = scope.canvasContainer.parentElement.offsetWidth;
canvas.height = scope.canvasContainer.parentElement.offsetHeight;
Catan.UI.LowDefinition.drawMap(mapData.map, canvas);
scope.mapData.thumbnailImageUri = Catan.UI.LowDefinition.getBase64String(canvas);
} else if (assetLoaded) {
Catan.UI.HighDefinition.draw(
renderer,
mapData.map,
scope.canvasContainer.parentElement.offsetWidth,
scope.canvasContainer.parentElement.offsetHeight
);
scope.mapData.thumbnailImageUri = Catan.UI.HighDefinition.getBase64String(renderer);
}
Image.getCroppedAndResizedBase64Uri(canvas, function(thumbnailImageUri) {
scope.$apply(function(){
scope.mapData.thumbnailImageUri = thumbnailImageUri;
});
});
});
}
};
Expand Down
108 changes: 88 additions & 20 deletions www/js/services.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
})

.factory('Favorites', function (localStorageService) {
var saveAll = function(mapsData) {
var saveAll = function (mapsData) {
var serializedMapsData = [];
for (var i = 0; i < mapsData.length; i++) {
mapsData[i].map = Catan.Map.serialize(mapsData[i].map);
Expand Down Expand Up @@ -78,40 +78,108 @@
})

.factory('Image', function () {

function getNonWhiteCoordinates(canvas) {
// from http://stackoverflow.com/questions/12175991/crop-image-white-space-automatically-using-jquery
var context = canvas.getContext('2d');
var imgWidth = canvas.width, imgHeight = canvas.height,
imageData = context.getImageData(0, 0, imgWidth, imgHeight),
data = imageData.data,
getRBG = function (x, y) {
var offset = imgWidth * y + x;
return {
red: data[offset * 4],
green: data[offset * 4 + 1],
blue: data[offset * 4 + 2],
opacity: data[offset * 4 + 3]
};
},
isWhite = function (rgb) {
// many images contain noise, as the white is not a pure #fff white
return rgb.red > 200 && rgb.green > 200 && rgb.blue > 200;
},
scanY = function (fromTop) {
var offset = fromTop ? 1 : -1;

// loop through each row
for (var y = fromTop ? 0 : imgHeight - 1; fromTop ? (y < imgHeight) : (y > -1); y += offset) {

// loop through each column
for (var x = 0; x < imgWidth; x++) {
var rgb = getRBG(x, y);
if (!isWhite(rgb)) {
return y;
}
}
}
return null; // all image is white
},
scanX = function (fromLeft) {
var offset = fromLeft ? 1 : -1;

// loop through each column
for (var x = fromLeft ? 0 : imgWidth - 1; fromLeft ? (x < imgWidth) : (x > -1); x += offset) {

// loop through each row
for (var y = 0; y < imgHeight; y++) {
var rgb = getRBG(x, y);
if (!isWhite(rgb)) {
return x;
}
}
}
return null; // all image is white
};

var res = {
cropTop: scanY(true),
cropBottom: scanY(false),
cropLeft: scanX(true),
cropRight: scanX(false)
};
res.cropWidth = res.cropRight - res.cropLeft;
res.cropHeight = res.cropBottom - res.cropTop;

return res;
}

var Image = {
getThumbnailWidth: function () {
return 80;
return 150;
},
getThumbnailHeight: function () {
return 80;
return 150;
},
resizeBase64Uri: function (base64Uri, callback, wantedWidth, wantedHeight) {
getCroppedAndResizedBase64Uri: function (canvasToCropAndResize, callback, wantedWidth, wantedHeight) {
wantedWidth = wantedWidth || Image.getThumbnailWidth();
wantedHeight = wantedHeight || Image.getThumbnailHeight();

// We create an image to receive the Data URI
var img = document.createElement('img');
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
var imageObj = document.createElement('img');

// When the event "onload" is triggered we can resize the image.
img.onload = function () {
// We create a canvas and get its context.
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
var cropCoordinates = getNonWhiteCoordinates(canvasToCropAndResize);

// We set the dimensions at the wanted size.
canvas.width = wantedWidth;
canvas.height = wantedHeight;
imageObj.onload = function () {

// We resize the image with the canvas method drawImage();
ctx.drawImage(this, 0, 0, wantedWidth, wantedHeight);
// draw cropped image based on http://www.html5canvastutorials.com/tutorials/html5-canvas-image-crop/
var sourceX = cropCoordinates.cropLeft;
var sourceY = cropCoordinates.cropTop;
var sourceWidth = cropCoordinates.cropWidth;
var sourceHeight = cropCoordinates.cropHeight;
var destWidth = Image.getThumbnailWidth();
var destHeight = Image.getThumbnailHeight();
var destX = 0;
var destY = 0;

var resizedBase64Uri = canvas.toDataURL();
canvas.width = destWidth;
canvas.height = destHeight;
context.drawImage(imageObj, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight);

callback(resizedBase64Uri);
callback(canvas.toDataURL());
};

// We put the Data URI in the image's src attribute
img.src = base64Uri;
imageObj.src = canvasToCropAndResize.toDataURL();
}
};

Expand Down
2 changes: 2 additions & 0 deletions www/templates/tab-favorites.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
<img ng-src="{{item.thumbnailImageUri}}">
<h2>{{item.name}}</h2>
<p>{{item.catchPhrase}}</p>
<p>Harbors: {{item.harborGenerationPhrase}}</p>
<p>Fairness: {{item.fairnessPhrase}}</p>
<ion-delete-button class="ion-minus-circled" ng-click="deleteItem(item)"></ion-delete-button>
</ion-item>
</ion-list>
Expand Down
2 changes: 1 addition & 1 deletion www/templates/tabs.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<ion-tabs class="tabs-icon-top tabs-color-active-positive">

<!-- Favorites Tab -->
<ion-tab title="Favorites" icon-off="ion-clock" icon-on="ion-clock" href="#/tab/favorites">
<ion-tab title="Favorites" icon-off="ion-star" icon-on="ion-star" href="#/tab/favorites">
<ion-nav-view name="tab-favorites"></ion-nav-view>
</ion-tab>

Expand Down

0 comments on commit 0258208

Please sign in to comment.