diff --git a/css/style.css b/css/style.css index 7471852..79402d8 100644 --- a/css/style.css +++ b/css/style.css @@ -1 +1,144 @@ -.drag{-webkit-transition:-webkit-transform 0s linear,opacity 0s linear!important}html,body{margin:0;padding:0;height:100%;font-family:Helvetica,Arial,sans-serif;font-size:19px;font-weight:bold;color:#fff}#fork-ribbon{display:none}#wrapper{position:absolute;width:100%;height:100%;top:0;left:0;background:#000;overflow:hidden}#list-view{z-index:1}.list{-webkit-transform:translate3d(0,0,0);-webkit-transition:opacity .3s cubic-bezier(0.64,0.16,0.39,0.83);position:absolute;width:100%;top:0;left:0;z-index:0}.list.fade{opacity:0}.item{text-shadow:0 1px 1px rgba(0,0,0,0.25);-webkit-transition:-webkit-transform .3s cubic-bezier(0.64,0.16,0.39,0.83),background-color .3s cubic-bezier(0.64,0.16,0.39,0.83),opacity .3s cubic-bezier(0.64,0.16,0.39,0.83);position:absolute;width:100%;top:0;left:0;height:64px}.item .inner{cursor:pointer;position:relative;-webkit-transform:translate3d(0,0,0);height:64px;line-height:64px;box-sizing:border-box;padding-left:12px;border-top:1px solid rgba(255,255,255,0.07);border-bottom:1px solid rgba(0,0,0,0.1)}.list-item{background-color:#0086f3}.list-item .count{position:absolute;width:64px;height:63px;right:0;top:-1px;background-color:rgba(255,255,255,0.15);text-align:center}.list-item.empty{color:rgba(255,255,255,0.5);text-shadow:0 1px 1px rgba(0,0,0,0.13)}body.desktop{background:url(../img/bg.png) center center no-repeat}body.desktop *{-webkit-user-select:none}body.desktop img{-webkit-user-drag:none}body.desktop #wrapper{width:320px;height:548px;top:50%;left:50%;margin-top:-259px;margin-left:-160px}body.desktop #fork-ribbon{display:inline}#log{position:absolute;bottom:5px;width:100%;left:0;text-align:center;font-size:14px} \ No newline at end of file +.drag { + -webkit-transition: -webkit-transform 0s linear, opacity 0s linear !important; +} +html, +body { + margin: 0; + padding: 0; + height: 100%; + font-family: Helvetica, Arial, sans-serif; + font-size: 19px; + font-weight: bold; + color: #fff; +} +#fork-ribbon { + display: none; +} +#wrapper { + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + background: #000; + overflow: hidden; +} +#list-view { + z-index: 1; +} +.list { + -webkit-transform: translate3d(0, 0, 0); + -webkit-transition: opacity 0.3s cubic-bezier(0.64, 0.16, 0.39, 0.83); + position: absolute; + width: 100%; + top: 0; + left: 0; + z-index: 0; +} +.list.fade { + opacity: 0; +} +.item { + text-shadow: 0 1px 1px rgba(0, 0, 0, 0.25); + -webkit-transition: -webkit-transform 0.3s cubic-bezier(0.64, 0.16, 0.39, 0.83), opacity 0.3s cubic-bezier(0.64, 0.16, 0.39, 0.83); + position: absolute; + z-index: 0; + width: 100%; + top: 0; + left: 0; + height: 64px; +} +.item .slider { + -webkit-transition: background-color 0.15s cubic-bezier(0.64, 0.16, 0.39, 0.83), color 0.15s cubic-bezier(0.64, 0.16, 0.39, 0.83); + cursor: pointer; + position: relative; + z-index: 1; + height: 64px; +} +.item .slider .inner { + -webkit-transform: translate3d(0, 0, 0); + box-sizing: border-box; + padding-left: 12px; + border-top: 1px solid rgba(255, 255, 255, 0.07); + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + height: 64px; + line-height: 64px; +} +.item .check, +.item .cross { + width: 64px; + height: 64px; + position: absolute; + z-index: 0; + top: 0; + opacity: 0; +} +.item .check { + left: 0; +} +.item .cross { + right: 0; +} +.list-item .count { + position: absolute; + width: 64px; + height: 63px; + right: 0; + top: -1px; + background-color: rgba(255, 255, 255, 0.15); + text-align: center; +} +.list-item.empty { + color: rgba(255, 255, 255, 0.5); + text-shadow: 0 1px 1px rgba(0, 0, 0, 0.13); +} +.todo-item .line { + position: absolute; + height: 2px; + left: 10px; + top: 31px; + width: 0; + background-color: #fff; + -webkit-transition: width 0s linear, background-color 0.15s cubic-bezier(0.64, 0.16, 0.39, 0.83); +} +.todo-item.done { + z-index: 1; + color: #666; +} +.todo-item.done .slider { + background-color: #000 !important; +} +.todo-item.done .line { + background-color: #666; +} +.todo-item.green .slider { + background-color: #0A3 !important; +} +body.desktop { + background: url(../img/bg.png) center center no-repeat; +} +body.desktop * { + -webkit-user-select: none; +} +body.desktop img { + -webkit-user-drag: none; +} +body.desktop #wrapper { + width: 320px; + height: 548px; + top: 50%; + left: 50%; + margin-top: -259px; + margin-left: -160px; +} +body.desktop #fork-ribbon { + display: inline; +} +#log { + position: absolute; + bottom: 5px; + width: 100%; + left: 0; + text-align: center; + font-size: 14px; +} diff --git a/css/style.less b/css/style.less index 50a574a..04bc9d0 100644 --- a/css/style.less +++ b/css/style.less @@ -50,28 +50,52 @@ html, body { .item { text-shadow: 0 1px 1px rgba(0,0,0,.25); -webkit-transition: -webkit-transform .3s @ease, - background-color .3s @ease, opacity .3s @ease; position: absolute; + z-index: 0; width: 100%; top: 0; left: 0; height: @itemHeight; - .inner { + + .slider { + -webkit-transition: background-color .15s @ease, + color .15s @ease; cursor: pointer; position: relative; - -webkit-transform: translate3d(0,0,0); + z-index: 1; height: @itemHeight; - line-height: @itemHeight; - box-sizing: border-box; - padding-left: 12px; - border-top: 1px solid rgba(255,255,255,.07); - border-bottom: 1px solid rgba(0,0,0,.1); + + .inner { + -webkit-transform: translate3d(0,0,0); + box-sizing: border-box; + padding-left: 12px; + border-top: 1px solid rgba(255,255,255,.07); + border-bottom: 1px solid rgba(0,0,0,.1); + height: @itemHeight; + line-height: @itemHeight; + } + } + + .check, .cross { + width: 64px; + height: 64px; + position: absolute; + z-index: 0; + top: 0; + opacity: 0; + } + + .check { + left: 0; + } + + .cross { + right: 0; } } .list-item { - background-color: #0086F3; .count { position: absolute; @@ -89,6 +113,37 @@ html, body { } } +.todo-item { + + .line { + position: absolute; + height: 2px; + left: 10px; + top: 31px; + width: 0; + background-color: #fff; + -webkit-transition: width 0s linear, + background-color .15s @ease; + } + + &.done { + z-index: 1; + color: #666; + .slider { + background-color: #000 !important; + } + .line { + background-color: #666; + } + } + + &.green { + .slider { + background-color: #0A3 !important; + } + } +} + // Desktop body.desktop { diff --git a/img/check.png b/img/check.png new file mode 100755 index 0000000..631ce58 Binary files /dev/null and b/img/check.png differ diff --git a/img/cross.png b/img/cross.png new file mode 100755 index 0000000..a8c96a2 Binary files /dev/null and b/img/cross.png differ diff --git a/js/item.js b/js/item.js index 533925a..00713ed 100644 --- a/js/item.js +++ b/js/item.js @@ -13,36 +13,118 @@ C.Item = (function () { this.render(); + this.style = this.el[0].style; + this.slider = this.el.find('.slider'); + this.sliderStyle = this.slider[0].style; + + this.check = $(''); + this.cross = $(''); + this.el + .append(this.check) + .append(this.cross); + + this.checkStyle = this.check[0].style; + this.crossStyle = this.cross[0].style; + + this.checkX = 0; + this.crossX = 0; + this.checkO = 0; + this.crossO = 0; + + }, + + updatePosition: function () { + + this.y = this.data.order * 64; + this.style.webkitTransform = 'translate3d(0,' + this.y + 'px, 0)'; + }, onDragStart: function () { - this.el.addClass('drag'); + this.slider.addClass('drag'); + this.checkX = this.crossX = 0; + this.checkStyle.webkitTransform = this.crossStyle.webkitTransform = 'translate3d(0,0,0)'; }, onDragMove: function (dx) { - if (this.noDragRight && this.x + dx > 0) return; - if (this.noDragLeft && this.x + dx < 0) return; + var tx = this.x + dx; + + if (this.noDragRight && tx > 0) return; + if (this.noDragLeft && tx < 0) return; + + if (tx > 0) { // dragging to right + + if (this.noDragRight) return; + if (tx <= rightBound) { + + this.checkO = tx / rightBound; + this.checkStyle.opacity = this.checkO; + + if (this.checkX != 0) { + this.checkX = 0; + this.checkStyle.webkitTransform = 'translate3d(0, 0, 0)'; + } + + } else { // over bound + + dx /= 3; + this.checkX = Math.max(0, (this.x + dx) - rightBound); + this.checkStyle.webkitTransform = 'translate3d(' + this.checkX + 'px, 0, 0)'; + + if (this.checkO != 1) { + this.checkO = 1; + this.checkStyle.opacity = 1; + } + + } + + } else if (tx < 0) { // dragging to left + + if (this.noDragLeft) return; + if (tx >= leftBound) { + + this.crossO = tx / leftBound; + this.crossStyle.opacity = this.crossO; + + if (this.crossX != 0) { + this.crossX = 0; + this.crossStyle.webkitTransform = 'translate3d(0, 0, 0)'; + } + + } else { // over bound + + dx /= 3; + this.crossX = Math.min(0, (this.x + dx) - leftBound); + this.crossStyle.webkitTransform = 'translate3d(' + this.crossX + 'px, 0, 0)'; + + if (this.crossO != 1) { + this.crossO = 1; + this.crossStyle.opacity = 1; + } + + } - if (this.x + dx < leftBound || this.x + dx > rightBound) { - dx /= 3; } this.x += dx; - this.style.webkitTransform = 'translate3d(' + this.x + 'px,' + this.y + 'px, 0)'; + this.sliderStyle.webkitTransform = 'translate3d(' + this.x + 'px, 0, 0)'; }, onDragEnd: function () { - var item = this; + var item = this, + complete; if (item.x < leftBound) { - this.del(); + complete = this.del; } else if (item.x > rightBound) { - this.done(); + complete = this.done; + } else { + complete = this.cancel; } loop(); @@ -50,19 +132,24 @@ C.Item = (function () { function loop () { item.x *= .6; - item.style.webkitTransform = 'translate3d(' + item.x + 'px,' + item.y + 'px, 0)'; + item.sliderStyle.webkitTransform = 'translate3d(' + item.x + 'px, 0, 0)'; if (Math.abs(item.x) > 0.1) { setTimeout(loop, 16); } else { item.x = 0; - item.style.webkitTransform = 'translate3d(' + item.x + 'px,' + item.y + 'px, 0)'; - item.el.removeClass('drag'); + item.sliderStyle.webkitTransform = 'translate3d(' + item.x + 'px, 0, 0)'; + item.slider.removeClass('drag'); + + complete.call(item); + } } - } + }, + + }; diff --git a/js/listItem.js b/js/listItem.js index 1cf79b6..9a44832 100644 --- a/js/listItem.js +++ b/js/listItem.js @@ -35,20 +35,18 @@ this.el = $('
' - + '
' - + this.data.title - + '
' + this.data.todos.length + '
' + + '
' + + '
' + + this.data.title + + '
' + this.data.todos.length + '
' + + '
' + '
' + '
'); - this.style = this.el[0].style; - }, updatePosition: function () { - - this.style.webkitTransform = 'translate3d(0,' + this.y + 'px, 0)'; - + C.Item.updatePosition.apply(this, arguments); }, updateColor: function () { @@ -65,7 +63,7 @@ sL = spanL / n; } - this.style.backgroundColor = 'hsl(' + this.sliderStyle.backgroundColor = 'hsl(' + (baseH + o * sH) + ',' + Math.min(100, (baseS + o * sS)) + '%,' + Math.min(100, (baseL + o * sL)) + '%)'; @@ -100,6 +98,10 @@ done: function () { console.log("done"); + }, + + cancel: function () { + } }; diff --git a/js/listView.js b/js/listView.js index fcad4d2..7e5a3fb 100644 --- a/js/listView.js +++ b/js/listView.js @@ -41,6 +41,19 @@ C.listView = { }, + fade: function (at) { + //TODO implement this + var t = this; + t.el.addClass('fade'); + setTimeout(function () { + t.el.css('display', 'none'); + }, 300); + }, + + countIncomplete: function () { + return C.View.countIncomplete.apply(this, arguments); + }, + updateBounds: function () { C.View.updateBounds.apply(this, arguments); }, @@ -63,15 +76,6 @@ C.listView = { onDragEnd: function () { C.View.onDragEnd.apply(this, arguments); - }, - - fade: function (at) { - //TODO implement this - var t = this; - t.el.addClass('fade'); - setTimeout(function () { - t.el.css('display', 'none'); - }, 300); } }; \ No newline at end of file diff --git a/js/todoItem.js b/js/todoItem.js index b7ef041..5b3ea88 100644 --- a/js/todoItem.js +++ b/js/todoItem.js @@ -12,6 +12,8 @@ spanH = stepH * maxColorSpan, spanL = stepL * maxColorSpan; + var leftBound = -64, + rightBound = 64; C.TodoItem = function (data) { C.Item.init.apply(this, arguments); @@ -22,20 +24,21 @@ render: function () { - this.el = $('
' - + '
' - + this.data.title + this.el = $('
' + + '
' + + '
' + + '' + this.data.title + '' + + '
' + + '
' + '
' + '
'); - this.style = this.el[0].style; + this.lineStyle = this.el.find('.line')[0].style; }, updatePosition: function () { - - this.style.webkitTransform = 'translate3d(0,' + this.y + 'px, 0)'; - + C.Item.updatePosition.apply(this, arguments); }, updateColor: function () { @@ -50,7 +53,7 @@ sL = spanL / n; } - this.style.backgroundColor = 'hsl(' + this.sliderStyle.backgroundColor = 'hsl(' + (baseH + o * sH) + ',' + (o ? (baseS - 10) : baseS) + '%,' + (baseL + o * sL) + '%)'; @@ -63,14 +66,36 @@ onDragStart: function () { C.Item.onDragStart.apply(this); + this.contentWidth = this.el.find('.title').width() + 7; }, onDragMove: function (dx) { + + this.lineStyle.width = Math.min(this.contentWidth, Math.max(0, ~~(this.x / 64 * this.contentWidth))) + 'px'; + if (this.x >= rightBound) { + if (!this.green) { + this.green = true; + this.el.addClass('green'); + } + } else { + if (this.green) { + this.green = false; + this.el.removeClass('green'); + } + } + C.Item.onDragMove.apply(this, arguments); + }, onDragEnd: function () { + + if (this.x < rightBound) { + this.lineStyle.width = 0; + } + C.Item.onDragEnd.apply(this); + }, del: function () { @@ -78,7 +103,21 @@ }, done: function () { - console.log("done"); + + //TODO: data manipulation + + this.data.done = true; + + this.el + .removeClass('green') + .addClass('done'); + + this.list.onDone(this); + + }, + + cancel: function () { + } }; diff --git a/js/todoView.js b/js/todoView.js index 5ca25e7..cfd8ae9 100644 --- a/js/todoView.js +++ b/js/todoView.js @@ -60,6 +60,33 @@ C.TodoView.prototype = { }, + onDone: function (doneTodo) { + + var todos = this.items, + i = todos.length, + incomplete = this.countIncomplete(), + doneOrder = doneTodo.data.order, + todo; + + while (i--) { + todo = todos[i]; + if (todo === doneTodo) { + todo.data.order = incomplete; + } else if (todo.data.order > doneOrder && !todo.data.done) { + todo.data.order -= 1; + } else { + continue; + } + todo.updateColor(); + todo.updatePosition(); + } + + }, + + countIncomplete: function () { + return C.View.countIncomplete.apply(this, arguments); + }, + updateBounds: function () { C.View.updateBounds.apply(this, arguments); }, diff --git a/js/view.js b/js/view.js index c51368f..21bd490 100644 --- a/js/view.js +++ b/js/view.js @@ -10,25 +10,34 @@ C.View = (function () { updateColor: function () { - var i = this.items.length, - item; + var i = this.items.length; while (i--) { - item = this.items[i]; - item.updateColor(); + this.items[i].updateColor(); } }, updatePosition: function () { + var i = this.items.length; + + while (i--) { + this.items[i].updatePosition(); + } + + }, + + countIncomplete: function () { + var i = this.items.length, - item; + count = 0; while (i--) { - item = this.items[i]; - item.updatePosition(); + if (!this.items[i].data.done) count++; } + + return count; },