diff --git a/app/lib/utils.coffee b/app/lib/utils.coffee index 663dbe959..44ef9dd1c 100644 --- a/app/lib/utils.coffee +++ b/app/lib/utils.coffee @@ -109,3 +109,12 @@ module.exports.keepDoingUntil = (func, wait=100, totalWait=5000) -> if (waitSoFar += wait) <= totalWait and not success _.delay (-> func done), wait) false +module.exports.grayscale = (imageData) -> + d = imageData.data + for i in [0..d.length] by 4 + r = d[i] + g = d[i+1] + b = d[i+2] + v = 0.2126*r + 0.7152*g + 0.0722*b + d[i] = d[i+1] = d[i+2] = v + imageData diff --git a/app/models/Achievement.coffee b/app/models/Achievement.coffee index 1010d2eaf..74d7d55d9 100644 --- a/app/models/Achievement.coffee +++ b/app/models/Achievement.coffee @@ -24,5 +24,30 @@ module.exports = class Achievement extends CocoModel getNotifyStyle: -> Achievement.styleMapping[@get 'difficulty'] + @defaultImageURL: '/images/achievements/default.png' + getImageURL: -> - if @get 'icon' then '/file/' + @get('icon') else '/images/achievements/default.png' + if @get 'icon' then '/file/' + @get('icon') else Achievement.defaultImageURL + + hasImage: -> @get('icon')? + + # TODO Could cache the default icon separately + cacheLockedImage: -> + return @lockedImageURL if @lockedImageURL + canvas = document.createElement 'canvas' + image = new Image + image.src = @getImageURL() + defer = $.Deferred() + image.onload = => + canvas.width = image.width + canvas.height = image.height + context = canvas.getContext '2d' + context.drawImage image, 0, 0 + imgData = context.getImageData 0, 0, canvas.width, canvas.height + imgData = utils.grayscale imgData + context.putImageData imgData, 0, 0 + @lockedImageURL = canvas.toDataURL() + defer.resolve @lockedImageURL + defer + + getLockedImageURL: -> @lockedImageURL diff --git a/app/styles/achievements.sass b/app/styles/achievements.sass index 141d24e76..122f81e45 100644 --- a/app/styles/achievements.sass +++ b/app/styles/achievements.sass @@ -1,7 +1,5 @@ .locked - filter: desaturate(gray, 50) - -moz-filter: desaturate(gray, 50) - -webkit-filter: desaturate(gray, 50) + // This used to be a grayscale filter but they're mad intensive to paint .achievement-body .achievement-icon @@ -19,8 +17,14 @@ right: 0 bottom: 0 + &.locked + .achievement-content + background-image: url("/images/achievements/achievement_background_locked.png") + &:not(.locked) + .achievement-content + background-image: url("/images/achievements/achievement_background.png") + .achievement-content - background-image: url("/images/achievements/reward_background2.png") background-size: 100% 100% text-align: center overflow: hidden @@ -150,30 +154,48 @@ background-size: 100% 100% z-index: 1 +.achievement-icon + background-size: 100% 100% !important + .notifyjs-achievement-wood-base, .achievement-wood - .achievement-icon - background: url("/images/achievements/border_wood.png") no-repeat - background-size: 100% 100% + &.locked + .achievement-icon + background: url("/images/achievements/border_wood_locked.png") no-repeat + &:not(.locked) + .achievement-icon + background: url("/images/achievements/border_wood.png") no-repeat .notifyjs-achievement-stone-base, .achievement-stone - .achievement-icon - background: url("/images/achievements/border_stone.png") no-repeat - background-size: 100% 100% + &.locked + .achievement-icon + background: url("/images/achievements/border_stone_locked.png") no-repeat + &:not(.locked) + .achievement-icon + background: url("/images/achievements/border_stone.png") no-repeat .notifyjs-achievement-silver-base, .achievement-silver - .achievement-icon - background: url("/images/achievements/border_silver.png") no-repeat - background-size: 100% 100% + &.locked + .achievement-icon + background: url("/images/achievements/border_silver_locked.png") no-repeat + &:not(.locked) + .achievement-icon + background: url("/images/achievements/border_silver.png") no-repeat .notifyjs-achievement-gold-base, .achievement-gold - .achievement-icon - background: url("/images/achievements/border_gold.png") no-repeat - background-size: 100% 100% + &.locked + .achievement-icon + background: url("/images/achievements/border_gold_locked.png") no-repeat + &:not(.locked) + .achievement-icon + background: url("/images/achievements/border_gold.png") no-repeat .notifyjs-achievement-diamond-base, .achievement-diamond - .achievement-icon - background: url("/images/achievements/border_diamond.png") no-repeat - background-size: 100% 100% + &.locked + .achievement-icon + background: url("/images/achievements/border_diamond_locked.png") no-repeat + &:not(.locked) + .achievement-icon + background: url("/images/achievements/border_diamond.png") no-repeat .exp-bar-accumulated background-color: #680080 diff --git a/app/templates/achievement_notify.jade b/app/templates/achievement_notify.jade index 505097224..5b07afabd 100644 --- a/app/templates/achievement_notify.jade +++ b/app/templates/achievement_notify.jade @@ -1,15 +1,15 @@ -div(class=notifyClass) - .clearfix.achievement-body(class=locked === true ? "locked" : "") - .achievement-icon - .achievement-image(data-notify-html="image") - if imgURL - img(src=imgURL) - .achievement-content - .achievement-title(data-notify-html="title") #{title} - p.achievement-description(data-notify-html="description") #{description} +- var addedClass = notifyClass + (locked === true ? ' locked' : '') +.clearfix.achievement-body(class=addedClass) + .achievement-icon + .achievement-image(data-notify-html="image") + if imgURL + img(src=imgURL) + .achievement-content + .achievement-title(data-notify-html="title") #{title} + p.achievement-description(data-notify-html="description") #{description} - if popup - .progress-wrapper - span.user-level.badge(data-notify-html="level") - .progress-bar-wrapper(data-notify-html="progressBar") - .progress-bar-border + if popup + .progress-wrapper + span.user-level.badge(data-notify-html="level") + .progress-bar-wrapper(data-notify-html="progressBar") + .progress-bar-border diff --git a/app/templates/user/achievements.jade b/app/templates/user/achievements.jade index 1bdf4bc85..cd64db67e 100644 --- a/app/templates/user/achievements.jade +++ b/app/templates/user/achievements.jade @@ -13,9 +13,14 @@ block append content each achievement, index in achievements - var title = achievement.get('name'); - var description = achievement.get('description'); - - var imgURL = achievement.getImageURL(); - var locked = ! achievement.get('unlocked'); - var notifyClass = achievement.getNotifyStyle() + - var imgURL = achievement.getImageURL(); + if locked + - var imgURL = achievement.getLockedImageURL(); + else + - var imgURL = achievement.getImageURL(); + - console.log(locked); .col-lg-4.col-xs-12 include ../achievement_notify else if activeLayout === 'table' diff --git a/app/views/user/AchievementsView.coffee b/app/views/user/AchievementsView.coffee index 7ca4dfb72..20cc05717 100644 --- a/app/views/user/AchievementsView.coffee +++ b/app/views/user/AchievementsView.coffee @@ -25,13 +25,16 @@ module.exports = class AchievementsView extends UserView super user onLoaded: -> - console.log @earnedAchievements + console.log @earnedAchievementsy console.log @achievements - _.each @earnedAchievements.models, (earned) => + for earned in @earnedAchievements.models return unless relatedAchievement = _.find @achievements.models, (achievement) -> achievement.get('_id') is earned.get 'achievement' relatedAchievement.set 'unlocked', true earned.set 'achievement', relatedAchievement + deferredImages = (achievement.cacheLockedImage() for achievement in @achievements.models when not achievement.get 'unlocked') + whenever = $.when deferredImages... + whenever.done => @render() super() layoutChanged: (e) -> diff --git a/public/images/achievements/reward_background2.png b/public/images/achievements/achievement_background.png similarity index 100% rename from public/images/achievements/reward_background2.png rename to public/images/achievements/achievement_background.png diff --git a/public/images/achievements/achievement_background_locked.png b/public/images/achievements/achievement_background_locked.png new file mode 100644 index 000000000..94a300b12 Binary files /dev/null and b/public/images/achievements/achievement_background_locked.png differ diff --git a/public/images/achievements/border_diamond_locked.png b/public/images/achievements/border_diamond_locked.png new file mode 100644 index 000000000..bc56fbc75 Binary files /dev/null and b/public/images/achievements/border_diamond_locked.png differ diff --git a/public/images/achievements/border_gold_locked.png b/public/images/achievements/border_gold_locked.png new file mode 100644 index 000000000..f1ee95e3d Binary files /dev/null and b/public/images/achievements/border_gold_locked.png differ diff --git a/public/images/achievements/border_silver_locked.png b/public/images/achievements/border_silver_locked.png new file mode 100644 index 000000000..44bcc7e84 Binary files /dev/null and b/public/images/achievements/border_silver_locked.png differ diff --git a/public/images/achievements/border_stone_locked.png b/public/images/achievements/border_stone_locked.png new file mode 100644 index 000000000..66f92b2b4 Binary files /dev/null and b/public/images/achievements/border_stone_locked.png differ diff --git a/public/images/achievements/border_wood_locked.png b/public/images/achievements/border_wood_locked.png new file mode 100644 index 000000000..167e87421 Binary files /dev/null and b/public/images/achievements/border_wood_locked.png differ