Skip to content

Instantly share code, notes, and snippets.

@jsmayo
Created January 24, 2018 07:16
Show Gist options
  • Save jsmayo/cbbb442b2a2b643245d0012b481ce4b0 to your computer and use it in GitHub Desktop.
Save jsmayo/cbbb442b2a2b643245d0012b481ce4b0 to your computer and use it in GitHub Desktop.
HTML5 Tags
<div class="wrapper">
<div class="menu-wrapper">
<ul id="jsi-category-container" class="menu">
<li><a href="0" class="selected">all</a></li>
<li><a href="1">metadata content</a></li>
<li><a href="2">flow content</a></li>
<li><a href="3">sectioning content</a></li>
<li><a href="4">heading content</a></li>
<li><a href="5">phrasing content</a></li>
<li><a href="6">embedded content</a></li>
<li><a href="7">interactive content</a></li>
<li><a href="8">palpable content</a></li>
<li><a href="9">sectioning root</a></li>
<li><a href="10">form-associated elements</a></li>
<li><a href="11">listed elements</a></li>
<li><a href="12">submittable elements</a></li>
<li><a href="13">resettable elements</a></li>
<li><a href="14">labelable elements</a></li>
<li><a href="15">reassociateable elements</a></li>
</ul>
</div>
<div id="jsi-elements-container" class="container"></div>
</div>
var RENDERER = {
PADDING : 0.1,
init : function(elementData){
this.setParameters();
this.reconstructMethods();
this.adjustContainer();
this.createElements(elementData);
this.bindEvent();
this.render();
},
setParameters : function(){
this.$window = $(window);
this.$container = $('#jsi-elements-container');
this.$categoryContainer = $('#jsi-category-container');
this.$categoryWrapper = this.$categoryContainer.parent();
this.$categories = this.$categoryContainer.find('a');
this.width = this.$container.width();
this.height = this.$container.height();
this.$canvas = $('<canvas />');
this.context = this.$canvas.attr({width : this.width, height : this.height}).appendTo(this.$container).get(0).getContext('2d');
this.selectedIndex = this.$categories.filter('.selected').attr('href');
this.animationCount = 0;
this.elements = [];
var distance = Math.sqrt(Math.pow(this.width, 2) + Math.pow(this.height, 2));
this.gradient = this.context.createRadialGradient(this.width / 2, this.height / 2, 0, this.width / 2, this.height / 2, distance);
this.gradient.addColorStop(0, 'hsl(220, 80%, 50%)');
this.gradient.addColorStop(1, 'hsl(220, 80%, 10%)');
},
adjustContainer : function(){
this.width = this.$container.width();
this.height = this.$container.height();
this.elementWidth = this.width * (1 - this.PADDING * 2) / 8;
this.elementWidth += this.elementWidth / 8;
this.elementHeight = this.elementWidth / 4;
this.font = '400 ' + 20 * this.width / 1200 + 'px "HG正楷書体-PRO"';
this.$canvas.attr({width : this.width, height : this.height});
this.$categoryWrapper.css('overflow-y', (this.$categoryContainer.height() > this.$categoryWrapper.height() ? 'scroll' : 'hidden'));
for(var i = 0, length = this.elements.length; i < length; i++){
this.elements[i].init();
}
},
createElements : function(elementData){
for(var i = 0, length = elementData.length; i < length; i++){
this.elements.push(new ELEMENT(this, elementData[i], i, this.selectedIndex));
}
},
reconstructMethods : function(){
this.render = this.render.bind(this);
},
bindEvent : function(){
var myself = this;
this.$categories.each(function(){
var $self = $(this);
$self.on('click', myself.selectCategory.bind(myself, $self.attr('href')));
});
this.$window.on('resize', this.adjustContainer.bind(this));
},
selectCategory : function(index, event){
event.preventDefault();
if(this.selectedIndex == index){
return;
}
this.$categories.removeClass('selected').eq(index).addClass('selected');
this.selectedIndex = index;
for(var i = 0, length = this.elements.length; i < length; i++){
this.elements[i].transform(this.selectedIndex);
}
},
render : function(){
requestAnimationFrame(this.render);
this.context.fillStyle = this.gradient;
this.context.fillRect(0, 0, this.width, this.height);
this.elements.sort(function(element1, element2){
return element2.z - element1.z;
});
this.context.font = this.font;
this.context.textAlign = 'center';
this.context.textBaseline = 'middle';
for(var i = 0, length = this.elements.length; i < length; i++){
this.elements[i].render(this.context);
}
}
};
var ELEMENT = function(renderer, data, index, selectedIndex){
this.renderer = renderer;
this.data = data;
this.index = index;
this.selected = this.setSelected(selectedIndex);
this.init();
};
ELEMENT.prototype = {
FOCUS_POSITION : 300,
FAR_LIMIT : 600,
ANIMATION_COUNT : 30,
init : function(){
this.x = this.renderer.width * this.renderer.PADDING + this.renderer.elementWidth / 2 + (this.index % 8) * this.renderer.elementWidth * 7 / 8 - this.renderer.width / 2;
this.y = -this.renderer.elementHeight / 2 - Math.floor(this.index / 8) * this.renderer.elementHeight - ((this.index % 8 % 2 == 0) ? 0 : this.renderer.elementHeight / 2) - (this.renderer.height - this.renderer.elementHeight * 14.5) / 2 + this.renderer.height / 2;
this.z = this.z0 = this.selected ? 0 : this.FAR_LIMIT;
this.animationCount = -1;
},
setSelected : function(selectedIndex){
if(selectedIndex == 0){
return true;
}
for(var i = 0, length = this.data.categories.length; i < length; i++){
if(this.data.categories[i] == selectedIndex){
return true;
}
}
return false;
},
getRandomValue : function(min, max){
return min + (max - min) * Math.random();
},
transform : function(selectedIndex){
var selected = this.setSelected(selectedIndex);
if(this.selected == selected){
return;
}
this.selected = selected;
this.animationCount = this.ANIMATION_COUNT;
this.z0 = this.z;
},
ease : function(t){
return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
},
render : function(context){
if(this.animationCount >= 0){
var tick = this.ease((this.ANIMATION_COUNT - this.animationCount) / this.ANIMATION_COUNT);
if(this.selected){
this.z = this.z0 * (1 - tick);
}else{
this.z = this.z0 + (this.FAR_LIMIT - this.z0) * tick;
}
this.animationCount--;
}
var rate = this.FOCUS_POSITION / (this.z + this.FOCUS_POSITION),
width = this.renderer.elementWidth,
height = this.renderer.elementHeight,
x = this.renderer.width / 2 + this.x * rate,
y = this.renderer.height / 2 - this.y * rate,
gradient = context.createLinearGradient(-this.renderer.elementWidth * 5 / 8, 0, this.renderer.elementWidth * 5 / 8, 0),
saturation = 70 * rate;
gradient.addColorStop(0, 'hsla(180, ' + saturation +'%, 30%, 0.9)');
gradient.addColorStop(0.3, 'hsla(180, ' + saturation +'%, 40%, 0.9)');
gradient.addColorStop(0.5, 'hsla(180, ' + saturation +'%, 45%, 0.9)');
gradient.addColorStop(0.7, 'hsla(180, ' + saturation +'%, 40%, 0.9)');
gradient.addColorStop(1, 'hsla(180, ' + saturation +'%, 30%, 0.9)');
context.save();
context.translate(x, y);
context.scale(rate, rate);
context.strokeStyle = 'hsl(180, 60%, 60%)';
context.fillStyle = gradient;
context.beginPath();
context.moveTo(-width / 2, 0);
context.lineTo(-width * 3 / 8, -height / 2);
context.lineTo(width * 3 / 8, -height / 2);
context.lineTo(width / 2, 0);
context.lineTo(width * 3 / 8, height / 2);
context.lineTo(-width * 3 / 8, height / 2);
context.closePath();
context.fill();
context.stroke();
context.fillStyle = 'hsl(210, 90%, 90%)';
context.fillText(this.data.name, 0, 0);
context.restore();
}
};
var ELEMENT_DATA = [
{name : 'a', categories : [2, 5, 7, 8]},
{name : 'abbr', categories : [2, 5, 8]},
{name : 'address', categories : [2, 8]},
{name : 'area', categories : [2, 5]},
{name : 'article', categories : [2, 3, 8]},
{name : 'aside', categories : [2, 3, 8]},
{name : 'audio', categories : [2, 5, 6, 7]},
{name : 'b', categories : [2, 5, 8]},
{name : 'base', categories : [1]},
{name : 'bdi', categories : [2, 5, 8]},
{name : 'bdo', categories : [2, 5, 8]},
{name : 'blockquote', categories : [2, 8, 9]},
{name : 'body', categories : [9]},
{name : 'br', categories : [2, 5]},
{name : 'button', categories : [2, 5, 7, 8, 10, 11, 12, 14, 15]},
{name : 'canvas', categories : [2, 5, 6, 8]},
{name : 'caption', categories : []},
{name : 'cite', categories : [2, 5, 8]},
{name : 'code', categories : [2, 5, 8]},
{name : 'col', categories : []},
{name : 'colgroup', categories : []},
{name : 'data', categories : [2, 5, 8]},
{name : 'datalist', categories : [2, 5]},
{name : 'dd', categories : []},
{name : 'del', categories : [2, 5]},
{name : 'details', categories : [2, 7, 8, 9]},
{name : 'dfn', categories : [2, 5, 8]},
{name : 'dialog', categories : [2, 9]},
{name : 'div', categories : [2, 8]},
{name : 'dl', categories : [2]},
{name : 'dt', categories : []},
{name : 'em', categories : [2, 5, 8]},
{name : 'embed', categories : [2, 5, 6, 7, 8]},
{name : 'fieldset', categories : [2, 8, 9, 10, 11, 15]},
{name : 'figcaption', categories : []},
{name : 'figure', categories : [2, 8, 9]},
{name : 'footer', categories : [2, 8]},
{name : 'form', categories : [2, 8]},
{name : 'h1', categories : [2, 4, 8]},
{name : 'h2', categories : [2, 4, 8]},
{name : 'h3', categories : [2, 4, 8]},
{name : 'h4', categories : [2, 4, 8]},
{name : 'h5', categories : [2, 4, 8]},
{name : 'h6', categories : [2, 4, 8]},
{name : 'head', categories : []},
{name : 'header', categories : [2, 8]},
{name : 'hr', categories : [2]},
{name : 'html', categories : []},
{name : 'i', categories : [2, 5, 8]},
{name : 'iframe', categories : [2, 5, 6, 7, 8]},
{name : 'img', categories : [2, 5, 6, 7, 8, 10]},
{name : 'input', categories : [2, 5, 7, 10, 11, 12, 13, 14, 15]},
{name : 'ins', categories : [2, 5, 8]},
{name : 'kbd', categories : [2, 5, 8]},
{name : 'label', categories : [2, 5, 7, 8, 10, 15]},
{name : 'legend', categories : []},
{name : 'li', categories : []},
{name : 'link', categories : [1, 2, 5]},
{name : 'main', categories : [2, 8]},
{name : 'map', categories : [2, 5, 8]},
{name : 'mark', categories : [2, 5, 8]},
{name : 'meta', categories : [1, 2, 5]},
{name : 'meter', categories : [2, 5, 8, 14]},
{name : 'nav', categories : [2, 3, 8]},
{name : 'noscript', categories : [1, 2, 5]},
{name : 'object', categories : [2, 5, 6, 7, 8, 10, 11, 12, 15]},
{name : 'ol', categories : [2]},
{name : 'optgroup', categories : []},
{name : 'option', categories : []},
{name : 'output', categories : [2, 5, 8, 10, 11, 13, 14, 15]},
{name : 'p', categories : [2, 8]},
{name : 'param', categories : []},
{name : 'picture', categories : [2, 5, 6]},
{name : 'pre', categories : [2, 8]},
{name : 'progress', categories : [2, 5, 8, 14]},
{name : 'q', categories : [2, 5, 8]},
{name : 'rb', categories : []},
{name : 'rp', categories : []},
{name : 'rt', categories : []},
{name : 'rtc', categories : []},
{name : 'ruby', categories : [2, 5, 8]},
{name : 's', categories : [2, 5, 8]},
{name : 'samp', categories : [2, 5, 8]},
{name : 'script', categories : [1, 2, 5]},
{name : 'section', categories : [2, 3, 8]},
{name : 'select', categories : [2, 5, 7, 8, 10, 11, 12, 13, 14, 15]},
{name : 'small', categories : [2, 5, 8]},
{name : 'source', categories : []},
{name : 'span', categories : [2, 5, 8]},
{name : 'strong', categories : [2, 5, 8]},
{name : 'style', categories : [1, 2]},
{name : 'sub', categories : [2, 5, 8]},
{name : 'summary', categories : []},
{name : 'sup', categories : [2, 5, 8]},
{name : 'table', categories : [2, 8]},
{name : 'tbody', categories : []},
{name : 'td', categories : [9]},
{name : 'template', categories : [1, 2, 5]},
{name : 'textarea', categories : [2, 5, 7, 8, 10, 11, 12, 13, 14, 15]},
{name : 'tfoot', categories : []},
{name : 'th', categories : [7]},
{name : 'thead', categories : []},
{name : 'time', categories : [2, 5, 8]},
{name : 'title', categories : [1]},
{name : 'tr', categories : []},
{name : 'track', categories : []},
{name : 'u', categories : [2, 5, 8]},
{name : 'ul', categories : [2]},
{name : 'var', categories : [2, 5, 8]},
{name : 'video', categories : [2, 5, 6, 7, 8]},
{name : 'wbr', categories : [2, 5]}
];
$(function(){
RENDERER.init(ELEMENT_DATA);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
html, body{
width: 100%;
height: 100%;
overflow:hidden;
margin: 0;
padding: 0;
}
.wrapper{
width: 100%;
height: 100%;
background-color: #808080;
}
.wrapper::after{
content: ".";
display: block;
height: 0;
font-size: 0;
clear: both;
visibility: hidden;
}
.menu-wrapper{
box-sizing: border-box;
float: left;
width: 220px;
height: 100%;
overflow-y: hidden;
}
.menu{
box-sizing: border-box;
list-style: none;
width: 100%;
margin: 0;
padding: 10px;
font-family: NotoSansJP,Slack-Lato,appleLogo,sans-serif;
font-size: 12px;
}
.menu > li{
box-sizing: border-box;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
.menu > li+li{
margin-top: 10px;
}
.menu > li > a{
box-sizing: border-box;
display: inline-block;
width: 100%;
height: 100%;
padding: 5px 10px;
text-decoration: none;
background-color: #40AAEF;
color: #FFFFFF;
border-radius: 4px;
box-shadow: 0px 4px 0 rgba(0, 0, 0, 0.7);
transition: 0.2s all ease 0s;
}
.menu > li > a.selected{
background-color: #0E7AC4;
box-shadow: none;
transform: translate3d(0, 3px, 0);
}
.container{
float: left;
width: calc(100% - 220px);
height: 100%;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment