-
Notifications
You must be signed in to change notification settings - Fork 547
Open
Labels
Milestone
Description
<template>
<button @click="onScreenshot">Screenshot</button>
<div v-if="cropping" class="cropper"
:style="style"
@mousedown="onStart"
@mousemove="onMove"
@mouseup="onEnd"
>
<div class="mask" v-if="style"></div>
<div class="area" v-if="style"></div>
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
const cropping = ref(false);
const startPoint = ref();
const endPoint = ref();
const rect = computed(() => {
if (!startPoint.value || !endPoint.value) return null;
return {
x: Math.min(startPoint.value.x, endPoint.value.x),
y: Math.min(startPoint.value.y, endPoint.value.y),
width: Math.abs(endPoint.value.x - startPoint.value.x),
height: Math.abs(endPoint.value.y - startPoint.value.y),
};
})
const style = computed(() => {
if (!rect.value) return null
return {
'--x': `${rect.value.x}px`,
'--y': `${rect.value.y}px`,
'--width': `${rect.value.width}px`,
'--height': `${rect.value.height}px`,
};
});
const onScreenshot = () => {
cropping.value = true;
}
const onStart = (e) => {
startPoint.value = { x: e.clientX, y: e.clientY };
};
const onMove = (e) => {
if (!startPoint.value) return;
endPoint.value = { x: e.clientX, y: e.clientY };
};
const onEnd = () => {
console.log(rect.value);
startPoint.value = undefined;
endPoint.value = undefined;
cropping.value = false;
};
</script>
<style>
.cropper {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
cursor: crosshair;
}
.mask {
width: 100%;
height: 100%;
background: rgba(0,0,0,0.2);
clip-path: polygon(
0% 0%,
0% 100%,
var(--x) 100%,
var(--x) var(--y),
calc(var(--x) + var(--width)) var(--y),
calc(var(--x) + var(--width)) calc(var(--y) + var(--height)),
var(--x) calc(var(--y) + var(--height)),
var(--x) 100%,
100% 100%,
100% 0%
);
}
.area {
position: absolute;
top: var(--y);
left: var(--x);
width: var(--width);
height: var(--height);
border: 1px solid black;
}
</style>