diff --git a/base/assets/javascripts/base.coffee b/base/assets/javascripts/base.coffee index eb9fc61c..7e15efe4 100644 --- a/base/assets/javascripts/base.coffee +++ b/base/assets/javascripts/base.coffee @@ -32,5 +32,19 @@ ready = -> ($ '.happening-decade-list').toggleClass 'visible' ($ '.happening-toggle .ss-icon:last-child').toggleClass 'ss-navigatedown ss-navigateup' -$(document).ready ready -$(document).on 'page:load', ready + # jquery.adaptive-background options and instantiation. + defaults = + parent: '[data-adaptive-parent="1"]' + lumaClasses: + light: 'ab-light' + dark: 'ab-dark' + + $.adaptiveBackground.run(defaults) + ($ '[data-adaptive-parent="1"]').on 'ab-color-found', (ev, payload) -> + console.log payload.color # The dominant color in the image. + console.log payload.palette # The color palette found in the image. + console.log ev # The jQuery.Event object. + return + +($ document).ready ready +($ document).on 'page:load', ready diff --git a/base/assets/stylesheets/partials/_landings.scss b/base/assets/stylesheets/partials/_landings.scss index 3eda4a37..d96aa132 100644 --- a/base/assets/stylesheets/partials/_landings.scss +++ b/base/assets/stylesheets/partials/_landings.scss @@ -373,9 +373,8 @@ font-size: 12px; } } - .happening-event-list { - font-size: 13px; - } + .happening-event-list { font-size: 13px; } + .event-groups-started .happening-actors { display: none; } } .happening-explore-more { text-align: right; diff --git a/base/static/javascripts/components/jquery.adaptive-backgrounds.js b/base/static/javascripts/components/jquery.adaptive-backgrounds.js new file mode 100644 index 00000000..0a801cac --- /dev/null +++ b/base/static/javascripts/components/jquery.adaptive-backgrounds.js @@ -0,0 +1,118 @@ + +/* jshint debug: true, expr: true */ + +;(function($){ + + /* Constants & defaults. */ + var DATA_COLOR = 'data-ab-color'; + var DATA_PARENT = 'data-ab-parent'; + var DATA_CSS_BG = 'data-ab-css-background'; + var EVENT_CF = 'ab-color-found'; + + var DEFAULTS = { + selector: '[data-adaptive-background="1"]', + parent: null, + normalizeTextColor: false, + normalizedTextColors: { + light: "#fff", + dark: "#000" + }, + lumaClasses: { + light: "ab-light", + dark: "ab-dark" + } + }; + + // Include RGBaster - https://github.com/briangonzalez/rgbaster.js + /* jshint ignore:start */ + !function(a){"use strict";var b=function(){return document.createElement("canvas").getContext("2d")},c=function(a,c){var d=new Image,e=a.src||a;"data:"!==e.substring(0,5)&&(d.crossOrigin="Anonymous"),d.onload=function(){var a=b();a.drawImage(d,0,0);var e=a.getImageData(0,0,d.width,d.height);c&&c(e.data)},d.src=e},d=function(a){return["rgb(",a,")"].join("")},e=function(a){return a.map(function(a){return d(a.name)})},f=5,g=10,h={};h.colors=function(a,b,h){c(a,function(a){for(var c=a.length,i={},j="",k=[],l={dominant:{name:"",count:0},palette:Array.apply(null,Array(h||g)).map(Boolean).map(function(){return{name:"0,0,0",count:0}})},m=0;c>m;){if(k[0]=a[m],k[1]=a[m+1],k[2]=a[m+2],j=k.join(","),i[j]=j in i?i[j]+1:1,"0,0,0"!==j&&"255,255,255"!==j){var n=i[j];n>l.dominant.count?(l.dominant.name=j,l.dominant.count=n):l.palette.some(function(a){return n>a.count?(a.name=j,a.count=n,!0):void 0})}m+=4*f}b&&b({dominant:d(l.dominant.name),palette:e(l.palette)})})},a.RGBaster=a.RGBaster||h}(window); + /* jshint ignore:end */ + + + /* + Our main function declaration. + */ + $.adaptiveBackground = { + run: function( options ){ + var opts = $.extend({}, DEFAULTS, options); + + /* Loop over each element, waiting for it to load + then finding its color, and triggering the + color found event when color has been found. + */ + $( opts.selector ).each(function(index, el){ + var $this = $(this); + + /* Small helper functions which applie + colors, attrs, triggers events, and check for css + */ + var handleColors = function(){ + var img = useCSSBackground() ? CSSBackground() : $this[0]; + + RGBaster.colors(img, function(colors){ + $this.attr(DATA_COLOR, colors.dominant); + $this.trigger(EVENT_CF, { color: colors.dominant, palette: colors.palette }); + }, 20); + }; + + var useCSSBackground = function(){ + return $this.attr( DATA_CSS_BG ); + }; + + var CSSBackground = function(){ + return $this.css('background-image') + .replace('url(','').replace(')',''); + }; + + /* Subscribe to our color-found event. */ + $this.on( EVENT_CF, function(ev, data){ + var $data = data; + var $parent; + + if ( useCSSBackground() ){ + $parent = $this; + } + else if ( $this.attr( DATA_PARENT ) ){ + $parent = $this.parents( $this.attr( DATA_PARENT ) ); + } + else if (opts.parent) { + $parent = $this.parents( opts.parent ); + } + else { + $parent = $this.parent(); + } + + $parent.css({ backgroundColor: data.color }); + + // Helper function to calculate yiq - http://en.wikipedia.org/wiki/YIQ + var getYIQ = function(color){ + var rgb = $data.color.match(/\d+/g); + return ((rgb[0]*299)+(rgb[1]*587)+(rgb[2]*114))/1000; + }; + + var getNormalizedTextColor = function (color){ + return getYIQ(color) >= 128 ? opts.normalizedTextColors.dark : opts.normalizedTextColors.light; + }; + + var getLumaClass = function (color){ + return getYIQ(color) <= 128 ? opts.lumaClasses.dark : opts.lumaClasses.light; + }; + + // Normalize the text color based on luminance. + if ( opts.normalizeTextColor ) + $parent.css({ color: getNormalizedTextColor(data.color) }); + + // Add a class based on luminance. + $parent.addClass( getLumaClass(data.color) ) + .attr('data-ab-yaq', getYIQ(data.color)); + + }); + + /* Handle the colors. */ + handleColors(); + + }); + }, + }; + +})(jQuery); diff --git a/base/templates/base.html b/base/templates/base.html index b77a1402..bc33159f 100644 --- a/base/templates/base.html +++ b/base/templates/base.html @@ -23,7 +23,6 @@ -{% include "partials/assets.html" %} {% if not debug %} + diff --git a/base/templates/people/group_detail.html b/base/templates/people/group_detail.html index ea1357af..5ba71e14 100644 --- a/base/templates/people/group_detail.html +++ b/base/templates/people/group_detail.html @@ -13,12 +13,12 @@
-