feat: drag to resize

This commit is contained in:
redhoodsu
2022-12-06 00:21:38 +08:00
parent 1084576623
commit 07697e8f7a
6 changed files with 122 additions and 55 deletions

View File

@@ -1,8 +0,0 @@
<div {{{class 'dev-tools'}}}>
<div {{{class 'nav-bar-container'}}}>
<div {{{class 'nav-bar'}}}></div>
<div class="eruda-bottom-bar"></div>
</div>
<div {{{class 'tools'}}}></div>
<div class="eruda-notification"></div>
</div>

View File

@@ -10,12 +10,13 @@ import last from 'licia/last'
import each from 'licia/each'
import isNum from 'licia/isNum'
import $ from 'licia/$'
import throttle from 'licia/throttle'
import toNum from 'licia/toNum'
import isDarkMode from 'licia/isDarkMode'
import extend from 'licia/extend'
import evalCss from '../lib/evalCss'
import { isDarkTheme } from '../lib/themes'
import LunaNotification from 'luna-notification'
import { classPrefix as c } from '../lib/util'
export default class DevTools extends Emitter {
constructor($container, { defaults = {} } = {}) {
@@ -85,9 +86,9 @@ export default class DevTools extends Emitter {
if (this._tools[name]) return logger.warn(`Tool ${name} already exists`)
this._$tools.prepend(
`<div id="eruda-${name}" class="eruda-${name} eruda-tool"></div>`
`<div id="${c(name)}" class="${c(name + ' tool')}"></div>`
)
tool.init(this._$tools.find(`.eruda-${name}.eruda-tool`), this)
tool.init(this._$tools.find(`.${c(name)}.${c('tool')}`), this)
tool.active = false
this._tools[name] = tool
@@ -196,9 +197,9 @@ export default class DevTools extends Emitter {
const { $container } = this
if (isDarkTheme(theme)) {
$container.addClass('eruda-dark')
$container.addClass(c('dark'))
} else {
$container.rmClass('eruda-dark')
$container.rmClass(c('dark'))
}
evalCss.setTheme(theme)
}
@@ -216,18 +217,30 @@ export default class DevTools extends Emitter {
_appendTpl() {
const $container = this.$container
$container.append(require('./DevTools.hbs')())
$container.append(
c(`
<div class="dev-tools">
<div class="resizer"></div>
<div class="nav-bar-container">
<div class="nav-bar"></div>
<div class="bottom-bar"></div>
</div>
<div class="tools"></div>
<div class="notification"></div>
</div>
`)
)
this._$el = $container.find('.eruda-dev-tools')
this._$tools = this._$el.find('.eruda-tools')
this._$el = $container.find(c('.dev-tools'))
this._$tools = this._$el.find(c('.tools'))
}
_initNavBar() {
this._navBar = new NavBar(this._$el.find('.eruda-nav-bar-container'))
this._navBar = new NavBar(this._$el.find(c('.nav-bar-container')))
this._navBar.on('showTool', (name) => this.showTool(name))
}
_initNotification() {
this._notification = new LunaNotification(
this._$el.find('.eruda-notification').get(0),
this._$el.find(c('.notification')).get(0),
{
position: {
x: 'center',
@@ -237,46 +250,62 @@ export default class DevTools extends Emitter {
)
}
_bindEvent() {
const $navBar = this._$el.find('.eruda-nav-bar')
const $resizer = this._$el.find(c('.resizer'))
const $navBar = this._$el.find(c('.nav-bar'))
const $root = $(document.documentElement)
const startListener = (e) => {
e.preventDefault()
e.stopPropagation()
e = e.origEvent
this._resizeTimer = setTimeout(() => {
e.preventDefault()
e.stopPropagation()
this._isResizing = true
this._resizeStartSize = this.config.get('displaySize')
this._resizeStartY = getClientY(e)
$navBar.css('filter', 'brightness(1.2)')
}, 1000)
this._isResizing = true
this._resizeStartSize = this.config.get('displaySize')
this._resizeStartY = getClientY(e)
$resizer.css('height', '100%')
if (isMobile()) {
$root.on('touchmove', moveListener)
$root.on('touchend', endListener)
} else {
$root.on('mousemove', moveListener)
$root.on('mouseup', endListener)
}
}
const setDisplaySize = throttle(
(size) => this.config.set('displaySize', size),
50
)
const moveListener = (e) => {
if (!this._isResizing) {
return clearTimeout(this._resizeTimer)
return
}
e.preventDefault()
e.stopPropagation()
e = e.origEvent
const deltaY = Math.round(
const deltaY =
((this._resizeStartY - getClientY(e)) / window.innerHeight) * 100
)
let displaySize = this._resizeStartSize + deltaY
if (displaySize < 40) {
displaySize = 40
} else if (displaySize > 100) {
displaySize = 100
}
setDisplaySize(displaySize)
this.config.set('displaySize', toNum(displaySize.toFixed(2)))
}
const endListener = () => {
clearTimeout(this._resizeTimer)
this._isResizing = false
$navBar.css('filter', 'brightness(1)')
$resizer.css('height', 10)
if (isMobile()) {
$root.off('touchmove', moveListener)
$root.off('touchend', endListener)
} else {
$root.off('mousemove', moveListener)
$root.off('mouseup', endListener)
}
}
$resizer.css('height', 10)
const getClientY = (e) => {
if (e.clientY) return e.clientY
@@ -285,14 +314,10 @@ export default class DevTools extends Emitter {
return 0
}
$navBar.on('contextmenu', (e) => e.preventDefault())
const $root = $(document.documentElement)
if (isMobile()) {
$navBar.on('touchstart', startListener).on('touchmove', moveListener)
$root.on('touchend', endListener)
$resizer.on('touchstart', startListener)
} else {
$navBar.on('mousedown', startListener)
$root.on('mousemove', moveListener)
$root.on('mouseup', endListener)
$resizer.on('mousedown', startListener)
}
}
}

View File

@@ -12,7 +12,15 @@
display: none;
padding-top: 40px !important;
opacity: 0;
transition: opacity $anim-duration, height $anim-duration;
transition: opacity $anim-duration;
.resizer {
position: absolute;
width: 100%;
left: 0;
top: -8px;
cursor: row-resize;
z-index: 120;
}
.tools {
@include overflow-auto();
height: 100%;

View File

@@ -2,6 +2,7 @@ import Emitter from 'licia/Emitter'
import $ from 'licia/$'
import isNum from 'licia/isNum'
import evalCss from '../lib/evalCss'
import { classPrefix as c } from '../lib/util'
export default class NavBar extends Emitter {
constructor($el) {
@@ -9,8 +10,8 @@ export default class NavBar extends Emitter {
this._style = evalCss(require('./NavBar.scss'))
this._$el = $el.find('.eruda-nav-bar')
this._$bottomBar = $el.find('.eruda-bottom-bar')
this._$el = $el.find(c('.nav-bar'))
this._$bottomBar = $el.find(c('.bottom-bar'))
this._len = 0
this._bindEvent()
@@ -19,8 +20,8 @@ export default class NavBar extends Emitter {
const $el = this._$el
this._len++
const $last = $el.find('.eruda-nav-bar-item').last()
const html = `<div class="eruda-nav-bar-item">${name}</div>`
const $last = $el.find(c('.nav-bar-item')).last()
const html = `<div class="${c('nav-bar-item')}">${name}</div>`
if ($last.length > 0 && $last.text() === 'settings') {
$last.before(html)
} else {
@@ -30,7 +31,7 @@ export default class NavBar extends Emitter {
}
remove(name) {
this._len--
this._$el.find('.eruda-nav-bar-item').each(function () {
this._$el.find(c('.nav-bar-item')).each(function () {
const $this = $(this)
if ($this.text().toLowerCase() === name.toLowerCase()) $this.remove()
})
@@ -39,15 +40,15 @@ export default class NavBar extends Emitter {
activateTool(name) {
const self = this
this._$el.find('.eruda-nav-bar-item').each(function () {
this._$el.find(c('.nav-bar-item')).each(function () {
const $this = $(this)
if ($this.text() === name) {
$this.addClass('eruda-active')
$this.addClass(c('active'))
self.resetBottomBar()
self._scrollItemToView()
} else {
$this.rmClass('eruda-active')
$this.rmClass(c('active'))
}
})
}
@@ -57,7 +58,7 @@ export default class NavBar extends Emitter {
}
_scrollItemToView() {
const $el = this._$el
const li = $el.find('.eruda-active').get(0)
const li = $el.find(c('.active')).get(0)
const container = $el.get(0)
const itemLeft = li.offsetLeft
@@ -80,7 +81,7 @@ export default class NavBar extends Emitter {
const $bottomBar = this._$bottomBar
const $el = this._$el
const li = $el.find('.eruda-active').get(0)
const li = $el.find(c('.active')).get(0)
if (!li) return
@@ -93,7 +94,7 @@ export default class NavBar extends Emitter {
const self = this
this._$el
.on('click', '.eruda-nav-bar-item', function () {
.on('click', c('.nav-bar-item'), function () {
self.emit('showTool', $(this).text())
})
.on('scroll', () => this.resetBottomBar())