Merge branch 'dev_vite' of http://18.167.251.121:10003/aidlab/aida_front into dev_vite
This commit is contained in:
@@ -329,12 +329,6 @@ const otherData = {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="app-container-example">
|
<div class="app-container-example">
|
||||||
<div id="test" style="position: fixed;
|
|
||||||
width: 500px; height: 500px;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
z-index: 9999999;"><pingpu
|
|
||||||
url="/src/assets/images/canvas/yinhua1.jpg" /></div>
|
|
||||||
<!-- 模拟左侧导航栏 -->
|
<!-- 模拟左侧导航栏 -->
|
||||||
<!-- <div
|
<!-- <div
|
||||||
class="app-wrapper-btns"
|
class="app-wrapper-btns"
|
||||||
|
|||||||
@@ -3,32 +3,154 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {
|
import { fabric } from "fabric-with-all";
|
||||||
defineComponent,
|
import { ref, watch, onMounted } from "vue";
|
||||||
ref,
|
|
||||||
reactive,
|
|
||||||
nextTick,
|
|
||||||
toRefs,
|
|
||||||
inject,
|
|
||||||
watch,
|
|
||||||
computed,
|
|
||||||
} from "vue";
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
url: { type: String, required: true },
|
url: { type: String, required: true },
|
||||||
positionX: { type: Number, default: 0 },// px
|
offsetX: { type: Number, default: 0 }, // px
|
||||||
positionY: { type: Number, default: 0 },// px
|
offsetY: { type: Number, default: 0 }, // px
|
||||||
angle: { type: Number, default: 0 },// 角度
|
angle: { type: Number, default: 0 }, // 角度
|
||||||
size: { type: Number, default: 100 },// %
|
scale: { type: Number, default: 100 }, // %
|
||||||
gapX: { type: Number, default: 0 },// px
|
gapX: { type: Number, default: 0 }, // px
|
||||||
gapY: { type: Number, default: 0 },// px
|
gapY: { type: Number, default: 0 }, // px
|
||||||
});
|
});
|
||||||
console.log("==========", props);
|
watch(
|
||||||
|
() => props.url,
|
||||||
|
() => getOriginalImage()
|
||||||
|
);
|
||||||
|
watch(
|
||||||
|
() => [
|
||||||
|
props.offsetX,
|
||||||
|
props.offsetY,
|
||||||
|
props.angle,
|
||||||
|
props.scale,
|
||||||
|
props.gapX,
|
||||||
|
props.gapY,
|
||||||
|
],
|
||||||
|
() => setCanvasData()
|
||||||
|
);
|
||||||
|
const el = ref(null);
|
||||||
|
const canvasRef = ref(null);
|
||||||
|
const canvas = ref(null);
|
||||||
|
const observer = ref(null);
|
||||||
|
const id = "asfs123121sfe";
|
||||||
|
onMounted(async () => {
|
||||||
|
initCanvas();
|
||||||
|
await getOriginalImage();
|
||||||
|
setCanvasData();
|
||||||
|
let throttleTimeout = null;
|
||||||
|
let lastRunTime = 0;
|
||||||
|
let trailingTimeout = null;
|
||||||
|
observer.value = new ResizeObserver((entries) => {
|
||||||
|
const now = Date.now();
|
||||||
|
const throttleDelay = 100;
|
||||||
|
if (!throttleTimeout) {
|
||||||
|
updateCanvasSize();
|
||||||
|
lastRunTime = now;
|
||||||
|
throttleTimeout = setTimeout(() => {
|
||||||
|
throttleTimeout = null;
|
||||||
|
}, throttleDelay);
|
||||||
|
} else {
|
||||||
|
clearTimeout(trailingTimeout);
|
||||||
|
trailingTimeout = setTimeout(() => {
|
||||||
|
updateCanvasSize();
|
||||||
|
lastRunTime = Date.now();
|
||||||
|
}, throttleDelay);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
observer.value.observe(el.value);
|
||||||
|
});
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
observer.value.disconnect();
|
||||||
|
});
|
||||||
|
const initCanvas = () => {
|
||||||
|
canvas.value = new fabric.Canvas(canvasRef.value, {
|
||||||
|
selection: false,
|
||||||
|
evented: false,
|
||||||
|
});
|
||||||
|
canvas.value.setWidth(el.value.offsetWidth);
|
||||||
|
canvas.value.setHeight(el.value.offsetHeight);
|
||||||
|
};
|
||||||
|
const updateCanvasSize = () => {
|
||||||
|
canvas.value.setWidth(el.value.offsetWidth);
|
||||||
|
canvas.value.setHeight(el.value.offsetHeight);
|
||||||
|
setCanvasData();
|
||||||
|
};
|
||||||
|
const originalImage = ref(null);
|
||||||
|
const getOriginalImage = () => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
fabric.Image.fromURL(
|
||||||
|
props.url,
|
||||||
|
(object) => {
|
||||||
|
const imgElement = object.getElement();
|
||||||
|
// 创建透明 Canvas
|
||||||
|
const tcanvas = document.createElement("canvas");
|
||||||
|
tcanvas.width = imgElement.width;
|
||||||
|
tcanvas.height = imgElement.height;
|
||||||
|
const ctx = tcanvas.getContext("2d");
|
||||||
|
ctx.clearRect(0, 0, tcanvas.width, tcanvas.height);
|
||||||
|
ctx.drawImage(imgElement, 0, 0);
|
||||||
|
originalImage.value = tcanvas;
|
||||||
|
resolve(tcanvas);
|
||||||
|
},
|
||||||
|
{ crossOrigin: "anonymous" }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const setCanvasData = () => {
|
||||||
|
canvas.value.getObjects().forEach((obj) => {
|
||||||
|
if (obj.id === id) canvas.value.remove(obj);
|
||||||
|
});
|
||||||
|
const image = originalImage.value;
|
||||||
|
const cwidth = canvas.value.width;
|
||||||
|
const cheight = canvas.value.height;
|
||||||
|
const offsetX = props.offsetX;
|
||||||
|
const offsetY = props.offsetY;
|
||||||
|
const scaleX = ((cwidth / image.width) * (props.scale / 100)) / 5;
|
||||||
|
const scaleY = ((cheight / image.height) * (props.scale / 100)) / 5;
|
||||||
|
const scale = cwidth > cheight ? scaleX : scaleY;
|
||||||
|
const angle = props.angle;
|
||||||
|
const gapX = props.gapX;
|
||||||
|
const gapY = props.gapY;
|
||||||
|
const patternTransform = fabric.util.composeMatrix({
|
||||||
|
scaleX: scale,
|
||||||
|
scaleY: scale,
|
||||||
|
angle: angle,
|
||||||
|
});
|
||||||
|
// 创建透明 Canvas
|
||||||
|
const tcanvas = document.createElement("canvas");
|
||||||
|
tcanvas.width = image.width + gapX;
|
||||||
|
tcanvas.height = image.height + gapY;
|
||||||
|
const ctx = tcanvas.getContext("2d");
|
||||||
|
ctx.clearRect(0, 0, tcanvas.width, tcanvas.height);
|
||||||
|
ctx.drawImage(image, 0, 0);
|
||||||
|
const pattern = new fabric.Pattern({
|
||||||
|
source: tcanvas,
|
||||||
|
repeat: "repeat",
|
||||||
|
patternTransform,
|
||||||
|
offsetX, // 水平偏移
|
||||||
|
offsetY, // 垂直偏移
|
||||||
|
});
|
||||||
|
const rect = new fabric.Rect({
|
||||||
|
id,
|
||||||
|
width: cwidth,
|
||||||
|
height: cheight,
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
// scaleX: 1,
|
||||||
|
// scaleY: 1,
|
||||||
|
fill: pattern,
|
||||||
|
evented: false,
|
||||||
|
selectable: false,
|
||||||
|
});
|
||||||
|
canvas.value.add(rect);
|
||||||
|
canvas.value.renderAll();
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang='less' scoped>
|
<style lang='less' scoped>
|
||||||
.pingpu {
|
.pingpu {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: #f00;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -1,54 +1,73 @@
|
|||||||
<template>
|
<template>
|
||||||
<div ref="modalTest"></div>
|
<div class="test">
|
||||||
<a-modal class="modal_test generalModel"
|
<div class="control">
|
||||||
v-model:visible="testModal"
|
<div>
|
||||||
:footer="null"
|
<span>偏移X</span>
|
||||||
:get-container="() => $refs.modalTest"
|
<input type="number" v-model="data.offsetX" />
|
||||||
width="78%"
|
</div>
|
||||||
:maskClosable="false"
|
<div>
|
||||||
:centered="true"
|
<span>偏移Y</span>
|
||||||
:closable="false"
|
<input type="number" v-model="data.offsetY" />
|
||||||
wrapClassName="#app"
|
</div>
|
||||||
:keyboard="false"
|
<div>
|
||||||
>
|
<span>角度</span>
|
||||||
<div class="generalModel_btn">
|
<input type="number" v-model="data.angle" />
|
||||||
<div class="generalModel_closeIcon" @click.stop="cancelDsign()">
|
</div>
|
||||||
<svg width="100%" height="100%" viewBox="0 0 46 46" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<div>
|
||||||
<circle cx="23" cy="23" r="23" fill="#000" fill-opacity="0.3"/>
|
<span>缩放</span>
|
||||||
<rect x="32.5063" y="12" width="3" height="29" rx="1.5" transform="rotate(45 32.5063 12)" fill="white"/>
|
<input type="number" v-model="data.scale" />
|
||||||
<rect x="34.6274" y="32.5059" width="3" height="29" rx="1.5" transform="rotate(135 34.6274 32.5059)" fill="white"/>
|
</div>
|
||||||
</svg>
|
<div>
|
||||||
|
<span>水平间距</span>
|
||||||
|
<input type="number" v-model="data.gapX" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span>垂直间距</span>
|
||||||
|
<input type="number" v-model="data.gapY" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<canvasIndex></canvasIndex>
|
<div class="box">
|
||||||
</a-modal>
|
<pingpu v-bind="data" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import { defineComponent,ref,createVNode,nextTick} from 'vue'
|
import pingpu from "./pingpu.vue";
|
||||||
import canvasIndex from './index.vue'
|
const data = ref({
|
||||||
export default defineComponent({
|
url: "/src/assets/images/canvas/yinhua1.jpg",
|
||||||
components:{canvasIndex},
|
offsetX: 0, // px
|
||||||
setup(){
|
offsetY: 0, // px
|
||||||
let testModal = ref(true)
|
angle: 0, // 角度
|
||||||
const init = ()=>{
|
scale: 100,// %
|
||||||
testModal.value = true
|
gapX: 0, // px
|
||||||
}
|
gapY: 0, // px
|
||||||
const cancelDsign = ()=>{
|
|
||||||
testModal.value = false
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
testModal,
|
|
||||||
init,
|
|
||||||
cancelDsign,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
window.data = data;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang='less' scoped>
|
<style lang='less' scoped>
|
||||||
.box {
|
.test {
|
||||||
border: 1px solid #f00;
|
> .control {
|
||||||
}
|
margin-left: 10px;
|
||||||
|
margin-top: 10px;
|
||||||
|
> div {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
> span {
|
||||||
|
width: 80px;
|
||||||
|
}
|
||||||
|
>input{
|
||||||
|
padding-left: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
> .box {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 400px;
|
||||||
|
height: 500px;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class='box'>
|
<tesst></tesst>
|
||||||
<tesst></tesst>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -16,7 +14,4 @@ export default defineComponent({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang='less' scoped>
|
<style lang='less' scoped>
|
||||||
.box {
|
|
||||||
border: 1px solid #f00;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
Reference in New Issue
Block a user