custom aspect ratio for composition

This commit is contained in:
jr-k 2024-08-27 03:06:55 +02:00
parent 236b9324f5
commit 0830af4f56
6 changed files with 112 additions and 68 deletions

View File

@ -1,25 +1,31 @@
jQuery(document).ready(function ($) { jQuery(document).ready(function ($) {
const contentData = JSON.parse($('#content-edit-location').val() || '{"layers":{}}'); const DEFAULT_RATIO = "16/9";
const screenRatio = 16/9; const contentData = JSON.parse($('#content-edit-location').val() || `{"ratio":"${DEFAULT_RATIO}", "layers":{}}`);
let currentElement = null; let currentElement = null;
let elementCounter = 0; let elementCounter = 0;
let screenRatio = 16/9;
$('.screen-holder').css({ const setRatio = function () {
'padding-top': ( 1/ ( screenRatio ) * 100) + '%' const ratioString = $('#elem-screen-ratio').val() || DEFAULT_RATIO;
}); $('.ratio-value').text(ratioString.replace('/', ' / '));
screenRatio = evalStringRatio(ratioString);
$('.screen-holder').css({ 'padding-top': ( 1/ ( screenRatio ) * 100) + '%' });
$('.ratio-value').val(screenRatio); $('.ratio-value').val(screenRatio);
$('#screen').css({ $('#screen').css({
width: $('#screen').width(), width: $('#screen').width(),
height: $('#screen').height(), height: $('#screen').width() * (1/screenRatio),
position: 'relative', position: 'relative',
}).parents('.screen-holder:eq(0)').css({ }).parents('.screen-holder:eq(0)').css({
width: 'auto', width: 'auto',
'padding-top': '0px' 'padding-top': '0px'
}); });
};
setRatio();
$(document).on('input', '#elem-screen-ratio', function() {
setRatio();
});
function createElement(config = null) { function createElement(config = null) {
const screen = $('#screen'); const screen = $('#screen');
@ -109,7 +115,7 @@ jQuery(document).ready(function ($) {
return element; return element;
} }
$(document).on('click', '.adjust-aspect-ratio', function(){ $(document).on('click', '.element-adjust-aspect-ratio', function(){
const metadata = currentElement.data('content-metadata'); const metadata = currentElement.data('content-metadata');
const ratio = metadata.height / metadata.width; const ratio = metadata.height / metadata.width;
$('#elem-height').val($('#elem-width').val() * ratio).trigger('input'); $('#elem-height').val($('#elem-width').val() * ratio).trigger('input');
@ -174,7 +180,7 @@ jQuery(document).ready(function ($) {
if (contentType === 'picture' || contentType === 'video') { if (contentType === 'picture' || contentType === 'video') {
const contentMetadata = $element.data('content-metadata'); const contentMetadata = $element.data('content-metadata');
if (contentMetadata.width && contentMetadata.height) { if (contentMetadata.width && contentMetadata.height) {
$('.element-tool.adjust-aspect-ratio-container').removeClass('hidden'); $('.element-tool.element-adjust-aspect-ratio-container').removeClass('hidden');
} }
} }
} }
@ -414,7 +420,6 @@ jQuery(document).ready(function ($) {
}; };
applyElementsFromContent(); applyElementsFromContent();
});
const getLocationPayload = function() { const getLocationPayload = function() {
const screen = $('#screen'); const screen = $('#screen');
@ -459,6 +464,8 @@ const getLocationPayload = function() {
}); });
return { return {
ratio: $('#elem-screen-ratio').val(),
layers: layers layers: layers
}; };
}; };
});

View File

@ -71,12 +71,9 @@ jQuery(document).ready(function ($) {
$(document).on('submit', 'form.form', function (e) { $(document).on('submit', 'form.form', function (e) {
const location = getLocationPayload(); const location = $('form#elementForm').serializeObject();
$('#content-edit-location').val(JSON.stringify(location)); $('#content-edit-location').val(JSON.stringify(location));
}); });
}); });
const getLocationPayload = function() {
return $('form#elementForm').serializeObject();
};

View File

@ -81,3 +81,9 @@ const secondsToHHMMSS = function (seconds) {
const secs = seconds % 60; const secs = seconds % 60;
return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`; return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
}; };
const evalStringRatio = function(str) {
return str.replace(/(\d+)\/(\d+)/g, function(match, p1, p2) {
return (parseInt(p1) / parseInt(p2)).toString();
});
};

View File

@ -34,13 +34,14 @@
<body> <body>
<div id="screen"></div> <div id="screen"></div>
<script src="{{ STATIC_PREFIX }}js/lib/jquery.min.js"></script> <script src="{{ STATIC_PREFIX }}js/lib/jquery.min.js"></script>
<script src="{{ STATIC_PREFIX }}js/utils.js"></script>
<script> <script>
const contentData = JSON.parse({{ json_dumps(content.location) | safe }}); const contentData = JSON.parse({{ json_dumps(content.location) | safe }});
const baseIframeRoute = '{{ url_for('player', preview_content_id='!c!', autoplay=1, cover=1, transparent=1) }}'; const baseIframeRoute = '{{ url_for('player', preview_content_id='!c!', autoplay=1, cover=1, transparent=1) }}';
jQuery(function($) { jQuery(function($) {
function setOptimalSize() { function setOptimalSize() {
const ratio = 16 / 9; const ratio = evalStringRatio(contentData.ratio);
const bodyWidth = $('body').width() - 100; const bodyWidth = $('body').width() - 100;
const bodyHeight = $('body').height() - 100; const bodyHeight = $('body').height() - 100;

View File

@ -79,6 +79,7 @@
</ul> </ul>
</div> </div>
{% set contentData = json_loads(content.location) %}
<div class="horizontal"> <div class="horizontal">
<div class="form-holder"> <div class="form-holder">
<form class="form" <form class="form"
@ -91,6 +92,26 @@
value="{{ content.name }}"/> value="{{ content.name }}"/>
</div> </div>
</div> </div>
<div class="form-group">
<label for="elem-screen-ratio">{{ l.enum_content_type_composition_object_label }}</label>
<div class="widget">
{% set ratios = [
"4/3",
"16/9",
"16/10",
"3/4",
"9/16",
"10/16",
] %}
<select name="name" id="elem-screen-ratio" required="required">
{% for ratio in ratios %}
<option value="{{ ratio }}" {% if ratio == contentData.ratio %}selected="selected"{% endif %}>
{{ ratio }}
</option>
{% endfor %}
</select>
</div>
</div>
{# <div class="form-group">#} {# <div class="form-group">#}
{# <label for="">Ratio</label>#} {# <label for="">Ratio</label>#}
@ -136,7 +157,7 @@
<div class="page-content"> <div class="page-content">
<div class="inner"> <div class="inner">
<h3 class="main"> <h3 class="main">
{{ l.composition_monitor }} <span class="ratio-value badge-inset">16 / 9</span> {{ l.composition_monitor }} <span class="ratio-value badge-inset"></span>
</h3> </h3>
<div class="toolbar"> <div class="toolbar">
@ -199,8 +220,8 @@
</div> </div>
</div> </div>
<div class="horizontal fx-end element-tool adjust-aspect-ratio-container hidden"> <div class="horizontal fx-end element-tool element-adjust-aspect-ratio-container hidden">
<button type="button" class="btn btn-wire-neutral adjust-aspect-ratio"> <button type="button" class="btn btn-wire-neutral element-adjust-aspect-ratio">
<i class="fa fa-solid fa-down-left-and-up-right-to-center icon-left"></i> {{ l.composition_element_match_content_aspect_ratio }} <i class="fa fa-solid fa-down-left-and-up-right-to-center icon-left"></i> {{ l.composition_element_match_content_aspect_ratio }}
</button> </button>
</div> </div>

View File

@ -56,8 +56,20 @@
<div class="form-group"> <div class="form-group">
<label for="" class="object-label"></label> <label for="" class="object-label"></label>
<div class="widget"> <div class="widget">
{% set ratios = [
"16/9",
"16/10",
"4/3",
"9/16",
"10/16",
"3/4",
] %}
<select name="object" data-input-type="composition" class="content-object-input size-m"> <select name="object" data-input-type="composition" class="content-object-input size-m">
<option value="16/9">16/9</option> {% for ratio in ratios %}
<option value="{{ ratio }}">
{{ ratio }}
</option>
{% endfor %}
</select> </select>
</div> </div>
</div> </div>