From 42725692c20a4b37fee8a8d03e92c0d5e022b62f Mon Sep 17 00:00:00 2001 From: Gil Barbara Date: Mon, 20 Jul 2015 20:50:54 -0300 Subject: [PATCH] add color and filter to tags --- app/scripts/App.jsx | 17 +- app/scripts/components/Header.jsx | 70 ++++--- app/scripts/utils/Colors.js | 307 +++++++++++++++++++++++++++++ app/scripts/utils/ScaleLog.js | 21 ++ app/scripts/utils/scaleLog.js | 21 -- app/styles/components/_header.scss | 1 + package.json | 17 +- 7 files changed, 398 insertions(+), 56 deletions(-) create mode 100644 app/scripts/utils/Colors.js create mode 100644 app/scripts/utils/ScaleLog.js delete mode 100644 app/scripts/utils/scaleLog.js diff --git a/app/scripts/App.jsx b/app/scripts/App.jsx index 72848be..fcdc2ca 100644 --- a/app/scripts/App.jsx +++ b/app/scripts/App.jsx @@ -37,12 +37,24 @@ var App = React.createClass({ this._changeColumns(this.state.columns + col); }, - _changeColumns(num) { + _onClickTag (e) { + e.preventDefault(); + + var el = e.currentTarget; + + console.log(el); + }, + + _changeColumns (num) { this.setState({ columns: num }); }, + _filterLogos (tag) { + + }, + render () { var state = this.state, logos = []; @@ -62,7 +74,8 @@ var App = React.createClass({
+ onClickChangeColumns={this._onClickChangeColumns} + onClickTag={this._onClickTag}/>
    {logos} diff --git a/app/scripts/components/Header.jsx b/app/scripts/components/Header.jsx index 06c281c..0caa4e1 100644 --- a/app/scripts/components/Header.jsx +++ b/app/scripts/components/Header.jsx @@ -1,5 +1,7 @@ var React = require('react/addons'), - ScaleLog = require('../utils/scaleLog'), + lodash = require('lodash'), + Colors = require('../utils/Colors'), + ScaleLog = require('../utils/ScaleLog'), config = require('../config'); var Header = React.createClass({ @@ -8,14 +10,16 @@ var Header = React.createClass({ propTypes: { columns: React.PropTypes.number.isRequired, logos: React.PropTypes.array.isRequired, - onClickChangeColumns: React.PropTypes.func.isRequired + onClickChangeColumns: React.PropTypes.func.isRequired, + onClickTag: React.PropTypes.func.isRequired }, componentWillMount () { - let tags = {}, - sizer = { + let tags = {}, + fScale = { min: 1, - max: 0 + max: 0, + unit: 'rem' }; if (config.features.tags) { @@ -28,25 +32,26 @@ var Header = React.createClass({ }); }); - tags = this._sortObject(tags); - + tags = this._sortObject(tags, 'value'); tags.forEach((t) => { - if (t.value < sizer.min) { - sizer.min = t.value; + if (t.value < fScale.min) { + fScale.min = t.value; } - if (t.value > sizer.max) { - sizer.max = t.value; + if (t.value > fScale.max) { + fScale.max = t.value; } }); this.setState({ tags: tags, - scale: new ScaleLog(sizer) + fontScale: new ScaleLog(fScale), + colorScale: new ScaleLog({ minSize: 12, min: fScale.min, maxSize: 70, max: fScale.max }), + color: new Colors('#ffced3') }); } }, - _sortObject (obj) { + _sortObject (obj, attr) { var arr = []; for (var prop in obj) { if (obj.hasOwnProperty(prop)) { @@ -56,12 +61,16 @@ var Header = React.createClass({ }); } } - /*arr.sort(function (a, b) { - return b.value - a.value; - });*/ - arr.sort(function (a, b) { - return a.key.toLowerCase().localeCompare(b.key.toLowerCase()); - }); //use this to sort as strings + if (attr === 'value') { + arr.sort(function (a, b) { + return b.value - a.value; + }); + } + else { + arr.sort(function (a, b) { + return a.key.toLowerCase().localeCompare(b.key.toLowerCase()); + }); //use this to sort as strings + } return arr; }, @@ -69,14 +78,22 @@ var Header = React.createClass({ render () { var props = this.props, state = this.state, - tags; + tags, + style; if (config.features.tags) { tags = (
    {state.tags.map((d, i) => { - return ({d.key + ' (' + d.value + ')'} + style = { + backgroundColor: state.color.hsl2hex({ + h: state.color.hue(), + s: state.color.saturation(), + l: state.color.lightness() - +state.colorScale.value(d.value) + }), + fontSize: state.fontScale.value(d.value) + }; + return ({d.key + ' (' + d.value + ')'} ); })}
    @@ -87,12 +104,15 @@ var Header = React.createClass({
    -

    A collection of svg logos for developers.

    +

    A collection of svg logos for developers

    • Columns + or use your keyboard
    • diff --git a/app/scripts/utils/Colors.js b/app/scripts/utils/Colors.js new file mode 100644 index 0000000..b7270a6 --- /dev/null +++ b/app/scripts/utils/Colors.js @@ -0,0 +1,307 @@ +var _ = require('lodash'); + +/* + Color + ===== + + SassMe - an Arc90 Lab Project + + The MIT License (MIT) + Copyright © 2012 Arc90 | http://arc90.com + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the “Software”), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Authors: + -------- + + Jim Nielsen + Darren Newton + Robert Petro + Matt Quintanilla + Jesse Reiner + + Color algorithms: + ----------------- + RGB/HSL Algorithms adapted from: http://mjijackson.com/2008/02/rgb-to-hsl-and- + rgb-to-hsv-color-model-conversion-algorithms-in-javascript + + Syntactically Awesome Stylesheets: + ---------------------------------- + The overall structure of the SASS conversions is based on the Ruby + SASS project: + https://github.com/nex3/sass/blob/stable/lib/sass/script/color.rb + Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein + */ + +class Colors { + constructor (color) { + this.hex = color.charAt(0) === '#' ? color : '#' + color; + + if (color != null) { + this.rgb = this.hex2rgb(this.hex); + } + + if (this.rgb != null) { + this.hsl = this.rgb2hsl(this.rgb); + } + + return this; + } + + hex2rgb (color) { + if (color.charAt(0) === '#') { + color = color.substr(1); + } + + return { + r: parseInt(color.charAt(0) + '' + color.charAt(1), 16), + g: parseInt(color.charAt(2) + '' + color.charAt(3), 16), + b: parseInt(color.charAt(4) + '' + color.charAt(5), 16) + }; + } + + rgb2hsl (rgb) { + var b, d, g, h, hsl, l, max, min, r, s, _ref; + _ref = [rgb.r, rgb.g, rgb.b]; + r = _ref[0]; + g = _ref[1]; + b = _ref[2]; + + r /= 255; + g /= 255; + b /= 255; + max = Math.max(r, g, b); + min = Math.min(r, g, b); + d = max - min; + h = (function () { + switch (max) { + case min: + return 0; + case r: + return 60 * (g - b) / d; + case g: + return 60 * (b - r) / d + 120; + case b: + return 60 * (r - g) / d + 240; + } + }()); + if (h < 0) { + h = 360 + h; + } + l = (max + min) / 2.0; + s = max === min ? 0 : l < 0.5 ? d / (2 * l) : d / (2 - 2 * l); + return { + h: Math.abs(+((h % 360).toFixed(5))), + s: +((s * 100).toFixed(5)), + l: +((l * 100).toFixed(5)) + }; + } + + rgb2hex (rgb) { + return '#' + ((1 << 24) + (rgb.r << 16) + (rgb.g << 8) + rgb.b).toString(16).slice(1); + } + + hue2rgb (p, q, t) { + if (t < 0) { + t += 1; + } + if (t > 1) { + t -= 1; + } + if (t < 1 / 6) { + return p + (q - p) * 6 * t; + } + if (t < 1 / 2) { + return q; + } + if (t < 2 / 3) { + return p + (q - p) * (2 / 3 - t) * 6; + } + return p; + } + + hsl2rgb (hsl) { + var b, g, h, l, p, q, r, s, _ref; + _ref = [parseFloat(hsl.h).toFixed(5) / 360, + parseFloat(hsl.s).toFixed(5) / 100, + parseFloat(hsl.l).toFixed(5) / 100]; + h = _ref[0]; + s = _ref[1]; + l = _ref[2]; + + if (s === 0) { + r = g = b = l; + } + else { + q = l < 0.5 ? l * (1 + s) : l + s - l * s; + p = 2 * l - q; + r = this.hue2rgb(p, q, h + 1 / 3); + g = this.hue2rgb(p, q, h); + b = this.hue2rgb(p, q, h - 1 / 3); + } + return { + r: Math.round(r * 255), + g: Math.round(g * 255), + b: Math.round(b * 255) + }; + } + + hsl2hex (hsl) { + return this.rgb2hex(this.hsl2rgb(hsl)); + } + + mod (attr) { + var hsl, out, rgb, type; + if ((_.intersection(_.keys(attr), ['h', 's', 'l']).length > 0) && + (_.intersection(_.keys(attr), ['r', 'g', 'b']).length > 0)) { + return null; + } + if (_.intersection(_.keys(attr), ['r', 'g', 'b']).length > 0) { + type = 'rgb'; + } + else if (_.intersection(_.keys(attr), ['h', 's', 'l']).length > 0) { + type = 'hsl'; + } + else { + return null; + } + _.each(attr, function (val, key, list) { + if (val === null) { + return delete list[key]; + } + }); + switch (type) { + case 'rgb': + rgb = _.pick(attr, 'r', 'g', 'b'); + if (_.isEmpty(rgb) === false) { + out = _.extend(_.clone(this.rgb), rgb); + } + else { + out = this.rgb; + } + break; + case 'hsl': + hsl = _.pick(attr, 'h', 's', 'l'); + if (_.isEmpty(hsl) === false) { + out = _.extend(_.clone(this.hsl), hsl); + } + else { + out = this.hsl; + } + } + return out; + } + + static constrain (attr, amount, limit, direction) { + var math, test, val; + math = [attr, direction, amount].join(' '); + val = eval(math); + test = (limit[1] >= val && val >= limit[0]); + if (test) { + val; + + } + else { + if (val < limit[0]) { + val = limit[0]; + } + if (val > limit[1]) { + val = limit[1]; + } + } + return Math.abs(val); + } + + static constrain_degrees (attr, amount) { + var val; + val = attr + amount; + if (val > 360) { + val -= 360; + } + if (val < 0) { + val += 360; + } + return Math.abs(val); + } + + red () { + return this.rgb.r; + } + + green () { + return this.rgb.g; + } + + blue () { + return this.rgb.b; + } + + hue () { + return +this.hsl.h; + } + + saturation () { + return +this.hsl.s; + } + + lightness () { + return +this.hsl.l; + } + + lighten (percentage) { + var hsl; + hsl = this.mod({ + l: this.constructor.constrain(this.lightness(), percentage, [0, 100], '+') + }); + return this.rgb2hex(this.hsl2rgb(hsl)); + } + + darken (percentage) { + var hsl; + hsl = this.mod({ + l: this.constructor.constrain(this.lightness(), percentage, [0, 100], '-') + }); + return this.rgb2hex(this.hsl2rgb(hsl)); + } + + saturate (percentage) { + var hsl; + hsl = this.mod({ + s: this.constructor.constrain(this.saturation(), percentage, [0, 100], '+') + }); + return this.rgb2hex(this.hsl2rgb(hsl)); + } + + desaturate (percentage) { + var hsl; + hsl = this.mod({ + s: this.constructor.constrain(this.saturation(), percentage, [0, 100], '-') + }); + return this.rgb2hex(this.hsl2rgb(hsl)); + } + + adjust_hue (degrees) { + var hsl = this.mod({ + h: this.constructor.constrain_degrees(this.hue(), degrees) + }); + + return this.rgb2hex(this.hsl2rgb(hsl)); + } +} + +module.exports = Colors; diff --git a/app/scripts/utils/ScaleLog.js b/app/scripts/utils/ScaleLog.js new file mode 100644 index 0000000..b3a9ed3 --- /dev/null +++ b/app/scripts/utils/ScaleLog.js @@ -0,0 +1,21 @@ +class ScaleLog { + constructor (options) { + options = options || {}; + this.minSize = options.minSize || 1.2; + this.maxSize = options.maxSize || 5; + this.unit = options.unit || ''; + this.min = (options.min || 1); + this.max = (options.max || 50); + + this.scale = (this.max - this.min) / (this.maxSize - this.minSize); + } + + value (qty) { + return (qty === this.min ? this.minSize : (qty / this.max) * (this.maxSize - this.minSize) + this.minSize).toFixed(2) + this.unit; + //Math.exp((position - this.minSize) * this.scale + this.min); + } +} + +// Usage: new LogSlider({ min: 10, max: 100 }); + +module.exports = ScaleLog; diff --git a/app/scripts/utils/scaleLog.js b/app/scripts/utils/scaleLog.js deleted file mode 100644 index ed1a49e..0000000 --- a/app/scripts/utils/scaleLog.js +++ /dev/null @@ -1,21 +0,0 @@ -class ScaleLog { - constructor (options) { - options = options || {}; - this.fontMin = options.fontMin || 1.2; - this.fontMax = options.fontMax || 5; - this.unit = options.unit || 'rem'; - this.min = (options.min || 1); - this.max = (options.max || 50); - - this.scale = (this.max - this.min) / (this.fontMax - this.fontMin); - } - - value (qty) { - return (qty === this.min ? this.fontMin : (qty / this.max) * (this.fontMax - this.fontMin) + this.fontMin).toFixed(2) + this.unit; - //Math.exp((position - this.fontMin) * this.scale + this.min); - } -} - -// Usage: new LogSlider({ min: 10, max: 100 }); - -module.exports = ScaleLog; diff --git a/app/styles/components/_header.scss b/app/styles/components/_header.scss index f800122..cc384d8 100644 --- a/app/styles/components/_header.scss +++ b/app/styles/components/_header.scss @@ -100,6 +100,7 @@ header { display: flex; flex-flow: wrap; justify-content: space-around; + margin-top: 2rem; a { background-color: $link-color; diff --git a/package.json b/package.json index d728440..46050c6 100644 --- a/package.json +++ b/package.json @@ -13,25 +13,25 @@ }, "devDependencies": { "babelify": "^6.1", - "browser-sync": "^2.7", - "browserify": "^10.2", + "browser-sync": "^2.8", + "browserify": "^11.0", "connect": "^3.4", "connect-history-api-fallback": "^1.1", "del": "^1.2", - "eslint": "^0.23", - "eslint-plugin-react": "^2.5", + "eslint": "^0.24", + "eslint-plugin-react": "^2.7", "gulp": "^3.9", "gulp-autoprefixer": "^2.3", "gulp-cache": "^0.2", "gulp-changed": "^1.2", "gulp-compile-handlebars": "^0.5", "gulp-cssmin": "^0.1", - "gulp-eslint": "^0.14", + "gulp-eslint": "^0.15", "gulp-filter": "^2.0", - "gulp-flatten": "0.0.4", + "gulp-flatten": "^0.1", "gulp-gh-pages": "^0.5", "gulp-if": "^1.2", - "gulp-imagemin": "^2.2", + "gulp-imagemin": "^2.3", "gulp-load-plugins": "^0.10", "gulp-plumber": "^1.0", "gulp-rename": "^1.2", @@ -41,11 +41,12 @@ "gulp-uglify": "^1.2", "gulp-useref": "^1.2", "gulp-util": "^3.0", + "lodash": "^3.10.0", "merge-stream": "^0.1", "run-sequence": "^1.1", "vinyl-buffer": "^1.0", "vinyl-source-stream": "^1.1", - "watchify": "^3.2" + "watchify": "^3.3" }, "engines": { "node": ">=0.10.0"