| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- <template>
- <div class="alpha">
- <div class="alpha-checkboard-wrap">
- <Checkboard />
- </div>
- <div class="alpha-gradient" :style="{ background: gradientColor }"></div>
- <div
- class="alpha-container"
- ref="alphaRef"
- @mousedown="$event => handleMouseDown($event)"
- >
- <div class="alpha-pointer" :style="{ left: color.a * 100 + '%' }">
- <div class="alpha-picker"></div>
- </div>
- </div>
- </div>
- </template>
- <script lang="ts">
- import { computed, defineComponent, onUnmounted, PropType, ref } from 'vue'
- import Checkboard from './Checkboard.vue'
- import { ColorFormats } from 'tinycolor2'
- export default defineComponent({
- name: 'alpha',
- components: {
- Checkboard,
- },
- props: {
- value: {
- type: Object as PropType<ColorFormats.RGBA>,
- required: true,
- },
- },
- setup(props, { emit }) {
- const color = computed(() => props.value)
-
- const gradientColor = computed(() => {
- const rgbaStr = [color.value.r, color.value.g, color.value.b].join(',')
- return `linear-gradient(to right, rgba(${rgbaStr}, 0) 0%, rgba(${rgbaStr}, 1) 100%)`
- })
- const alphaRef = ref<HTMLElement>()
- const handleChange = (e: MouseEvent) => {
- e.preventDefault()
- if (!alphaRef.value) return
- const containerWidth = alphaRef.value.clientWidth
- const xOffset = alphaRef.value.getBoundingClientRect().left + window.pageXOffset
- const left = e.pageX - xOffset
- let a
- if (left < 0) a = 0
- else if (left > containerWidth) a = 1
- else a = Math.round(left * 100 / containerWidth) / 100
- if (color.value.a !== a) {
- emit('colorChange', {
- r: color.value.r,
- g: color.value.g,
- b: color.value.b,
- a: a,
- })
- }
- }
- const unbindEventListeners = () => {
- window.removeEventListener('mousemove', handleChange)
- window.removeEventListener('mouseup', unbindEventListeners)
- }
- const handleMouseDown = (e: MouseEvent) => {
- handleChange(e)
- window.addEventListener('mousemove', handleChange)
- window.addEventListener('mouseup', unbindEventListeners)
- }
- onUnmounted(unbindEventListeners)
- return {
- alphaRef,
- gradientColor,
- handleMouseDown,
- color,
- }
- },
- })
- </script>
- <style lang="scss" scoped>
- .alpha {
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- }
- .alpha-checkboard-wrap {
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- overflow: hidden;
- }
- .alpha-gradient {
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- }
- .alpha-container {
- cursor: pointer;
- position: relative;
- z-index: 2;
- height: 100%;
- margin: 0 3px;
- }
- .alpha-pointer {
- z-index: 2;
- position: absolute;
- }
- .alpha-picker {
- cursor: pointer;
- width: 4px;
- height: 8px;
- box-shadow: 0 0 2px rgba(0, 0, 0, .6);
- background: #fff;
- margin-top: 1px;
- transform: translateX(-2px);
- }
- </style>
|