chore: structure change

This commit is contained in:
xiaoxian521
2021-04-14 16:44:58 +08:00
parent e027fec6dc
commit f4cd720ce8
43 changed files with 859 additions and 766 deletions

View File

@@ -0,0 +1,10 @@
import { App } from "vue"
import cropper from "./src/Cropper"
export const Cropper = Object.assign(cropper, {
install(app: App) {
app.component(cropper.name, cropper)
}
})
export default Cropper

View File

@@ -0,0 +1,127 @@
import type { CSSProperties } from 'vue'
import { defineComponent, onBeforeMount, nextTick, ref, unref, computed, PropType, getCurrentInstance } from 'vue'
import { useAttrs } from '/@/utils/useAttrs'
import { emitter } from '/@/utils/mitt'
import Cropper from 'cropperjs'
import 'cropperjs/dist/cropper.css'
type Options = Cropper.Options
const defaultOptions: Cropper.Options = {
aspectRatio: 16 / 9,
zoomable: true,
zoomOnTouch: true,
zoomOnWheel: true,
cropBoxMovable: true,
cropBoxResizable: true,
toggleDragModeOnDblclick: true,
autoCrop: true,
background: true,
highlight: true,
center: true,
responsive: true,
restore: true,
checkCrossOrigin: true,
checkOrientation: true,
scalable: true,
modal: true,
guides: true,
movable: true,
rotatable: true,
}
export default defineComponent({
name: "Cropper",
props: {
src: {
type: String,
required: true,
},
alt: {
type: String,
},
width: {
type: [String, Number],
default: '',
},
height: {
type: [String, Number],
default: '360px',
},
crossorigin: {
type: String || Object,
default: undefined,
},
imageStyle: {
type: Object as PropType<CSSProperties>,
default: {},
},
options: {
type: Object as PropType<Options>,
default: {},
}
},
setup(props) {
let vm: any
const cropper: any = ref<Nullable<Cropper>>(null)
const isReady = ref(false)
const getImageStyle = computed(
(): CSSProperties => {
return {
height: props.height,
width: props.width,
maxWidth: '100%',
...props.imageStyle,
}
}
)
const getWrapperStyle = computed(
(): CSSProperties => {
const { height, width } = props
return { width: `${width}`.replace(/px/, '') + 'px', height: `${height}`.replace(/px/, '') + 'px' }
}
)
async function init() {
const imgEl = vm.refs.imgElRef
if (!imgEl) {
return
}
cropper.value = new Cropper(imgEl, {
...defaultOptions,
ready: () => {
isReady.value = true
},
...props.options,
})
}
onBeforeMount(() => {
vm = getCurrentInstance()
nextTick(() => {
init()
// tsx语法返回渲染模板外部组件想调用内部方法或者获取setup里面的实例暂时想到的办法是通过公共事件
emitter.emit("cropperInstance", unref(cropper))
})
})
return () => (
<>
<div class={useAttrs({ excludeListeners: true, excludeKeys: ['class'] })} style={unref(getWrapperStyle)}>
<img
ref="imgElRef"
src={props.src}
alt={props.alt}
crossorigin={props.crossorigin}
style={unref(getImageStyle)}
/>
</div>
</>
)
},
})

View File

@@ -0,0 +1,131 @@
/**
<template>
<div :class="$attrs.class" :style="getWrapperStyle">
<img
v-show="isReady"
ref="imgElRef"
:src="src"
:alt="alt"
:crossorigin="crossorigin"
:style="getImageStyle"
/>
</div>
</template>
<script lang="ts">
import type { CSSProperties } from 'vue';
import { defineComponent, onMounted, ref, unref, computed, PropType } from 'vue';
import Cropper from 'cropperjs';
import 'cropperjs/dist/cropper.css';
type Options = Cropper.Options;
const defaultOptions: Cropper.Options = {
aspectRatio: 16 / 9,
zoomable: true,
zoomOnTouch: true,
zoomOnWheel: true,
cropBoxMovable: true,
cropBoxResizable: true,
toggleDragModeOnDblclick: true,
autoCrop: true,
background: true,
highlight: true,
center: true,
responsive: true,
restore: true,
checkCrossOrigin: true,
checkOrientation: true,
scalable: true,
modal: true,
guides: true,
movable: true,
rotatable: true,
};
export default defineComponent({
name: "Cropper",
props: {
src: {
type: String,
required: true,
},
alt: {
type: String,
},
height: {
type: [String, Number],
default: '360px',
},
crossorigin: {
type: String,
default: undefined,
},
imageStyle: {
type: Object as PropType<CSSProperties>,
default: {},
},
options: {
type: Object as PropType<Options>,
default: {},
},
},
setup(props, ctx) {
const imgElRef = ref<ElRef<HTMLImageElement>>(null);
const cropper: any = ref<Nullable<Cropper>>(null);
const isReady = ref(false);
const getImageStyle = computed(
(): CSSProperties => {
return {
height: props.height,
maxWidth: '100%',
...props.imageStyle,
};
}
);
const getWrapperStyle = computed(
(): CSSProperties => {
const { height } = props;
return { height: `${height}`.replace(/px/, '') + 'px' };
}
);
async function init() {
const imgEl = unref(imgElRef);
if (!imgEl) {
return;
}
cropper.value = new Cropper(imgEl, {
...defaultOptions,
ready: () => {
isReady.value = true;
},
...props.options,
});
}
// event: return base64 and width and height information after cropping
const croppered = (): void => {
let imgInfo = cropper.value.getData();
cropper.value.getCroppedCanvas().toBlob(blob => {
let fileReader: FileReader = new FileReader()
fileReader.onloadend = (e: any) => {
ctx.emit("cropperedInfo", {
imgBase64: e.target.result,
imgInfo
})
}
fileReader.readAsDataURL(blob)
}, 'image/jpeg')
}
onMounted(init);
return { imgElRef, getWrapperStyle, getImageStyle, isReady, croppered };
},
});
</script>
*/