<div id="app">
<svg version="1.1" id="world" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="1000px" height="600px" viewBox="0 0 1000 600" enable-background="new 0 0 1000 600" xml:space="preserve">
<transition name="fade">
<g v-if="activeIndex > 0" v-on:click="prevPalette">
<text class="prevBtn" x="130" y="498" style="font-size: 20px; cursor: pointer;" :fill="prevColor" >Prev</text>
<rect class="prevBtnRect" x="100" y="465" width="100" rx="5" height="50" :stroke="prevColor" fill="none"/>
</g>
</transition>
<transition name="fade">
<g v-if="activeIndex < paletteSize-1" v-on:click="nextPalette">
<text class="nextBtn" x="436" y="498" style="font-size: 20px; cursor: pointer;" :fill="nextColor">Next</text>
<rect class="nextBtnRect" x="410" y="465" width="100" height="50" rx="5" :stroke="nextColor" fill="none"/>
</g>
</transition>
<g v-for="(value, key, index) in items" class="palettes" >
<rect x="300" y="270" height="2" width="170" style="stroke:none; fill:none; "/>
<rect x="360" y="270" height="15" width="100" rx="4" :fill=value.shade_600 :class="activepalette == key ? 'active' : 'inactive'" v-on:click="activeIndex=index" />
</g>
<g class="paletteTitle">
<path fill="none" stroke="none" stroke-miterlimit="10" d="M889.5 222.6c0 104.6-84.8 190.4-189.3 190.4s-189.4-85.8-189.4-190.4c0-104.5 84.8-189.3 189.4-189.3S889.5 118 889.5 222.6z" id="Layer_2"/>
<use xlink:href="#Layer_2"/>
<text style="font-size: 25px; text-transform: uppercase;" :fill=activeColor>
<textPath xlink:href="#Layer_2">
{{ activepalette }} Palette
</textPath>
</text>
</g>
<g class="palette" v-for="code in activeValues">
<text x="530" y="267" v-fillcolor="code" style="text-transform: uppercase;"> {{ code }} </text>
<rect x="530" y="270" width="160" height="15" rx="3" fill="none" />
<rect x="530" y="270" width="100" height="15" rx="3" v-fillcolor="code" />
</g>
<text class="title" x="20" y="50" style="font-size: 20px;" :fill="activeColor"> Material UI Circular Colour Palette Made With
<tspan style="fill:#41B883"> Vue JS </tspan> and
<tspan style="fill:#88CE02"> GSAP </tspan> </text>
</svg>
</div>
body {
background-color: #212121;
text-align: center;
font-family: 'Roboto Condensed', sans-serif;
}
svg {
height: 100vh;
width: 100vw;
}
#world {
width: 100%;
height: 100%;
}
.fade-enter-active, .fade-leave-active {
transition: opacity 1s
}
.fade-enter, .fade-leave-to {
opacity: 0
}
text {
font-size: 18px; text-transform: uppercase;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.active { opacity: 1; transition: opacity 2s; }
.inactive { opacity: 0.5; cursor: pointer; }
.palettes { opacity: 0; }
.palette { opacity: 0; }
.paletteTitle { opacity: 0; }
.nav { cursor: pointer; }
Vue.directive('fillcolor', function(el, binding) {
el.style.fill = binding.value;
el.style.transition = "opacity 1s";
})
new Vue({
el: '#app',
data() {
return {
items: {},
activepalette: "red",
activeColor: "#ef5350", // for red palette
activeIndex: 0,
clickedPalette: "red",
clickedColor: "#E53935",
nextColor: "#D81B60",
prevColor: "#ef5350",
};
},
created() {
this.fetchData();
},
watch: {
items(newValue) {
this.$nextTick(function() {
this.createColorWheel();
this.createSpectrum()
})
},
activeIndex(newValue) {
this.assignColors(newValue);
this.rotateWheel(newValue);
},
activepalette(newValue) {
this.createSpectrum()
},
}, // end of watch
computed: {
activeValues() {
return _.find(this.items, (item, index) => {
return index == this.activepalette
})
},
paletteSize() {
return _.size(this.items)
},
}, // end of computed
methods: {
fetchData() {
var self = this;
var dataURL="https://raw.githubusercontent.com/Krutie/dataRepo/master/palette.json";
$.getJSON(dataURL, function(data) {
self.items = data;
});
}, // end of fetchData()
createColorWheel() {
let degrees = $(".palettes")
let angle = 360/16;
degrees.each(function(index, item) {
TweenMax.to(item, 2, {
rotation: angle*index, opacity: 1, transformOrigin: "0% 100%"
}, 1);
});
}, // end of createColorWheel
createSpectrum() {
let palette = $(".palette")
let paletteTitle = $(".paletteTitle");
let angle = 360/_.size(palette);
_.map(palette, (item, key) => {
TweenMax.to(item, 1, {
rotation: angle*key+50, opacity: 1, transformOrigin: "100% 65%", delay: 0.2,
onComplete: this.createTitleOnAPath
}, 0.1);
}); // end of map
}, // end of createSpectrum()
createTitleOnAPath(){
TweenMax.staggerFromTo($(".paletteTitle"), 0.5,
{ rotation: 0, opacity: 0 },
{ rotation: -45, opacity: 1, transformOrigin: "60% 55%"
}, 0.1); // end of TweenMax
},
// For Interactive Color Wheel
assignColors(newValue){
let k = _.keys(this.items);
this.clickedPalette = k[newValue];
let c = k[newValue];
this.clickedColor = this.items[c].shade_600;
let n = k[newValue+1]
let p = k[newValue-1]
this.fillColor(".title", this.clickedColor);
if (n != undefined ) {
this.fillColor(".nextBtn", this.items[n].shade_600 );
this.strokeColor(".nextBtnRect", this.items[n].shade_600 );
}
if (p != undefined ) {
this.fillColor(".prevBtn", this.items[p].shade_600);
this.strokeColor(".prevBtnRect", this.items[p].shade_600);
}
}, // end of assignColors
fillColor(el, shade) {
TweenMax.staggerTo(el, 1, {
fill:shade
}, 1, 0)
},
strokeColor(el, shade) {
TweenMax.staggerTo(el, 1, {
stroke:shade
}, 1, 0)
},
rotateWheel(clickedKey) {
let degrees = $(".palettes"); let angle = 360/16;
_.map(degrees, (index, key) => {
if(clickedKey == key) {
TweenLite.to(index, 1, {
rotation: 0+'_short', transformOrigin: "0% 100%",delay: 1.5, onStart: this.erasePrevious,
}, 0.1);
} else if (key == 0) {
TweenLite.to(index, 1, {
rotation: (clickedKey*angle)+'_short', transformOrigin: "0% 100%", delay: 1
}, 0.1);
} else {
TweenLite.to(index, 1, {
rotation: key*angle+'_short', transformOrigin: "0% 100%", delay: 0.5
}, 0.1);
}
});
}, // end of rotateWheel
erasePrevious() {
let palette = $(".palette")
let angle = 360/_.size(palette);
let eraseTL = new TimelineMax();
_.map(palette, (index, key) => {
eraseTL.to(index, 1.5, {
rotation: 0, opacity: 0, transformOrigin: "100% 65%", ease: Circ.easeOut
}, 0.1);
});
eraseTL.to($(".paletteTitle"), 1.5, {
rotation: 0, opacity: 0, transformOrigin: "60% 55%", ease: Circ.easeOut, onComplete: this.passNewValues
}, 0.1);
}, // end of erasePrevious
passNewValues() {
this.activepalette = this.clickedPalette;
this.activeColor = this.clickedColor;
},
prevPalette() { this.activeIndex -= 1; },
nextPalette() { this.activeIndex += 1; },
}, // end of methods
})
View Compiled