AdventCalendar
by MKGaru
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-debug.js"></script>
<script src="https://mbest.github.io/knockout.punches/knockout.punches.js"></script>
<script src="https://rawgit.com/SteveSanderson/knockout-es5/master/dist/knockout-es5.js"></script>
<script src="https://rawgit.com/LeaVerou/prefixfree/gh-pages/prefixfree.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/sugar/1.4.1/sugar-full.min.js"></script>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Fredericka+the+Great&.css">
<span>数字をクリックしてね</span>
<h1>Advent Calendar</h1>
<div class="cupboard">
<div class="backpanel"></div>
<table>
<tbody data-bind="template:{foreach: weeks,as:'week'}">
<tr data-bind="foreach:week">
<td>
<div class="cell">
<div class="box {{done?'done':'active'}}">
<div class="front"><span data-bind="on.click:done=true">{{date.format('{d}')}}</span></div>
<div class="back"></div>
<div class="left"></div>
<div class="right" data-bind="style:{'background-position':($index()*20)+'% '+($parentContext.$index()*20)+'%'}"></div>
<div class="bottom"><span>{{note}}</span></div>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
SCSS
*{
user-select:none;
}
h1{
font-family: 'Fredericka the Great', cursive;
margin: 0;
margin-top:1em;
width: 300px;
text-align: center;
color: green;
text-shadow: 2px 2px gray;
}
.cupboard{
position:absolute;
left:10px;
width: 300px;
transform-style: preserve-3d;
perspective: 1500px;
perspective-origin: 50% 0;
transform: rotateX(0deg);
.backpanel{
position:absolute;
height:100%;
width:100%;
left:0;right:0;
top:0;bottom:0;
transform: translateZ(-51px);
background: #664444;
}
.cell{
}
th,td{
border:solid 2px darkslategrey;
}
}
.box{
width: 50px;
height: 50px;
top: 0px;
bottom: 0;
left: 0;
right: 0;
margin: auto;
transform-style: preserve-3d;
transform: translateZ(100px);
transform-origin: 25px 0px -25px;
transition: transform ease-out 500ms;
//animation: rotateY 5s linear infinite;
transform: rotateY(180deg);
&.active{
transform: rotateY(0deg);
//animation: pull-push 5s ease-in infinite;
}
&.done{
animation: pull-push 3s ease-in 1;
transform: rotateY(-90deg);
}
.front,
.back,
.left,
.right,
.bottom{
width: 50px;
height: 50px;
position: absolute;
top: 0px;
bottom: 0;
left: 0;
right: 0;
margin: auto;
text-align: center;
line-height: 50px;
opacity: 0.8;
border: solid 1px brown;
background: url(https://yabumi.cc/15142c3178cd66b98092f9a6.png);
&>span{
display:block;
}
}
.front{
transform: translateZ(0px);
&>span{
background:rgba(red,0.75);
cursor:pointer;
color: white;
font-size:30px;
font-family: 'Fredericka the Great', cursive;
font-weight:bold;
}
}
...
JavaScript
function Day(date){
this.note = '';
this.done = false;
this.date = date;
ko.track(this);
}
function AdventCalendar(){
var calendar = this;
calendar.date = new Date();
calendar.days = Date
.range("12/1","12/25")
.every('date')
.map(function(date){
return new Day(date);
});
calendar.weeks = Number
.range(0,24)
.every(5)
.map(function(day){
return calendar.days.from(day).first(5)
});
calendar.days
.filter(function(day){
return day.date.isBefore(calendar.date)
})
.forEach(function(day){
day.done = true;
});
ko.track(calendar);
}
var calendar = new AdventCalendar();
ko.punches.enableAll();
ko.applyBindings(calendar);