mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 22:09:52 +08:00
WebView: click an image to view/zoom it
This commit is contained in:
parent
15151742c9
commit
4df0d03baa
@ -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;
|
||||||
|
@ -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']);
|
||||||
|
@ -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">×</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>
|
||||||
|
@ -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;
|
||||||
|
@ -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');
|
||||||
|
@ -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,
|
||||||
|
63
src/resources/view_image.css
Normal file
63
src/resources/view_image.css
Normal 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
149
src/resources/view_image.js
Normal 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';
|
||||||
|
};
|
@ -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>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user