feat: tui-image-editor 使用完成

master
LCJ-MinYa 7 months ago
parent c5cc48c240
commit 1f9c282ad7

@ -4,13 +4,33 @@
class="tui-image-editor-wrap"
v-loading="loading"
>
<div id="tui-image-editor"></div>
<div
ref="tuiImageEditorRef"
id="tui-image-editor"
></div>
<el-button
circle
:icon="Close"
class="close-btn"
@click="closeEditor"
></el-button>
<el-button
:loading="sending"
type="primary"
class="save-btn"
@click="save"
>保存图片</el-button
>
<el-icon
class="left-btn"
@click="changeImage('prev')"
><ArrowLeftBold
/></el-icon>
<el-icon
class="right-btn"
@click="changeImage('next')"
><ArrowRightBold
/></el-icon>
</div>
</Teleport>
</template>
@ -18,15 +38,21 @@
<script setup>
import '../css/tui-color-picker.css';
import '../css/tui-image-editor.css';
import { ref, onMounted, watch } from 'vue';
import { Close } from '@element-plus/icons-vue';
import { ref, onMounted, onUnmounted } from 'vue';
import { Close, ArrowLeftBold, ArrowRightBold } from '@element-plus/icons-vue';
const emits = defineEmits(['close']);
const props = defineProps(['imgList']);
const currentIndex = ref(0);
const imageEditor = ref(null);
const loading = ref(false);
const sending = ref(false);
const scale = ref(1);
const tuiImageEditorRef = ref(null);
const imgSize = {
width: 750,
height: 500,
};
function createScriptElement(src) {
return new Promise((resolve, reject) => {
@ -41,6 +67,7 @@ function createScriptElement(src) {
onMounted(async () => {
loading.value = true;
if (!window.hasOwnProperty('tui')) {
// js
await createScriptElement('/src/views/demo/tuiImageEditor/js/fabric.js');
await createScriptElement('/src/views/demo/tuiImageEditor/js/tui-code-snippet.js');
@ -49,9 +76,13 @@ onMounted(async () => {
await createScriptElement('/src/views/demo/tuiImageEditor/js/tui-image-editor.js');
await createScriptElement('/src/views/demo/tuiImageEditor/js/white-theme.js');
await createScriptElement('/src/views/demo/tuiImageEditor/js/black-theme.js');
}
initTuiImageEditor();
addEventListenerFN();
});
onUnmounted(() => {});
const locale_zh = {
Resize: '调整宽高',
Crop: '裁剪',
@ -152,53 +183,183 @@ const initTuiImageEditor = () => {
// Image editor
imageEditor.value = new tui.ImageEditor('#tui-image-editor', {
includeUI: {
loadImage: {},
loadImage: {
path: props.imgList[currentIndex.value].path,
name: props.imgList[currentIndex.value].name,
},
locale: locale_zh,
theme: theme,
menu: ['resize', 'crop', 'rotate', 'draw', 'shape', 'icon', 'text'],
},
cssMaxWidth: 700,
cssMaxHeight: 500,
cssMaxWidth: imgSize.width,
cssMaxHeight: imgSize.height,
usageStatistics: false,
});
imageEditor.value.loadImageFromURL(props.imgList[currentIndex.value].path, props.imgList[currentIndex.value].name).then((res) => {
console.log(res);
console.log(imageEditor.value);
imageEditor.value.ui._actions.main.zoomIn = () => {
console.log('zoomIn');
zoomSize('zoomIn');
};
imageEditor.value.ui._actions.main.zoomOut = () => {
console.log('zoomOut');
zoomSize('zoomOut');
};
});
window.onresize = function () {
imageEditor.value.ui.resizeEditor();
};
const defaultColor = '#ff4040';
console.log(imageEditor.value);
//
imageEditor.value.ui.draw.color = defaultColor;
imageEditor.value.ui.draw._els.drawColorPicker.colorElement.style.backgroundColor = defaultColor;
//
imageEditor.value.ui.shape.options.stroke = defaultColor;
imageEditor.value.ui.shape._els.strokeColorpicker.colorElement.style.backgroundColor = defaultColor;
//
imageEditor.value.ui.icon._els.iconColorpicker._color = defaultColor;
imageEditor.value.ui.icon._els.iconColorpicker.colorElement.style.backgroundColor = defaultColor;
//
imageEditor.value.ui.text._els.textColorpicker.color = defaultColor;
imageEditor.value.ui.text._els.textColorpicker.colorElement.style.backgroundColor = defaultColor;
// tui-image-editor.js addText 50592
// window.onresize = function () {
// imageEditor.value.ui.resizeEditor();
// };
// bug
// imageEditor.value.on('addText', (pos) => {
// let obj = imageEditor.value._graphics._objects;
// let arr = Reflect.ownKeys(obj);
// arr.forEach((item) => {
// if (obj[item].text === '') {
// let defaultText = '';
// obj[item].text = defaultText;
// obj[item].textLines[0] = defaultColor;
// obj[item]._text = defaultColor.split(',');
// obj[item]._textBeforeEdit = defaultColor;
// }
// });
// console.log(imageEditor.value);
// });
loading.value = false;
};
const addEventListenerFN = () => {
document.querySelector('.tui-image-editor-wrap').addEventListener('click', handleClickOutside);
window.addEventListener('wheel', handleWheelEvent);
};
const handleClickOutside = (event) => {
const getBtnDom = (claseeName) => {
return document.querySelector(claseeName);
};
if (
getBtnDom('.save-btn').contains(event.target) ||
getBtnDom('.left-btn').contains(event.target) ||
getBtnDom('.right-btn').contains(event.target)
) {
return;
}
if (tuiImageEditorRef.value && !(tuiImageEditorRef.value.contains(event.target) || tuiImageEditorRef.value === event.target)) {
closeEditor();
}
};
const handleWheelEvent = (event) => {
if (event.deltaY < 0) {
zoomSize('zoomIn');
} else {
zoomSize('zoomOut');
}
};
const zoomSize = (type) => {
console.log(type);
if ((scale.value > 1.5 && type === 'zoomIn') || (scale.value < 0.8 && type === 'zoomOut')) {
return;
}
if (type === 'zoomIn') {
scale.value = scale.value + 0.1;
} else {
scale.value = scale.value - 0.1;
}
imageEditor.value.resizeCanvasDimension({
width: 750 * scale.value,
height: 500 * scale.value,
width: imgSize.width * scale.value,
height: imgSize.height * scale.value,
});
};
const save = () => {
sending.value = true;
const base64String = imageEditor.value.toDataURL({ format: 'jpeg', quality: 0.8 });
//base64file
const data = window.atob(base64String.split(',')[1]);
const arr = new Uint8Array(data.length);
for (let i = 0; i < data.length; i++) {
arr[i] = data.charCodeAt(i);
}
const blob = new Blob([arr], { type: 'image/jpeg' }); //bolb
const file = new File([arr], new Date().getTime() + '.jpg', { type: blob.type }); //file
const objectURL = URL.createObjectURL(file); //fileurl
//
//
//
const a = document.createElement('a');
a.href = objectURL;
a.download = new Date().getTime() + '.jpg';
a.click();
URL.revokeObjectURL(objectURL);
sending.value = false;
};
const changeImage = (type) => {
loading.value = true;
let index;
switch (type) {
case 'prev':
index = currentIndex.value - 1;
if (index < 0) {
index = props.imgList.length - 1;
}
break;
case 'next':
index = currentIndex.value + 1;
if (index >= props.imgList.length) {
index = 0;
}
break;
default:
break;
}
imageEditor.value
.loadImageFromURL(props.imgList[index].path, props.imgList[index].name)
.then(() => {
currentIndex.value = index;
refreshImageShow();
})
.finally(() => {
loading.value = false;
});
};
const refreshImageShow = () => {
scale.value = 1;
imageEditor.value.resizeCanvasDimension({
width: imgSize.width,
height: imgSize.height,
});
};
const closeEditor = () => {
document.querySelector('.tui-image-editor-wrap').removeEventListener('click', handleClickOutside);
imageEditor.value.destroy();
imageEditor.value = null;
window.fabric = null;
emits('close');
};
</script>
@ -219,16 +380,41 @@ const closeEditor = () => {
margin: 0 auto;
}
.close-btn {
.close-btn,
.save-btn {
position: absolute;
top: 10px;
right: calc(50% - 400px + 18px);
z-index: 9;
}
.save-btn {
top: unset;
bottom: 10px;
}
.left-btn,
.right-btn {
position: absolute;
left: calc(50% - 400px + 10px);
top: 50%;
margin-top: -12px;
font-size: 24px;
cursor: pointer;
color: #fff;
}
.right-btn {
left: unset;
right: calc(50% - 400px + 10px);
}
}
</style>
<style lang="scss">
body > svg:last-of-type {
display: none;
}
//
.tui-image-editor-container div.tui-colorpicker-clearfix {
display: none !important;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

@ -29,11 +29,18 @@ const imgList = ref([
path: 'http://gips3.baidu.com/it/u=3886271102,3123389489&fm=3028&app=3028&f=JPEG&fmt=auto?w=1280&h=960',
name: '1',
},
{
path: 'http://gips3.baidu.com/it/u=3886271102,3123389489&fm=3028&app=3028&f=JPEG&fmt=auto?w=1280&h=960',
path: 'http://gips0.baidu.com/it/u=1690853528,2506870245&fm=3028&app=3028&f=JPEG&fmt=auto?w=1024&h=1024',
name: '2',
},
{
path: 'http://gips2.baidu.com/it/u=207216414,2485641185&fm=3028&app=3028&f=JPEG&fmt=auto?w=1280&h=720',
name: '3',
},
{
path: '/src/views/demo/tuiImageEditor/img/test.jpg',
name: '3',
},
]);
const openImageEditor = () => {

@ -50589,7 +50589,7 @@ var ImageTracer = /*#__PURE__*/function () {
underline = _this12$ui$text.underline;
var fontFamily = 'Noto Sans';
_this12.addText('Double Click', {
_this12.addText('请输入', {
position: pos.originPosition,
styles: {
fill: fill,

Loading…
Cancel
Save