/* global $, Vue, axios, chroma, vm */ /* eslint no-undef: "error", semi: 2 */ /** * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * ······· Copy * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ */ new ClipboardJS('.btn-copy'); /** * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * ······· Functions * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ */ function lightOrDark (color) { // Variables for red, green, blue values var r, g, b, hsp; // Check the format of the color, HEX or RGB? if (color.match(/^rgb/)) { // If RGB --> store the red, green, blue values in separate variables color = color.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+(?:\.\d+)?))?\)$/); r = color[1]; g = color[2]; b = color[3]; } else { // If hex --> Convert it to RGB: http://gist.github.com/983661 color = +('0x' + color.slice(1).replace(color.length < 5 && /./g, '$&$&')); r = color >> 16; g = color >> 8 & 255; b = color & 255; } // HSP (Highly Sensitive Poo) equation from http://alienryderflex.com/hsp.html hsp = Math.sqrt(0.299 * (r * r) + 0.587 * (g * g) + 0.114 * (b * b)); // Using the HSP value, determine whether the color is light or dark if (hsp > 127.5) { return 'light'; } else { return 'dark'; } } /** * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * ······· Color Functions * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ */ function colorDistance (color1, color2) { // This is actually the square of the distance but // this doesn't matter for sorting. var result = 0; for (var i = 0; i < color1.length; i++) result += (color1[i] - color2[i]) * (color1[i] - color2[i]); return result; } function sortColors (colors) { // Calculate distance between each color var distances = []; for (var i = 0; i < colors.length; i++) { distances[i] = []; for (var j = 0; j < i; j++) distances.push([ colors[i], colors[j], colorDistance(colors[i], colors[j]), ]); } distances.sort(function (a, b) { return a[2] - b[2]; }); // Put each color into separate cluster initially var colorToCluster = {}; for (var y = 0; y < colors.length; y++) colorToCluster[colors[y]] = [colors[y]]; // Merge clusters, starting with lowest distances var lastCluster; for (var e = 0; e < distances.length; e++) { var color1 = distances[e][0]; var color2 = distances[e][1]; var cluster1 = colorToCluster[color1]; var cluster2 = colorToCluster[color2]; if (!cluster1 || !cluster2 || cluster1 == cluster2) continue; // Make sure color1 is at the end of its cluster and // color2 at the beginning. if (color1 !== cluster1[cluster1.length - 1]) cluster1.reverse(); if (color2 !== cluster2[0]) cluster2.reverse(); // Merge cluster2 into cluster1 cluster1.push.apply(cluster1, cluster2); delete colorToCluster[color1]; delete colorToCluster[color2]; colorToCluster[cluster1[0]] = cluster1; colorToCluster[cluster1[cluster1.length - 1]] = cluster1; lastCluster = cluster1; } // By now all colors should be in one cluster return lastCluster; } /** * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * ······· Vue App * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ */ var $getUrl = 'https://raw.githubusercontent.com/Gogh-Co/Gogh/master/data/themes.json'; const $app = { data () { return { themes: [], filter: 'all', themeBackgrounds: null, selected: null }; }, created () { axios.get($getUrl).then((response) => { this.themes = response.data.themes; this.themes.forEach((v) => { v.category = lightOrDark(v.background); }); }); }, computed: { allValues () { // var $result = []; // for(var e in this.themes) { // var value = this.themes[e]; // for (var i in value) { // if (value.hasOwnProperty(i)) { // $result.push(value[i]) // } // } // } // $result = $result.filter(s => ~s.indexOf("#")); // $result = $result.map(ele => ele.toLowerCase()); // $result = [...new Set($result)]; // $result = $result.sort(); // return $result; } }, methods: { setFilter (f) { this.filter = ''; setTimeout(() => { this.filter = f; }, 100); }, setBackground () { this.filter = 'background'; }, getBackgrounds () { const $bgs = this.themes.map(e => e.background); const $bgsLowerCase = $bgs.map((ele) => ele.toLowerCase()); const $bgsUnique = [...new Set($bgsLowerCase)]; const $bgsRGB = $bgsUnique.map((ele) => chroma(ele).rgb()); const $bgsSort = sortColors($bgsRGB); const $bgsHEX = $bgsSort.map(ele => chroma(ele).hex()); this.themeBackgrounds = $bgsHEX.reverse(); this.selected = 'background'; this.filter = 'background'; }, resetMenuSelected () { this.selected = ''; } } }; Vue.createApp($app) .mount('#js-vue-app'); /** * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * ······· Menu * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ */ $('.js-btn--filter-bg').on('click', function () { $('.js-filter-background').slideToggle(); }); $('.js-btn--filter').on('click', function () { $('.js-filter-background').slideUp(400); });