123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- <template>
- <el-button
- v-if="contentType === 'button'"
- :type="btnType"
- :link="isLink"
- @click="showPdf"
- >
- {{ btnText }}
- </el-button>
- <VuePdfEmbed
- v-else
- :source="{ url: pdfSource, cMapUrl: '/cmaps/', cMapPacked: true }"
- :page="pageNumber"
- annotation-layer
- text-layer
- @click="showPdf"
- />
- <el-drawer
- v-if="needToShowPdf"
- v-model="visible"
- :footer="false"
- :header="false"
- :show-close="false"
- destroy-on-close
- direction="rtl"
- :append-to-body="true"
- size="60%"
- >
- <VuePdfEmbed
- v-if="needToShowPdf"
- :source="{
- url: pdfSource,
- cMapUrl: '/cmaps/',
- cMapPacked: true,
- }"
- :page="showPdfNumber"
- @rendered="rendered"
- annotation-layer
- text-layer
- />
- </el-drawer>
- </template>
- <script setup>
- import VuePdfEmbed from "vue-pdf-embed";
- // either URL, Base64, binary, or document proxy
- const props = defineProps({
- pdfSource: {
- type: String,
- required: true,
- },
- pageNumber: {
- type: Number,
- default: 0,
- },
- needToShowPdf: {
- type: Boolean,
- default: false,
- },
- contentType: {
- type: String,
- default: "pdf",
- },
- btnText: {
- type: String,
- default: "预览",
- },
- btnType: {
- type: String,
- default: "primary",
- },
- isLink: {
- type: Boolean,
- default: false,
- },
- showPdfNumber: {
- type: Number,
- default: 0,
- },
- });
- const visible = ref(false);
- const showPdf = () => {
- visible.value = true;
- };
- const rendered = () => {
- const clickableElementsA = document.querySelectorAll(
- ".el-drawer__body .vue-pdf-embed div"
- );
- const clickableElements = document.querySelectorAll(
- ".el-drawer__body .vue-pdf-embed .vue-pdf-embed__page"
- );
- clickableElementsA.forEach((element) => {
- element.style.display = "flex";
- element.style.alignItems = "center";
- element.style.justifyContent = "center";
- });
- clickableElements.forEach((element, index) => {
- let rotationAngle = 0;
- element.addEventListener("click", () => {
- const currentWidth = element.offsetWidth;
- const currentHeight = element.offsetHeight;
- const parent = element.parentNode;
- let distance = 0;
- if (currentHeight > currentWidth) {
- distance = currentHeight - currentWidth;
- } else {
- element.style.width = `${currentHeight}px`;
- element.style.height = `${currentWidth}px`;
- }
- rotationAngle = (rotationAngle + 90) % 360;
- if (rotationAngle == 0) {
- if (distance > 0) {
- element.style.transform = `rotate(${rotationAngle}deg) `;
- element.firstElementChild.style.transform = `translateY(0px) `;
- } else {
- element.style.transform = `rotate(${rotationAngle}deg) `;
- element.firstElementChild.style.transform = `translateY(0px) `;
- }
- }
- if (rotationAngle == 90) {
- if (distance > 0) {
- element.style.transform = `rotate(${rotationAngle}deg)`;
- element.firstElementChild.style.transform = `translateY(-${distance / 2}px) `;
- } else {
- element.style.transform = `rotate(${rotationAngle}deg)`;
- element.firstElementChild.style.transform = `translateY(0px) `;
- }
- }
- if (rotationAngle === 180) {
- if (distance > 0) {
- element.style.transform = `rotate(${rotationAngle}deg) `;
- element.firstElementChild.style.transform = `translateY(0px) `;
- } else {
- element.style.transform = `rotate(${rotationAngle}deg) `;
- element.firstElementChild.style.transform = `translateY(0px) `;
- }
- }
- if (rotationAngle === 270) {
- if (distance > 0) {
- element.style.transform = `rotate(${rotationAngle}deg) `;
- element.firstElementChild.style.transform = `translateY(${distance / 2}px) `;
- } else {
- element.style.transform = `rotate(${rotationAngle}deg) `;
- element.firstElementChild.style.transform = `translateY(0px) `;
- }
- }
- parent.style.width = `${currentWidth}px`;
- parent.style.height = `${currentHeight}px`;
- });
- element.addEventListener("wheel", function (event) {
- const currentWidth = element.offsetWidth;
- const currentHeight = element.offsetHeight;
- const parent = element.parentNode;
- if (event.ctrlKey) {
- event.preventDefault();
- // 获取当前的transform值并解析
- const transform = getComputedStyle(element).transform;
- let scale = 1,
- rotate = 0;
- if (transform && transform !== "none") {
- const transformMatrix = new WebKitCSSMatrix(transform);
- scale = Math.sqrt(
- Math.pow(transformMatrix.a, 2) + Math.pow(transformMatrix.b, 2)
- );
- rotate =
- Math.atan2(transformMatrix.b, transformMatrix.a) * (180 / Math.PI);
- }
- // 根据滚轮方向调整缩放级别
- if (event.deltaY < 0) {
- // 向上滚动,放大
- scale += 0.1;
- } else {
- // 向下滚动,缩小
- scale -= 0.1;
- }
- // 确保缩放级别不会变成负数或过小
- scale = Math.max(0.1, Math.min(scale, 5));
- // 应用新的缩放级别和原有的旋转角度
- element.style.transform = `scale(${scale}) rotate(${rotate}deg)`;
- //同步放大展示盒子
- parent.style.width = `${currentWidth * scale}px`;
- parent.style.height = `${currentHeight * scale}px`;
- }
- });
- });
- };
- </script>
- <style lang="scss" scoped></style>
|