Files
koodo-reader/src/components/imageViewer/component.tsx
troyeguo 7e51cd4dde fix bug
Former-commit-id: 684228395a8b8c403fbb1b227fb25a75602067d9
2021-11-27 18:29:39 +08:00

217 lines
6.2 KiB
TypeScript

import React from "react";
import "./imageViewer.css";
import { ImageViewerProps, ImageViewerStates } from "./interface";
import StyleUtil from "../../utils/readUtils/styleUtil";
import FileSaver from "file-saver";
import { isElectron } from "react-device-detect";
declare var window: any;
class ImageViewer extends React.Component<ImageViewerProps, ImageViewerStates> {
constructor(props: ImageViewerProps) {
super(props);
this.state = {
isShowImage: false,
imageRatio: "horizontal",
zoomIndex: 0,
rotateIndex: 0,
};
}
componentDidMount() {
console.log(this.props.rendition);
this.props.rendition.on("rendered", () => {
let iframe = document.getElementsByTagName("iframe")[0];
if (!iframe) return;
let doc = iframe.contentDocument;
if (!doc) {
return;
}
StyleUtil.addDefaultCss();
doc.addEventListener("click", this.showImage, false);
});
}
showImage = (event: any) => {
if (this.props.isShow) {
this.props.handleLeaveReader("left");
this.props.handleLeaveReader("right");
this.props.handleLeaveReader("top");
this.props.handleLeaveReader("bottom");
}
let href;
if (
event.target &&
event.target.parentNode &&
event.target.parentNode.parentNode
) {
href =
(event.target.innerText.indexOf("http") > -1 &&
event.target.innerText) ||
event.target.src ||
event.target.href ||
event.target.parentNode.href ||
event.target.parentNode.parentNode.href ||
"";
}
if (
href &&
href.indexOf("http") === 0 &&
href.indexOf("OEBPF") === -1 &&
href.indexOf("OEBPS") === -1 &&
href.indexOf("footnote") === -1 &&
href.indexOf("blob") === -1 &&
href.indexOf("data:application") === -1 &&
href.indexOf(".htm") === -1
) {
event.preventDefault();
if (isElectron) {
const { shell } = window.require("electron");
shell.openExternal(href);
} else {
window.open(href);
}
}
if (!event.target.src) {
return;
}
if (this.state.isShowImage) {
this.setState({
isShowImage: false,
zoomIndex: 0,
rotateIndex: 0,
imageRatio: "horizontal",
});
}
event.preventDefault();
const handleDirection = (direction: string) => {
this.setState({ imageRatio: direction });
};
var img = new Image();
img.addEventListener("load", function () {
handleDirection(
this.naturalWidth / this.naturalHeight > 1 ? "horizontal" : "vertical"
);
});
img.src = event.target.src;
let image: HTMLImageElement | null = document.querySelector(".image");
if (image) {
image.src = event.target.src;
this.setState({ isShowImage: true });
}
};
hideImage = (event: any) => {
event.preventDefault();
if (event.target.src) {
let image: HTMLImageElement | null = document.querySelector(".image");
if (image) image.src = "";
}
this.setState({ isShowImage: false });
};
handleZoomIn = () => {
let image: any = document.querySelector(".image");
if (image.style.width === "200vw" || image.style.height === "200vh") return;
this.setState({ zoomIndex: this.state.zoomIndex + 1 }, () => {
if (this.state.imageRatio === "horizontal") {
image.style.width = `${60 + this.state.zoomIndex * 10}vw`;
} else {
image.style.height = `${90 + 10 * this.state.zoomIndex}vh`;
}
});
};
handleZoomOut = () => {
let image: any = document.querySelector(".image");
if (image.style.width === "10vw" || image.style.height === "10vh") return;
this.setState({ zoomIndex: this.state.zoomIndex - 1 }, () => {
if (this.state.imageRatio === "horizontal") {
image.style.width = `${60 + this.state.zoomIndex * 10}vw`;
} else {
image.style.height = `${90 + 10 * this.state.zoomIndex}vh`;
}
});
};
handleSave = async () => {
let image: any = document.querySelector(".image");
let blob = await fetch(image.src).then((r) => r.blob());
FileSaver.saveAs(blob, `${new Date().toLocaleDateString()}`);
};
handleClock = () => {
let image: any = document.querySelector(".image");
this.setState({ rotateIndex: this.state.rotateIndex + 1 }, () => {
image.style.transform = `rotate(${this.state.rotateIndex * 90}deg)`;
});
};
handleCounterClock = () => {
let image: any = document.querySelector(".image");
this.setState({ rotateIndex: this.state.rotateIndex - 1 }, () => {
image.style.transform = `rotate(${this.state.rotateIndex * 90}deg)`;
});
};
render() {
return (
<div
className="image-preview"
style={this.state.isShowImage ? {} : { display: "none" }}
>
<div
className="image-background"
style={
this.state.isShowImage
? { backgroundColor: "rgba(75,75,75,0.3)" }
: {}
}
onClick={(event) => {
this.hideImage(event);
}}
></div>
<img
src=""
alt=""
className="image"
style={
this.state.imageRatio === "horizontal"
? { width: "60vw" }
: { height: "90vh" }
}
/>
<div className="image-operation">
<span
className="icon-zoom-in zoom-in-icon"
onClick={() => {
this.handleZoomIn();
}}
></span>
<span
className="icon-zoom-out zoom-out-icon"
onClick={() => {
this.handleZoomOut();
}}
></span>
<span
className="icon-save save-icon"
onClick={() => {
this.handleSave();
}}
></span>
<span
className="icon-clockwise clockwise-icon"
onClick={() => {
this.handleClock();
}}
></span>
<span
className="icon-counterclockwise counterclockwise-icon"
onClick={() => {
this.handleCounterClock();
}}
></span>
</div>
</div>
);
}
}
export default ImageViewer;