diff --git a/config/config.inc.php b/config/config.inc.php index 7384bbefd..5d29a4213 100644 --- a/config/config.inc.php +++ b/config/config.inc.php @@ -174,6 +174,7 @@ // possible camera_mode values: "user", "environment" $config['preview']['camera_mode'] = 'user'; $config['preview']['asBackground'] = false; +$config['preview']['showFrame'] = false; // K E Y I N G diff --git a/index.php b/index.php index 2ba84e051..2045dafa4 100644 --- a/index.php +++ b/index.php @@ -81,6 +81,8 @@ +pictureFrame +collageFrame
diff --git a/lib/config.php b/lib/config.php index c18fc57eb..e39d9d73f 100644 --- a/lib/config.php +++ b/lib/config.php @@ -241,3 +241,13 @@ } $config['photobooth']['version'] = getPhotoboothVersion(); + +if (!empty($config['picture']['frame'])) { + $pf_root = getrootpath($config['picture']['frame']); + $config['picture']['htmlframe'] = fixSeperator($pf_root); +} + +if (!empty($config['collage']['frame'])) { + $cf_root = getrootpath($config['collage']['frame']); + $config['collage']['htmlframe'] = fixSeperator($cf_root); +} \ No newline at end of file diff --git a/lib/configsetup.inc.php b/lib/configsetup.inc.php index b6a64d4ae..3fdb3d7e3 100644 --- a/lib/configsetup.inc.php +++ b/lib/configsetup.inc.php @@ -1117,6 +1117,11 @@ 'name' => 'preview[asBackground]', 'value' => $config['preview']['asBackground'], ], + 'preview_showFrame' => [ + 'type' => 'checkbox', + 'name' => 'preview[showFrame]', + 'value' => $config['preview']['showFrame'], + ], ], 'keying' => [ 'view' => 'advanced', diff --git a/resources/lang/en.json b/resources/lang/en.json index 6535f5f4d..49b6c2357 100644 --- a/resources/lang/en.json +++ b/resources/lang/en.json @@ -398,6 +398,7 @@ "manual:preview:preview_gphoto_bsm": "If enabled, gphoto2 live preview is started once a photo get triggered. This results in a delay of ~3 seconds until the preview is visible at countdown. If disabled, a preview is generated in background which results in a high battery usage and also a general slowdown. Camera is always active which might generate some heat and damage the camera sensor.", "manual:preview:preview_mode": "Choose a live preview mode. By default live preview is disabled, you can choose between a preview at countdown by your device cam and a preview from a URL. Preview \"from device cam\" will always use the camera of the device where Photobooth get opened in a Browser (e.g. on a tablet it will always show the tablet camera while on a smartphone it will always show the smartphone camera instead)! A secure origin or exception is required! You can find out how to set an exception here.", "manual:preview:preview_rotation": "Choose to rotate the preview.", + "manual:preview:preview_showFrame": "If enabled, the selected frame is show on top of the preview to allow guests to positionate themselves according to the frame.", "manual:preview:preview_stop_time": "Define the time, the stop gphoto preview command gets executed before the (collage-) countdown ends. The value must be lower than the (collage-) countdown.", "manual:preview:preview_style": "This setting uses the css object-fit property which is used to specify how the preview should be resized to fit.

The following options are available:
fill - The image is resized to fill the given dimension. If necessary, the image will be stretched or squished to fit.

contain - The image keeps its aspect ratio, but is resized to fit within the given dimension.

cover - The image keeps its aspect ratio and fills the given dimension. The image will be clipped to fit.

none - The image is not resized.

scale-down - the image is scaled down to the smallest version of none or contain.

Note: preview from URL only supports the cover and contain options, all other options apply the contain setting and won't harm.", "manual:preview:preview_url": "CSS style to use a stream from an URL for preview while countdown.

Example: url(../img/bg_bluegray.jpg)

", @@ -529,6 +530,7 @@ "preview:preview_gphoto_bsm": "Battery saving mode on gphoto2 live preview", "preview:preview_mode": "Preview mode", "preview:preview_rotation": "Rotate preview", + "preview:preview_showFrame": "Show frame over the preview", "preview:preview_stop_time": "Time before the countdown ends to execute the preview stop command:", "preview:preview_style": "Preview style", "preview:preview_url": "Preview-URL", diff --git a/src/js/core.js b/src/js/core.js index ddab9a3ed..b16856961 100644 --- a/src/js/core.js +++ b/src/js/core.js @@ -16,6 +16,18 @@ const photoBooth = (function () { DEVICE: 'device_cam', URL: 'url', GPHOTO: 'gphoto' + }, + PreviewStyle = { + NONE: 'none', + SCALE_DOWN: 'scale-down', + CONTAIN: 'contain', + FILL: 'fill', + COVER: 'cover' + }, + CollageFrameMode = { + OFF: 'off', + ALWAYS: 'always', + ONCE: 'once' }; const api = {}, @@ -48,6 +60,8 @@ const photoBooth = (function () { aperture = $('#aperture'), idVideoView = $('#video--view'), idVideoSensor = $('#video--sensor'), + idPictureFrame = $('#picture--frame'), + idCollageFrame = $('#collage--frame'), webcamConstraints = { audio: false, video: { @@ -111,6 +125,8 @@ const photoBooth = (function () { gallery.removeClass('gallery--open'); gallery.find('.gallery__inner').hide(); idVideoView.hide(); + idCollageFrame.hide(); + idPictureFrame.hide(); idVideoView.css('z-index', 0); idVideoSensor.hide(); ipcamView.hide(); @@ -313,6 +329,8 @@ const photoBooth = (function () { api.stream = null; } idVideoView.hide(); + idPictureFrame.hide(); + idCollageFrame.hide(); }; api.stopPreviewVideo = function () { @@ -416,6 +434,18 @@ const photoBooth = (function () { api.startVideo(CameraDisplayMode.COUNTDOWN, retry); + if ( + config.preview.mode !== PreviewMode.NONE && + config.preview.style === PreviewStyle.CONTAIN && + config.preview.showFrame + ) { + if (photoStyle === PhotoStyle.PHOTO && config.picture.take_frame) { + idPictureFrame.show(); + } else if (photoStyle === PhotoStyle.COLLAGE && config.collage.take_frame === CollageFrameMode.ALWAYS) { + idCollageFrame.show(); + } + } + loader.addClass('open'); if (config.get_request.countdown) { @@ -543,6 +573,8 @@ const photoBooth = (function () { loading.empty(); idVideoSensor.hide(); idVideoView.hide(); + idCollageFrame.hide(); + idPictureFrame.hide(); let imageUrl = config.foldersJS.tmp + '/' + result.collage_file; const preloadImage = new Image(); @@ -688,6 +720,8 @@ const photoBooth = (function () { cheese.empty(); idVideoView.hide(); idVideoSensor.hide(); + idCollageFrame.hide(); + idPictureFrame.hide(); loader.addClass('error'); loading.append($('

').text(photoboothTools.getTranslation('error'))); photoboothTools.console.log('An error occurred:', data.error); diff --git a/src/js/theme.js b/src/js/theme.js index 3299b1ebc..5737d4860 100644 --- a/src/js/theme.js +++ b/src/js/theme.js @@ -20,6 +20,8 @@ style.setProperty('--background-chroma', config.background.chroma); style.setProperty('--background-url', config.preview.url); style.setProperty('--fontSize', config.ui.font_size); style.setProperty('--preview-rotation', config.preview.rotation); +style.setProperty('--picture-frame', config.picture.htmlframe); +style.setProperty('--collage-frame', config.collage.htmlframe); $(function () { $('#wrapper').show(); diff --git a/src/sass/classic_style.scss b/src/sass/classic_style.scss index 911066dc6..139971038 100644 --- a/src/sass/classic_style.scss +++ b/src/sass/classic_style.scss @@ -310,3 +310,21 @@ button { border-radius: 10px; } } + +#picture--frame, +#collage--frame { + display: none; + object-fit: contain; + z-index: 100; + margin: 0; + padding: 0; + box-sizing: border-box; + min-width: 100%; + min-height: 100%; + width: 100%; + height: 100%; + max-width: 100%; + max-height: 100%; + position: absolute; + top: 0; +} diff --git a/src/sass/modules/_theme.scss b/src/sass/modules/_theme.scss index 3ea025aca..610515d1c 100644 --- a/src/sass/modules/_theme.scss +++ b/src/sass/modules/_theme.scss @@ -20,6 +20,8 @@ --background-url: none; --fontSize: 16px; --preview-rotation: 0deg; + --picture-frame: none; + --collage-frame: none; } $mainColor: var(--primary-color); @@ -42,3 +44,5 @@ $chromaBackground: var(--background-chroma); $urlBackground: var(--background-url); $fontSize: var(--fontSize); $previewRotation: var(--preview-rotation); +$pictureFrame: var(--picture-frame); +$collageFrame: var(--collage-frame);