Как сделать UI such a desktop?
Добрый день.
Подскажите как сделать интерфейс псевдодескопный? Что бы дивы, при приближении к границе окна автоматически прилеплялись к ней с изменением размеров? Перемещение draggable. Как например окно в винде, при приближении к левой или правой границе экрана автоматически занимает половину экрана. |
Как-то так: http://jsfiddle.net/Octane/WWkkm/ – во фреймах срабатывает, если не больше чем за 20 пикселей от границы отпустить мышь.
<!DOCTYPE html> <html> <head> <meta charser="utf-8"> <title>Windows Snap</title> <style> html, body { height: 100%; } body { margin: 0; } .window { position: fixed; background: #53bdde; outline: 1px solid #1d5e6d; } .window-title { font: 12px/24px sans-serif; color: #373e45; text-align: center; cursor: move; -ms-user-select: none; } .window-content { overflow: scroll; position: absolute; top: 24px; right: 5px; bottom: 5px; left: 5px; background: #efefef; border: 1px solid #569cb6; } </style> </head> <body> <div class="window" style="top:50px; left:50px; width:320px; height:240px;"> <div class="window-title">Snappable Window</div> <div class="window-content"></div> </div> <script> var obj = {}, arr = {}, fn = {}, ui = {}; arr.from = Array.prototype.slice.call.bind(Array.prototype.slice); obj.extend = function (target/*, sources*/) { arr.from(arguments, 1).forEach(function (src) { Object.keys(src).forEach(function (prop) { target[prop] = src[prop]; }); }); return target; }; fn.inherit = function (cns, cls) { cns.prototype = Object.create(cls.prototype); cns.prototype.constructor = cns; return cns; } obj.Observable = new function () { function Observable() { } Observable.prototype = { constructor: Observable, _getObservers: function (eventType) { var observers; if (!("_observers" in this)) { this._observers = {}; } observers = this._observers; if (!(eventType in observers)) { observers[eventType] = []; } observers = observers[eventType]; return observers; }, on: function (eventType, observer) { var observers; if ("addEventListener" in this) { this.addEventListener(eventType, observer, false); } else { observers = this._getObservers(eventType); observers.push(observer); } return this; }, fire: function (eventType) { var observers = this._getObservers(eventType), i = 0, length = observers.length; while (i < length) { observers[i].call(this, {type: eventType}) i++; } return this; } }; return Observable; }; ui.Draggable = new function () { function Draggable() { } obj.extend(fn.inherit(Draggable, obj.Observable).prototype, { container: null, activeElement: null, _x: 0, _y: 0, _offsetX: 0, _offsetY: 0, _dragging: false, _dragTimeout: 0, enableDragging: function () { this._onDragging = this._onDragging.bind(this); this._saveCoords = this._saveCoords.bind(this); this._onDragStop = this._onDragStop.bind(this); this.activeElement.addEventListener("mousedown", this._onDragStart.bind(this), false); }, _onDragStart: function (event) { var rect = this.container.getBoundingClientRect(); this._offsetY = event.pageY - rect.top; this._offsetX = event.pageX - rect.left; this._dragging = true; this._saveCoords(event); document.addEventListener("mousemove", this._saveCoords, false); document.addEventListener("mouseup", this._onDragStop, false); this.fire("drag.beforeStart"); this._onDragging(); this.fire("drag.start"); }, _onDragStop: function () { clearTimeout(this._dragTimeout); this._dragging = false; document.removeEventListener("mousemove", this._saveCoords, false); document.removeEventListener("mouseup", this._onDragStop, false); this.fire("drag.stop"); }, _onDragging: function () { this._move(); if (this._dragging) { this._dragTimeout = setTimeout(this._onDragging, 50); } }, _saveCoords: function (event) { this._x = event.pageX; this._y = event.pageY; }, _move: function () { var style = this.container.style; style.top = this._y - this._offsetY + "px"; style.left = this._x - this._offsetX + "px"; } }); return Draggable; }; ui.Snappable = new function () { function Snappable() { } obj.extend(fn.inherit(Snappable, ui.Draggable).prototype, { container: null, _x: 0, _y: 0, _snapping: false, _snapTimeout: 0, _maxX: 0, _needSnap: false, _snapTo: "", _snapped: false, _width: 0, _height: 0, enableSnapping: function () { this._onSnapping = this._onSnapping.bind(this); this.on("drag.start", this._onSpanStart.bind(this)); this.on("drag.stop", this._onSnapStop.bind(this)); this.on("drag.beforeStart", this._unsnap.bind(this)); }, _onSpanStart: function () { this._maxX = document.documentElement.offsetWidth; this._snapping = true; this._saveBounds(); this._onSnapping(); }, _onSnapStop: function () { clearTimeout(this._snapTimeout); this._snapping = false; if (this._needSnap) { this._needSnap = false; this._snap(); } }, _onSnapping: function () { this._ckeckSnapping(); if (this._snapping) { this._snapTimeout = setTimeout(this._onSnapping, 100); } }, _ckeckSnapping: function () { if ((this._x <= 20) || (this._x >= this._maxX - 20) || (this._y <= 20)) { this._needSnap = true; if (this._x <= 0) { this._snapTo = "left"; } else if (this._x >= this._maxX) { this._snapTo = "right"; } else if (this._y <= 0) { this._snapTo = "top"; } } else { this._needSnap = false; } }, _saveBounds: function () { this._width = this.container.offsetWidth; this._height = this.container.offsetHeight; }, _snap: function () { var style = this.container.style; style.top = 0; style.height = "100%"; if (this._snapTo == "left") { style.left = 0; style.width = "50%"; } else if (this._snapTo == "right") { style.left = "50%"; style.width = "50%"; } else { style.left = 0; style.width = "100%"; } this._snapped = true; }, _unsnap: function () { var style; if (this._snapped) { this._snapped = false; this._offsetX = Math.ceil(this._width / 2); style = this.container.style; style.top = this._y - this._offsetY + "px"; style.left = this._x - this._offsetX + "px"; style.width = this._width + "px"; style.height = this._height + "px"; } } }); return Snappable; }; ui.Window = new function () { function Window(container) { if (!(this instanceof ui.Window)) { return new ui.Window(container); } this.container = container; this.activeElement = container.querySelector(".window-title"); this.enableDragging(); this.enableSnapping(); } obj.extend(fn.inherit(Window, ui.Snappable).prototype, { container: null, activeElement: null, }); return Window; }; arr.from(document.querySelectorAll(".window")).forEach(ui.Window); </script> </body> </html>Кросс-браузерность допилите, проверял только в IE10. |
Часовой пояс GMT +3, время: 05:52. |