| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- <script setup lang="ts">
- import Camera from '@/assets/camera.html?url';
- import { DEFAULT_HEIGHT, DEFAULT_WIDTH, DEFAULT_ZOOM } from '@/modules/camera/camera.config';
- const {
- preview = true,
- scale = 1,
- offsetX = 0,
- offsetY = 0,
- } = defineProps<{
- scale?: number;
- offsetX?: number;
- offsetY?: number;
- preview?: boolean;
- }>();
- const emits = defineEmits<{ loaded: [] }>();
- const style = computed(() => `width: ${scale * DEFAULT_WIDTH}px;height: ${scale * DEFAULT_HEIGHT}px;`);
- const snapshot = ref<string | void>();
- const cameraFrameRef = useTemplateRef<
- HTMLIFrameElement & {
- contentWindow: {
- loadCamera(props: { width: number; height: number; zoom?: number }): Promise<void>;
- handle(promise?: Promise<void>): string;
- updateCoordinate(offsetX: number, offsetY: number): void;
- };
- }
- >('camera-frame');
- const loadCamera = async () => {
- await cameraFrameRef.value?.contentWindow.loadCamera?.({
- width: DEFAULT_WIDTH,
- height: DEFAULT_HEIGHT,
- zoom: DEFAULT_ZOOM,
- });
- cameraFrameRef.value?.contentWindow.addEventListener('resize', update);
- emits('loaded');
- };
- watch([() => offsetX, () => offsetY], () => { setTimeout(update, 100); });
- function update() {
- cameraFrameRef.value?.contentWindow.updateCoordinate?.(offsetX, offsetY);
- }
- defineExpose({
- handle() {
- if ( !preview || !snapshot.value ) {
- snapshot.value = cameraFrameRef.value?.contentWindow.handle?.();
- } else {
- snapshot.value = void 0;
- }
- return snapshot.value;
- },
- });
- </script>
- <template>
- <div class="relative camera-container" :style="style">
- <iframe ref="camera-frame" :src="Camera" @load="loadCamera()"></iframe>
- <img v-if="snapshot" :src="snapshot" alt="图像" />
- <slot name="shade" :style="style" :scale="scale"></slot>
- </div>
- </template>
- <style scoped lang="scss">
- .camera-container {
- iframe {
- clip-path: url('#shade');
- }
- img {
- object-fit: scale-down;
- }
- > * {
- position: absolute;
- width: 100%;
- height: 100%;
- }
- }
- </style>
|