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

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

@ -286,6 +286,30 @@
<br/> <br/>
</div> </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"> <div class="video-info-thumbnail-advanced-crop-flex-item">
<img <img
id="video-info-thumbnail-template-overlay-image" id="video-info-thumbnail-template-overlay-image"
@ -303,6 +327,7 @@
<br/> <br/>
</div> </div>
</div> </div>
</details> </details>
</div> </div>
<div <div

@ -290,6 +290,9 @@ window.addEventListener("DOMContentLoaded", async (event) => {
templateImageElement.src = `/thrimshim/template/${imageTemplate}.png`; templateImageElement.src = `/thrimshim/template/${imageTemplate}.png`;
templateImageElement.classList.remove("hidden"); templateImageElement.classList.remove("hidden");
const aspectRatioControls = document.getElementById("video-info-thumbnail-aspect-ratio-controls");
aspectRatioControls.classList.remove("hidden");
createTemplateCropWidgets(); 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-2").addEventListener("input", updateTemplateCropWidgets);
document.getElementById("video-info-thumbnail-location-3").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 document
.getElementById("video-info-thumbnail-template-preview-generate") .getElementById("video-info-thumbnail-template-preview-generate")
.addEventListener("click", async (_event) => { .addEventListener("click", async (_event) => {
@ -2214,29 +2247,37 @@ function createTemplateCropWidgets() {
const fieldX2 = document.getElementById("video-info-thumbnail-crop-2"); const fieldX2 = document.getElementById("video-info-thumbnail-crop-2");
const fieldY2 = document.getElementById("video-info-thumbnail-crop-3"); const fieldY2 = document.getElementById("video-info-thumbnail-crop-3");
// 640x320 -> 1920x1080 // 640x320 -> 1920x1080
fieldX1.value = pos.x*3; fieldX1.value = Math.round(pos.x*3);
fieldY1.value = pos.y*3; fieldY1.value = Math.round(pos.y*3);
fieldX2.value = (pos.x+pos.w)*3; fieldX2.value = Math.round((pos.x+pos.w)*3);
fieldY2.value = (pos.y+pos.h)*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) { if (templateStage == null) {
templateStage = Jcrop.attach('video-info-thumbnail-template-overlay-image'); 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 pos = widget.pos;
const fieldX1 = document.getElementById("video-info-thumbnail-location-0"); const fieldX1 = document.getElementById("video-info-thumbnail-location-0");
const fieldY1 = document.getElementById("video-info-thumbnail-location-1"); const fieldY1 = document.getElementById("video-info-thumbnail-location-1");
const fieldX2 = document.getElementById("video-info-thumbnail-location-2"); const fieldX2 = document.getElementById("video-info-thumbnail-location-2");
const fieldY2 = document.getElementById("video-info-thumbnail-location-3"); const fieldY2 = document.getElementById("video-info-thumbnail-location-3");
// 640x320 -> 1280x720 // 640x320 -> 1280x720
fieldX1.value = pos.x*2; fieldX1.value = Math.round(pos.x*2);
fieldY1.value = pos.y*2; fieldY1.value = Math.round(pos.y*2);
fieldX2.value = (pos.x+pos.w)*2; fieldX2.value = Math.round((pos.x+pos.w)*2);
fieldY2.value = (pos.y+pos.h)*2; fieldY2.value = Math.round((pos.y+pos.h)*2);
}); });
} }
updateTemplateCropWidgets(); updateTemplateCropWidgets();
updateTemplateCropAspectRatio();
} }
/** /**
@ -2269,4 +2310,22 @@ function updateTemplateCropWidgets() {
templateStage.active.pos = templateRect; templateStage.active.pos = templateRect;
templateStage.active.render(); 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 { .video-info-thumbnail-advanced-crop-flex-wrapper {
display: flex; 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 { .submission-response-error {

Loading…
Cancel
Save