Match aspect ratio from frame to template or vice versa, or lock

template to frame
pull/437/head
Dan Collins 3 weeks ago committed by Mike Lang
parent 2c5e1058e8
commit 3c746e569e

@ -267,7 +267,7 @@
Update Source Images
</button>
<br/>
<div class="video-info-thumbnail-advanced-crop-flex-wrapper">
<div class="video-info-thumbnail-advanced-crop-flex-item">
<img
@ -285,7 +285,31 @@
<input type="text" class="video-info-thumbnail-position" id="video-info-thumbnail-crop-3" />
<br/>
</div>
<div class="video-info-thumbnail-advanced-crop-flex-item hidden" id="video-info-thumbnail-aspect-ratio-controls">
<div class="video-info-thumbnail-advanced-crop-flex-column">
<div>
Aspect Ratio
</div>
<div>
<button id="video-info-thumbnail-aspect-ratio-match-right">
--Match-&gt;
</button>
</div>
<div>
<button id="video-info-thumbnail-aspect-ratio-match-left">
&lt;-Match--
</button>
</div>
<div>
<label>
<input type="checkbox" id="video-info-thumbnail-lock-aspect-ratio">
Lock
</label>
</div>
</div>
</div>
<div class="video-info-thumbnail-advanced-crop-flex-item">
<img
id="video-info-thumbnail-template-overlay-image"
@ -303,6 +327,7 @@
<br/>
</div>
</div>
</details>
</div>
<div

@ -290,6 +290,9 @@ window.addEventListener("DOMContentLoaded", async (event) => {
templateImageElement.src = `/thrimshim/template/${imageTemplate}.png`;
templateImageElement.classList.remove("hidden");
const aspectRatioControls = document.getElementById("video-info-thumbnail-aspect-ratio-controls");
aspectRatioControls.classList.remove("hidden");
createTemplateCropWidgets();
});
@ -302,6 +305,36 @@ window.addEventListener("DOMContentLoaded", async (event) => {
document.getElementById("video-info-thumbnail-location-2").addEventListener("input", updateTemplateCropWidgets);
document.getElementById("video-info-thumbnail-location-3").addEventListener("input", updateTemplateCropWidgets);
document.getElementById("video-info-thumbnail-lock-aspect-ratio").addEventListener("change", updateTemplateCropAspectRatio);
document.getElementById("video-info-thumbnail-aspect-ratio-match-right").addEventListener("click", function(){
// Calculate and copy the aspect ratio from the video field to the template
const videoFieldX1 = document.getElementById("video-info-thumbnail-crop-0");
const videoFieldY1 = document.getElementById("video-info-thumbnail-crop-1");
const videoFieldX2 = document.getElementById("video-info-thumbnail-crop-2");
const videoFieldY2 = document.getElementById("video-info-thumbnail-crop-3");
const videoFieldAspectRatio = (videoFieldX2.value-videoFieldX1.value)/(videoFieldY2.value-videoFieldY1.value);
templateStage.setOptions({aspectRatio: videoFieldAspectRatio});
// Re-apply the locked/unlocked status
updateTemplateCropAspectRatio();
});
document.getElementById("video-info-thumbnail-aspect-ratio-match-left").addEventListener("click", function(){
// Calculate and copy the aspect ratio from the template to the video field
const templateFieldX1 = document.getElementById("video-info-thumbnail-location-0");
const templateFieldY1 = document.getElementById("video-info-thumbnail-location-1");
const templateFieldX2 = document.getElementById("video-info-thumbnail-location-2");
const templateFieldY2 = document.getElementById("video-info-thumbnail-location-3");
const templateFieldAspectRatio = (templateFieldX2.value-templateFieldX1.value)/(templateFieldY2.value-templateFieldY1.value);
videoFrameStage.setOptions({aspectRatio: templateFieldAspectRatio});
// Re-apply the locked/unlocked status
updateTemplateCropAspectRatio();
});
document
.getElementById("video-info-thumbnail-template-preview-generate")
.addEventListener("click", async (_event) => {
@ -2214,29 +2247,37 @@ function createTemplateCropWidgets() {
const fieldX2 = document.getElementById("video-info-thumbnail-crop-2");
const fieldY2 = document.getElementById("video-info-thumbnail-crop-3");
// 640x320 -> 1920x1080
fieldX1.value = pos.x*3;
fieldY1.value = pos.y*3;
fieldX2.value = (pos.x+pos.w)*3;
fieldY2.value = (pos.y+pos.h)*3;
fieldX1.value = Math.round(pos.x*3);
fieldY1.value = Math.round(pos.y*3);
fieldX2.value = Math.round((pos.x+pos.w)*3);
fieldY2.value = Math.round((pos.y+pos.h)*3);
});
videoFrameStage.listen('crop.change',function(widget,e){
// This only fires when the user is finished dragging, not every time the size
// of the cropped area updates. This avoids the template area updating every
// instant due to minute changes in the aspect ratio, which causes it to shrink
// while resizing.
updateTemplateCropAspectRatio();
});
}
if (templateStage == null) {
templateStage = Jcrop.attach('video-info-thumbnail-template-overlay-image');
templateStage.listen('crop.change',function(widget,e){
templateStage.listen('crop.update',function(widget,e){
const pos = widget.pos;
const fieldX1 = document.getElementById("video-info-thumbnail-location-0");
const fieldY1 = document.getElementById("video-info-thumbnail-location-1");
const fieldX2 = document.getElementById("video-info-thumbnail-location-2");
const fieldY2 = document.getElementById("video-info-thumbnail-location-3");
// 640x320 -> 1280x720
fieldX1.value = pos.x*2;
fieldY1.value = pos.y*2;
fieldX2.value = (pos.x+pos.w)*2;
fieldY2.value = (pos.y+pos.h)*2;
fieldX1.value = Math.round(pos.x*2);
fieldY1.value = Math.round(pos.y*2);
fieldX2.value = Math.round((pos.x+pos.w)*2);
fieldY2.value = Math.round((pos.y+pos.h)*2);
});
}
updateTemplateCropWidgets();
updateTemplateCropAspectRatio();
}
/**
@ -2269,4 +2310,22 @@ function updateTemplateCropWidgets() {
templateStage.active.pos = templateRect;
templateStage.active.render();
}
updateTemplateCropAspectRatio();
}
function updateTemplateCropAspectRatio() {
const aspectRatioCheckbox = document.getElementById("video-info-thumbnail-lock-aspect-ratio");
if (aspectRatioCheckbox.checked) {
const videoFieldX1 = document.getElementById("video-info-thumbnail-crop-0");
const videoFieldY1 = document.getElementById("video-info-thumbnail-crop-1");
const videoFieldX2 = document.getElementById("video-info-thumbnail-crop-2");
const videoFieldY2 = document.getElementById("video-info-thumbnail-crop-3");
const videoFieldAspectRatio = (videoFieldX2.value-videoFieldX1.value)/(videoFieldY2.value-videoFieldY1.value);
videoFrameStage.setOptions({aspectRatio: videoFieldAspectRatio});
templateStage.setOptions({aspectRatio: videoFieldAspectRatio});
} else {
videoFrameStage.setOptions({aspectRatio: null});
templateStage.setOptions({aspectRatio: null});
}
}

@ -381,6 +381,18 @@ input.range-definition-chapter-marker-description {
.video-info-thumbnail-advanced-crop-flex-wrapper {
display: flex;
align-items: center;
}
.video-info-thumbnail-advanced-crop-flex-column {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.video-info-thumbnail-advanced-crop-flex-column div {
margin: 0.5em;
}
.submission-response-error {

Loading…
Cancel
Save