Try to be smarter about scaling images on canvases

This commit is contained in:
Robin Ward 2016-09-21 16:48:48 -04:00
parent 14bee641aa
commit 62e1f88adc
7 changed files with 50 additions and 11 deletions

View File

@ -93,7 +93,7 @@ export default createPreviewComponent(659, 320, {
ctx.font = `${bodyFontSize}em 'Arial'`;
const textPos = y + (topicHeight * 0.45);
ctx.fillStyle = textColor;
ctx.drawImage(this.avatar, cols[2], y + (margin * 0.6), avatarSize, avatarSize);
this.scaleImage(this.avatar, cols[2], y + (margin * 0.6), avatarSize, avatarSize);
ctx.fillText(title, cols[3], textPos);
ctx.font = `Bold ${bodyFontSize}em 'Arial'`;
@ -174,7 +174,7 @@ export default createPreviewComponent(659, 320, {
ctx.fillStyle = colors.primary;
ctx.fillText(category.name, cols[1] + (badgeSize * 1.5), y + (rowHeight * 0.65));
ctx.drawImage(this.avatar, cols[2], y + rowHeight * 0.3, rowHeight * 0.5, rowHeight * 0.5);
this.scaleImage(this.avatar, cols[2], y + rowHeight * 0.3, rowHeight * 0.5, rowHeight * 0.5);
ctx.fillStyle = textColor;
ctx.font = `${bodyFontSize}em 'Arial'`;

View File

@ -15,7 +15,7 @@ export default createPreviewComponent(325, 125, {
},
paint(ctx, colors, width, height) {
ctx.drawImage(this.image, 10, 8, 87, 87);
ctx.drawImage(this.ios, 0, 0, width, height);
this.scaleImage(this.image, 10, 8, 87, 87);
this.scaleImage(this.ios, 0, 0, width, height);
}
});

View File

@ -16,8 +16,8 @@ export default createPreviewComponent(371, 124, {
},
paint(ctx, colors, width, height) {
ctx.drawImage(this.tab, 0, 0, width, height);
ctx.drawImage(this.image, 40, 25, 30, 30);
this.scaleImage(this.tab, 0, 0, width, height);
this.scaleImage(this.image, 40, 25, 30, 30);
ctx.font = `20px 'Arial'`;
ctx.fillStyle = '#000';

View File

@ -34,7 +34,7 @@ export default createPreviewComponent(375, 100, {
imageWidth = maxWidth;
}
ctx.drawImage(image, headerMargin, headerMargin, imageWidth, image.height * ratio);
this.scaleImage(image, headerMargin, headerMargin, imageWidth, image.height * ratio);
const afterLogo = (headerMargin * 1.7) + imageWidth;
const fontSize = Math.round(headerHeight * 0.4);

View File

@ -24,7 +24,7 @@ export default createPreviewComponent(400, 100, {
const imageHeight = headerHeight - (headerMargin * 2);
const ratio = imageHeight / image.height;
ctx.drawImage(image, headerMargin, headerMargin, image.width * ratio, imageHeight);
this.scaleImage(image, headerMargin, headerMargin, image.width * ratio, imageHeight);
this.drawPills(colors, height / 2);
}

View File

@ -30,7 +30,7 @@ export default createPreviewComponent(659, 320, {
const lineHeight = height / 19.0;
// Draw a fake topic
ctx.drawImage(this.avatar, margin, headerHeight + (height * 0.17), avatarSize, avatarSize);
this.scaleImage(this.avatar, margin, headerHeight + (height * 0.17), avatarSize, avatarSize);
const titleFontSize = headerHeight / 44;

View File

@ -13,6 +13,21 @@ accumsan sapien, nec feugiat quam. Quisque non risus.
placerat lacus vitae, lacinia nisi. Sed metus arcu, iaculis
sit amet cursus nec, sodales at eros.`;
const scaled = {};
function canvasFor(image, w, h) {
w = Math.ceil(w);
h = Math.ceil(h);
const can = document.createElement('canvas');
can.width = w;
can.height = h;
const ctx = can.getContext('2d');
ctx.drawImage(image, 0, 0, w, h);
return can;
}
export function createPreviewComponent(width, height, obj) {
return Ember.Component.extend({
layoutName: 'components/theme-preview',
@ -75,6 +90,30 @@ export function createPreviewComponent(width, height, obj) {
return [{name: 'consecteteur', color: '#652D90'}, {name: 'ultrices', color: '#3AB54A'}];
},
scaleImage(image, x, y, w, h) {
w = Math.floor(w);
h = Math.floor(h);
const { ctx } = this;
const key = `${image.src}-${w}-${h}`;
if (!scaled[key]) {
let copy = image;
let ratio = copy.width / copy.height;
let newH = (copy.height * 0.5);
while (newH > h) {
copy = canvasFor(copy, ratio * newH, newH);
newH = newH * 0.5;
}
scaled[key] = copy;
}
ctx.drawImage(scaled[key], x, y, w, h);
},
drawFullHeader(colors) {
const { ctx } = this;
@ -87,10 +126,10 @@ export function createPreviewComponent(width, height, obj) {
const headerMargin = headerHeight * 0.2;
const logoHeight = headerHeight - (headerMargin * 2);
const logoWidth = (logoHeight / this.logo.height) * this.logo.width;
ctx.drawImage(this.logo, headerMargin, headerMargin, logoWidth, logoHeight);
this.scaleImage(this.logo, headerMargin, headerMargin, logoWidth, logoHeight);
// Top right menu
ctx.drawImage(this.avatar, width - avatarSize - headerMargin, headerMargin, avatarSize, avatarSize);
this.scaleImage(this.avatar, width - avatarSize - headerMargin, headerMargin, avatarSize, avatarSize);
ctx.fillStyle = darkLightDiff(colors.primary, colors.secondary, 45, 55);
const headerFontSize = headerHeight / 44;