Merge pull request #432 from Budibase/colorpicker/palette-drag
Palette Drag, Debounce and Tidyup
This commit is contained in:
commit
672ef1745e
|
@ -2,13 +2,13 @@ export default function(node) {
|
||||||
function handleMouseDown() {
|
function handleMouseDown() {
|
||||||
window.addEventListener("mousemove", handleMouseMove)
|
window.addEventListener("mousemove", handleMouseMove)
|
||||||
window.addEventListener("mouseup", handleMouseUp)
|
window.addEventListener("mouseup", handleMouseUp)
|
||||||
|
node.dispatchEvent(new CustomEvent("dragstart"))
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleMouseMove(event) {
|
function handleMouseMove(event) {
|
||||||
let mouseX = event.clientX
|
|
||||||
node.dispatchEvent(
|
node.dispatchEvent(
|
||||||
new CustomEvent("drag", {
|
new CustomEvent("drag", {
|
||||||
detail: mouseX,
|
detail: { mouseX: event.clientX, mouseY: event.clientY },
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
<script>
|
<script>
|
||||||
import FlatButton from "./FlatButton.svelte"
|
import FlatButton from "./FlatButton.svelte"
|
||||||
|
import { createEventDispatcher } from "svelte"
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
export let format = "hex"
|
export let format = "hex"
|
||||||
export let onclick = format => {}
|
|
||||||
|
|
||||||
let colorFormats = ["hex", "rgb", "hsl"]
|
let colorFormats = ["hex", "rgb", "hsl"]
|
||||||
</script>
|
</script>
|
||||||
|
@ -12,7 +14,7 @@
|
||||||
<FlatButton
|
<FlatButton
|
||||||
selected={format === text}
|
selected={format === text}
|
||||||
{text}
|
{text}
|
||||||
on:click={() => onclick(text)} />
|
on:click={() => dispatch('click', text)} />
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -120,7 +120,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeFormatAndConvert(f) {
|
function changeFormatAndConvert(f) {
|
||||||
format = f
|
format = f.detail
|
||||||
value = convertHsvaToFormat([h, s, v, a], format)
|
value = convertHsvaToFormat([h, s, v, a], format)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,7 +251,7 @@
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="format-input-panel">
|
<div class="format-input-panel">
|
||||||
<ButtonGroup {format} onclick={changeFormatAndConvert} />
|
<ButtonGroup {format} on:click={changeFormatAndConvert} />
|
||||||
<Input
|
<Input
|
||||||
{value}
|
{value}
|
||||||
on:input={event => handleColorInput(event.target.value)}
|
on:input={event => handleColorInput(event.target.value)}
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
let errorMsg = null
|
let errorMsg = null
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
const dispatchValue = value =>
|
||||||
|
debounce(() => dispatch("change", value), 300, true)
|
||||||
|
|
||||||
beforeUpdate(() => {
|
beforeUpdate(() => {
|
||||||
format = getColorFormat(value)
|
format = getColorFormat(value)
|
||||||
|
@ -47,7 +49,7 @@
|
||||||
|
|
||||||
function onColorChange(color) {
|
function onColorChange(color) {
|
||||||
value = color.detail
|
value = color.detail
|
||||||
dispatch("change", color.detail)
|
dispatchValue(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
function calculateDimensions() {
|
function calculateDimensions() {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { onMount, createEventDispatcher } from "svelte"
|
import { onMount, createEventDispatcher } from "svelte"
|
||||||
|
import { drag } from "../actions"
|
||||||
import CheckedBackground from "./CheckedBackground.svelte"
|
import CheckedBackground from "./CheckedBackground.svelte"
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
@ -14,18 +15,13 @@
|
||||||
let paletteHeight,
|
let paletteHeight,
|
||||||
paletteWidth = 0
|
paletteWidth = 0
|
||||||
|
|
||||||
function handleClick(event) {
|
function handePaletteChange({ mouseX, mouseY }) {
|
||||||
const { left, top } = palette.getBoundingClientRect()
|
const { left, top } = palette.getBoundingClientRect()
|
||||||
let clickX = event.clientX - left
|
let x = mouseX - left
|
||||||
let clickY = event.clientY - top
|
let y = mouseY - top
|
||||||
if (
|
if (x > 0 && y > 0 && x < paletteWidth && y < paletteHeight) {
|
||||||
clickX > 0 &&
|
let s = (x / paletteWidth) * 100
|
||||||
clickY > 0 &&
|
let v = 100 - (y / paletteHeight) * 100
|
||||||
clickX < paletteWidth &&
|
|
||||||
clickY < paletteHeight
|
|
||||||
) {
|
|
||||||
let s = (clickX / paletteWidth) * 100
|
|
||||||
let v = 100 - (clickY / paletteHeight) * 100
|
|
||||||
dispatch("change", { s, v })
|
dispatch("change", { s, v })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,10 +42,17 @@
|
||||||
bind:this={palette}
|
bind:this={palette}
|
||||||
bind:clientHeight={paletteHeight}
|
bind:clientHeight={paletteHeight}
|
||||||
bind:clientWidth={paletteWidth}
|
bind:clientWidth={paletteWidth}
|
||||||
on:click={handleClick}
|
on:click={event => handePaletteChange({
|
||||||
|
mouseX: event.clientX,
|
||||||
|
mouseY: event.clientY,
|
||||||
|
})}
|
||||||
class="palette"
|
class="palette"
|
||||||
{style}>
|
{style}>
|
||||||
<div class="picker" style={pickerStyle} />
|
<div
|
||||||
|
use:drag
|
||||||
|
on:drag={event => handePaletteChange(event.detail)}
|
||||||
|
class="picker"
|
||||||
|
style={pickerStyle} />
|
||||||
</div>
|
</div>
|
||||||
</CheckedBackground>
|
</CheckedBackground>
|
||||||
|
|
||||||
|
@ -64,10 +67,15 @@
|
||||||
|
|
||||||
.picker {
|
.picker {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
cursor: grab;
|
||||||
width: 10px;
|
width: 10px;
|
||||||
height: 10px;
|
height: 10px;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
border: 2px solid white;
|
border: 2px solid white;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.picker:active {
|
||||||
|
cursor: grabbing;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -14,8 +14,9 @@
|
||||||
|
|
||||||
const isWithinLimit = value => value >= 0 && value <= upperLimit
|
const isWithinLimit = value => value >= 0 && value <= upperLimit
|
||||||
|
|
||||||
function onSliderChange(mouseX, isDrag = false) {
|
function onSliderChange({ mouseX }, isDrag = false) {
|
||||||
const { left, width } = slider.getBoundingClientRect()
|
const { left, width } = slider.getBoundingClientRect()
|
||||||
|
|
||||||
let clickPosition = mouseX - left
|
let clickPosition = mouseX - left
|
||||||
|
|
||||||
let percentageClick = (clickPosition / sliderWidth).toFixed(2)
|
let percentageClick = (clickPosition / sliderWidth).toFixed(2)
|
||||||
|
@ -42,6 +43,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleDragEnd() {
|
||||||
|
dispatch("dragend")
|
||||||
|
}
|
||||||
|
|
||||||
$: thumbPosition =
|
$: thumbPosition =
|
||||||
type === "hue" ? sliderWidth * (value / 360) : sliderWidth * value
|
type === "hue" ? sliderWidth * (value / 360) : sliderWidth * value
|
||||||
|
|
||||||
|
@ -53,14 +58,14 @@
|
||||||
bind:this={slider}
|
bind:this={slider}
|
||||||
use:keyevents={{ 37: handleLeftKey, 39: handleRightKey }}
|
use:keyevents={{ 37: handleLeftKey, 39: handleRightKey }}
|
||||||
bind:clientWidth={sliderWidth}
|
bind:clientWidth={sliderWidth}
|
||||||
on:click={event => onSliderChange(event.clientX)}
|
on:click={event => onSliderChange({ mouseX: event.clientX })}
|
||||||
class="color-format-slider"
|
class="color-format-slider"
|
||||||
class:hue={type === 'hue'}
|
class:hue={type === 'hue'}
|
||||||
class:alpha={type === 'alpha'}>
|
class:alpha={type === 'alpha'}>
|
||||||
<div
|
<div
|
||||||
use:drag
|
use:drag
|
||||||
on:drag={e => onSliderChange(e.detail, true)}
|
on:drag={e => onSliderChange(e.detail, true)}
|
||||||
on:dragend
|
on:dragend={handleDragEnd}
|
||||||
class="slider-thumb"
|
class="slider-thumb"
|
||||||
{style} />
|
{style} />
|
||||||
</div>
|
</div>
|
||||||
|
@ -106,4 +111,8 @@
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
cursor: grab;
|
cursor: grab;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.slider-thumb:active {
|
||||||
|
cursor: grabbing;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -13,8 +13,12 @@ export const convertCamel = str => {
|
||||||
return str.replace(/[A-Z]/g, match => `-${match.toLowerCase()}`)
|
return str.replace(/[A-Z]/g, match => `-${match.toLowerCase()}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const debounce = (fn, milliseconds) => {
|
export const debounce = (fn, milliseconds, callImmediately) => {
|
||||||
return () => {
|
const debouncedFn = () => {
|
||||||
setTimeout(fn, milliseconds)
|
setTimeout(fn, milliseconds)
|
||||||
}
|
}
|
||||||
|
if (callImmediately) {
|
||||||
|
debouncedFn()
|
||||||
|
}
|
||||||
|
return debouncedFn
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue