WebView: click an image to view/zoom it

This commit is contained in:
Le Tan 2018-06-30 22:16:51 +08:00
parent 15151742c9
commit 4df0d03baa
9 changed files with 228 additions and 2 deletions

View File

@ -20,6 +20,7 @@ var updateHtml = function(html) {
contentDiv.innerHTML = html; contentDiv.innerHTML = html;
insertImageCaption(); insertImageCaption();
setupImageView();
var codes = document.getElementsByTagName('code'); var codes = document.getElementsByTagName('code');
mermaidIdx = 0; mermaidIdx = 0;

View File

@ -138,6 +138,7 @@ var updateText = function(text) {
contentDiv.innerHTML = html; contentDiv.innerHTML = html;
handleToc(needToc); handleToc(needToc);
insertImageCaption(); insertImageCaption();
setupImageView();
handleMetaData(); handleMetaData();
renderMermaid('lang-mermaid'); renderMermaid('lang-mermaid');
renderFlowchart(['lang-flowchart', 'lang-flow']); renderFlowchart(['lang-flowchart', 'lang-flow']);

View File

@ -21,17 +21,24 @@
} }
</style> </style>
<link rel="stylesheet" type="text/css" href="qrc:/resources/view_image.css">
<link rel="stylesheet" type="text/css" href="CSS_PLACE_HOLDER"> <link rel="stylesheet" type="text/css" href="CSS_PLACE_HOLDER">
<link rel="stylesheet" type="text/css" href="HIGHLIGHTJS_CSS_PLACE_HOLDER"> <link rel="stylesheet" type="text/css" href="HIGHLIGHTJS_CSS_PLACE_HOLDER">
<script src="qrc:/resources/qwebchannel.js"></script> <script src="qrc:/resources/qwebchannel.js"></script>
<script src="qrc:/utils/highlightjs/highlight.pack.js"></script> <script src="qrc:/utils/highlightjs/highlight.pack.js"></script>
<!-- EXTRA_PLACE_HOLDER --> <!-- EXTRA_PLACE_HOLDER -->
<script src="JS_PLACE_HOLDER" defer></script> <script src="JS_PLACE_HOLDER" defer></script>
<script src="qrc:/resources/view_image.js" defer></script>
<script src="qrc:/resources/markdown_template.js" defer></script> <script src="qrc:/resources/markdown_template.js" defer></script>
</head> </head>
<body> <body>
<div id="content-div"></div> <div id="content-div"></div>
<div id="image-view-div" class="modal-box">
<span id="image-view-close" class="modal-close">&times;</span>
<img id="image-view" class="modal-content">
</div>
<div id="preview-div" style="display:none;"></div> <div id="preview-div" style="display:none;"></div>
<div id="inplace-preview-div" style="display:none;"></div> <div id="inplace-preview-div" style="display:none;"></div>

View File

@ -854,7 +854,7 @@ var insertImageCaption = function() {
captionDiv.textContent = img.alt; captionDiv.textContent = img.alt;
img.insertAdjacentElement('afterend', captionDiv); img.insertAdjacentElement('afterend', captionDiv);
} }
} };
var asyncJobsCount = 0; var asyncJobsCount = 0;
@ -1005,7 +1005,8 @@ window.onmousedown = function(e) {
// Left button and Ctrl key. // Left button and Ctrl key.
if (e.buttons == 1 if (e.buttons == 1
&& isCtrl && isCtrl
&& window.getSelection().type != 'Range') { && window.getSelection().type != 'Range'
&& !isViewingImage()) {
vds_oriMouseClientX = e.clientX; vds_oriMouseClientX = e.clientX;
vds_oriMouseClientY = e.clientY; vds_oriMouseClientY = e.clientY;
vds_readyToScroll = true; vds_readyToScroll = true;

View File

@ -58,6 +58,7 @@ var updateText = function(text) {
contentDiv.innerHTML = html; contentDiv.innerHTML = html;
handleToc(needToc); handleToc(needToc);
insertImageCaption(); insertImageCaption();
setupImageView();
renderMermaid('lang-mermaid'); renderMermaid('lang-mermaid');
renderFlowchart(['lang-flowchart', 'lang-flow']); renderFlowchart(['lang-flowchart', 'lang-flow']);
renderPlantUML('lang-puml'); renderPlantUML('lang-puml');

View File

@ -97,6 +97,7 @@ var updateText = function(text) {
contentDiv.innerHTML = html; contentDiv.innerHTML = html;
handleToc(needToc); handleToc(needToc);
insertImageCaption(); insertImageCaption();
setupImageView();
highlightCodeBlocks(document, highlightCodeBlocks(document,
VEnableMermaid, VEnableMermaid,
VEnableFlowchart, VEnableFlowchart,

View File

@ -0,0 +1,63 @@
.view-image {
cursor: pointer;
transition: 0.3s;
}
.modal-box {
display: none;
position: fixed;
z-index: 1000;
padding-top: 50px;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: hidden;
background-color: rgb(68, 68, 68);
background-color: rgba(68, 68, 68, 0.9);
}
.modal-content {
margin: auto;
display: block;
width: auto;
height: auto;
cursor: move;
}
/* Add Animation */
.modal-content {
-webkit-animation-name: zoom;
-webkit-animation-duration: 0.6s;
animation-name: zoom;
animation-duration: 0.6s;
}
@-webkit-keyframes zoom {
from {-webkit-transform:scale(0)}
to {-webkit-transform:scale(1)}
}
@keyframes zoom {
from {transform:scale(0)}
to {transform:scale(1)}
}
/* The Close Button */
span.modal-close {
position: absolute;
z-index: 1000;
top: 15px;
right: 35px;
color: #DADADA;
font-size: 40px;
font-weight: bold;
transition: 0.3s;
}
span.modal-close:hover,
span.modal-close:focus {
color: #EEEEEE;
text-decoration: none;
cursor: pointer;
}

149
src/resources/view_image.js Normal file
View File

@ -0,0 +1,149 @@
var imageViewDiv = document.getElementById('image-view-div');
var viewImage = function(obj, image) {
image = !image ? obj.src : image;
imageViewDiv.style.display = 'block';
var boxImage = document.getElementById('image-view');
boxImage.src = image;
// Restore image-view.
boxImage.style.width = '';
boxImage.style.position = '';
boxImage.style.zIndex = '';
};
var viewBoxImageMouseDown = false;
var viewBoxImageOffsetToMouse = [0, 0];
var closeImageViewBox = function() {
imageViewDiv.style.display = "none";
};
var initImageViewBox = function() {
// Left and top in pixel.
var moveImage = function(img, left, top) {
if (img.style.position != 'absolute') {
img.style.position = 'absolute';
img.style.zIndex = parseInt(document.getElementById('image-view-close').style.zIndex) - 1;
}
img.style.left = left + 'px';
img.style.top = top + 'px';
};
// View box.
imageViewDiv.onclick = function(e) {
e = e || window.event;
var boxImage = document.getElementById('image-view');
if (e.target.id != boxImage.id) {
// Click outside the image to close the box.
closeImageViewBox();
}
e.preventDefault();
};
imageViewDiv.onwheel = function(e) {
e = e || window.event;
var ctrl = !!e.ctrlKey;
if (ctrl) {
return;
}
var target = e.target;
if (!target || target.id != 'image-view') {
return;
}
var rect = target.getBoundingClientRect();
var centerX = e.clientX - rect.left;
var centerY = e.clientY - rect.top;
var oriWidth = target.getAttribute('oriWidth');
var oriHeight = target.getAttribute('oriWidth');
if (!oriWidth) {
oriWidth = rect.width;
oriHeight = rect.height;
target.setAttribute('oriWidth', oriWidth);
target.setAttribute('oriHeight', oriHeight);
}
var step = Math.floor(oriWidth / 4);
var value = e.wheelDelta || -e.detail;
// delta >= 0 is up, which will trigger zoom in.
var delta = Math.max(-1, Math.min(1, value));
var newWidth = rect.width + (delta < 0 ? -step : step);
if (newWidth < 200) {
e.preventDefault();
return;
}
var factor = newWidth / rect.width;
target.style.width = newWidth + 'px';
// Adjust the image around the center point.
moveImage(target, e.clientX - centerX * factor, e.clientY - centerY * factor);
e.preventDefault();
};
// Content image.
var boxImage = document.getElementById('image-view');
boxImage.onmousedown = function(e) {
e = e || window.event;
var target = this || e.target;
viewBoxImageMouseDown = true;
viewBoxImageOffsetToMouse = [
target.offsetLeft - e.clientX,
target.offsetTop - e.clientY
];
e.preventDefault();
};
boxImage.onmouseup = function(e) {
e = e || window.event;
viewBoxImageMouseDown = false;
e.preventDefault();
};
boxImage.onmousemove = function(e) {
e = e || window.event;
var target = this || e.target;
if (viewBoxImageMouseDown) {
moveImage(target, e.clientX + viewBoxImageOffsetToMouse[0], e.clientY + viewBoxImageOffsetToMouse[1]);
}
e.preventDefault();
};
// Close button.
document.getElementById('image-view-close').onclick = closeImageViewBox;
};
initImageViewBox();
var setupImageView = function() {
closeImageViewBox();
var imgs = document.getElementsByTagName('img');
for (var i = 0; i < imgs.length; ++i) {
var img = imgs[i];
if (img.id == 'image-view') {
continue;
}
img.classList.add('view-image');
img.onclick = function() {
viewImage(this, this.src);
};
}
};
var isViewingImage = function() {
return imageViewDiv.style.display == 'block';
};

View File

@ -261,5 +261,7 @@
<file>resources/icons/tags.svg</file> <file>resources/icons/tags.svg</file>
<file>resources/icons/tag_explorer.svg</file> <file>resources/icons/tag_explorer.svg</file>
<file>resources/icons/tag.svg</file> <file>resources/icons/tag.svg</file>
<file>resources/view_image.js</file>
<file>resources/view_image.css</file>
</qresource> </qresource>
</RCC> </RCC>