Quellcode durchsuchen

wip: 图片裁剪

kailong321200875 vor 1 Jahr
Ursprung
Commit
19ccf8b518

+ 9 - 0
mock/role/index.ts

@@ -293,6 +293,14 @@ const adminList = [
         meta: {
           title: 'router.waterfall'
         }
+      },
+      {
+        path: 'image-cropping',
+        component: 'views/Components/ImageCropping',
+        name: 'ImageCropping',
+        meta: {
+          title: 'router.imageCropping'
+        }
       }
     ]
   },
@@ -651,6 +659,7 @@ const testList: string[] = [
   '/components/infotip',
   '/components/input-password',
   '/components/waterfall',
+  '/components/image-cropping',
   'function',
   '/function/multiple-tabs',
   '/function/multiple-tabs-demo/:id',

+ 3 - 0
src/components/ImageCropping/index.ts

@@ -0,0 +1,3 @@
+import ImageCropping from './src/ImageCropping.vue'
+
+export { ImageCropping }

+ 76 - 0
src/components/ImageCropping/src/ImageCropping.vue

@@ -0,0 +1,76 @@
+<script setup lang="ts">
+import { useDesign } from '@/hooks/web/useDesign'
+import { propTypes } from '@/utils/propTypes'
+import { CSSProperties, computed } from 'vue'
+
+const { getPrefixCls } = useDesign()
+
+const prefixCls = getPrefixCls('image-cropping')
+
+const bgIcon =
+  'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC'
+
+const props = defineProps({
+  imageUrl: propTypes.string,
+  boxWidth: propTypes.oneOfType([propTypes.number, propTypes.string]).def('100%'),
+  boxHeight: propTypes.oneOfType([propTypes.number, propTypes.string]).def('100%'),
+  dragWidth: propTypes.oneOfType([propTypes.number, propTypes.string]).def(200),
+  dragHeight: propTypes.oneOfType([propTypes.number, propTypes.string]).def(200),
+  cropWidth: propTypes.oneOfType([propTypes.number, propTypes.string]).def(200),
+  cropHeight: propTypes.oneOfType([propTypes.number, propTypes.string]).def(200)
+})
+
+const boxStyles = computed((): CSSProperties => {
+  return {
+    width: (typeof props.boxWidth === 'number' ? `${props.boxWidth}px` : props.boxWidth) ?? '100%',
+    height:
+      (typeof props.boxHeight === 'number' ? `${props.boxHeight}px` : props.boxHeight) ?? '100%',
+    position: 'relative',
+    backgroundImage: `url(${bgIcon})`
+  }
+})
+
+const dragStyles = computed((): CSSProperties => {
+  return {
+    width: (typeof props.dragWidth === 'number' ? `${props.dragWidth}px` : props.dragWidth) ?? 200,
+    height:
+      (typeof props.dragHeight === 'number' ? `${props.dragHeight}px` : props.dragHeight) ?? 200,
+    position: 'absolute',
+    top: '50%',
+    left: '50%',
+    transform: 'translate(-50%, -50%)',
+    zIndex: 1,
+    boxShadow: '0 0 0 1px var(--el-color-primary),0 0 0 10000px rgba(0,0,0,.5)',
+    cursor: 'move'
+  }
+})
+
+const cropStyles = computed((): CSSProperties => {
+  return {
+    width: (typeof props.cropWidth === 'number' ? `${props.cropWidth}px` : props.cropWidth) ?? 300,
+    height:
+      (typeof props.cropHeight === 'number' ? `${props.cropHeight}px` : props.cropHeight) ?? 300,
+    position: 'absolute',
+    top: '50%',
+    left: '80px',
+    transform: 'translate(0, -50%)',
+    overflow: 'hidden',
+    borderRadius: '50%',
+    border: '1px solid var(--el-border-color)'
+  }
+})
+</script>
+
+<template>
+  <div :class="prefixCls" class="flex">
+    <div class="flex-1">
+      <div :style="boxStyles">
+        <img :src="imageUrl" class="w-full absolute top-[50%] left-[50%]" alt="" srcset="" />
+        <div :style="dragStyles"> </div>
+      </div>
+    </div>
+    <div class="relative w-full">
+      <div :style="cropStyles"></div>
+    </div>
+  </div>
+</template>

+ 2 - 1
src/locales/en.ts

@@ -177,7 +177,8 @@ export default {
     details: 'Details',
     iconPicker: 'Icon picker',
     request: 'Request',
-    waterfall: 'Waterfall'
+    waterfall: 'Waterfall',
+    imageCropping: 'Image cropping'
   },
   permission: {
     hasPermission: 'Please set the operation permission value'

+ 2 - 1
src/locales/zh-CN.ts

@@ -175,7 +175,8 @@ export default {
     details: '详情页',
     iconPicker: '图标选择器',
     request: '请求',
-    waterfall: '瀑布流'
+    waterfall: '瀑布流',
+    imageCropping: '图片裁剪'
   },
   permission: {
     hasPermission: '请设置操作权限值'

+ 8 - 0
src/router/index.ts

@@ -334,6 +334,14 @@ export const asyncRouterMap: AppRouteRecordRaw[] = [
         meta: {
           title: t('router.waterfall')
         }
+      },
+      {
+        path: 'image-cropping',
+        component: () => import('@/views/Components/ImageCropping.vue'),
+        name: 'ImageCropping',
+        meta: {
+          title: t('router.imageCropping')
+        }
       }
     ]
   },

+ 14 - 0
src/views/Components/ImageCropping.vue

@@ -0,0 +1,14 @@
+<script setup lang="ts">
+import { ContentWrap } from '@/components/ContentWrap'
+import { ImageCropping } from '@/components/ImageCropping'
+</script>
+
+<template>
+  <ContentWrap title="图片裁剪">
+    <ImageCropping
+      :box-width="350"
+      :box-height="380"
+      image-url="https://images6.alphacoders.com/657/thumbbig-657194.webp"
+    />
+  </ContentWrap>
+</template>