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,24 +1,30 @@
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);
$('#screen').css({
width: $('#screen').width(),
height: $('#screen').width() * (1/screenRatio),
position: 'relative',
}).parents('.screen-holder:eq(0)').css({
width: 'auto',
'padding-top': '0px'
});
};
setRatio();
$('.ratio-value').val(screenRatio); $(document).on('input', '#elem-screen-ratio', function() {
setRatio();
$('#screen').css({
width: $('#screen').width(),
height: $('#screen').height(),
position: 'relative',
}).parents('.screen-holder:eq(0)').css({
width: 'auto',
'padding-top': '0px'
}); });
function createElement(config = null) { function createElement(config = null) {
@ -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,51 +420,52 @@ jQuery(document).ready(function ($) {
}; };
applyElementsFromContent(); applyElementsFromContent();
});
const getLocationPayload = function() { const getLocationPayload = function() {
const screen = $('#screen'); const screen = $('#screen');
const screenWidth = screen.width(); const screenWidth = screen.width();
const screenHeight = screen.height(); const screenHeight = screen.height();
const layers = []; const layers = [];
$('.element').each(function () { $('.element').each(function () {
const $element = $(this); const $element = $(this);
const offset = $element.position(); const offset = $element.position();
const x = offset.left; const x = offset.left;
const y = offset.top; const y = offset.top;
const width = $element.width(); const width = $element.width();
const height = $element.height(); const height = $element.height();
const xPercent = (x / screenWidth) * 100; const xPercent = (x / screenWidth) * 100;
const yPercent = (y / screenHeight) * 100; const yPercent = (y / screenHeight) * 100;
const widthPercent = (width / screenWidth) * 100; const widthPercent = (width / screenWidth) * 100;
const heightPercent = (height / screenHeight) * 100; const heightPercent = (height / screenHeight) * 100;
const contentId = $element.attr('data-content-id'); const contentId = $element.attr('data-content-id');
const contentName = $element.attr('data-content-name'); const contentName = $element.attr('data-content-name');
const contentType = $element.attr('data-content-type'); const contentType = $element.attr('data-content-type');
const contentMetadata = $element.data('content-metadata'); const contentMetadata = $element.data('content-metadata');
const layer = { const layer = {
xPercent: xPercent, xPercent: xPercent,
yPercent: yPercent, yPercent: yPercent,
widthPercent: widthPercent, widthPercent: widthPercent,
heightPercent: heightPercent, heightPercent: heightPercent,
zIndex: parseInt($element.css('zIndex')), zIndex: parseInt($element.css('zIndex')),
contentId: contentId ? parseInt(contentId) : null, contentId: contentId ? parseInt(contentId) : null,
contentName: contentName ? contentName : null, contentName: contentName ? contentName : null,
contentType: contentType ? contentType : null, contentType: contentType ? contentType : null,
contentMetadata: contentMetadata && contentMetadata !== "null" ? contentMetadata : null, contentMetadata: contentMetadata && contentMetadata !== "null" ? contentMetadata : null,
};
layers.push(layer);
});
layers.sort(function(a, b) {
return parseInt(b.zIndex) - parseInt(a.zIndex);
});
return {
ratio: $('#elem-screen-ratio').val(),
layers: layers
}; };
layers.push(layer);
});
layers.sort(function(a, b) {
return parseInt(b.zIndex) - parseInt(a.zIndex);
});
return {
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>