aico-image-editor
Version:
Combine multiple image into and create single combined image
244 lines (236 loc) • 20.9 kB
HTML
<div class="container" x-data="containerModal">
<div class="row">
<div class="col-12 modalParent">
<div class="modal fade pe-none" id="imageCombinerModal" aria-labelledby="imageCombinerModalLabel"
x-init="() => {
$store.elements.containerModalEL = $el;
$store.modal.createModal($el, $dispatch)
}" x-bind="imageCombinerModal">
<div class="modal-dialog modal-xl pe-auto">
<div class="modal-content">
<div class="block block-rounded shadow-none mb-0" :class="fullscreenMode ? 'block-mode-fullscreen':''">
<div class="block-header block-header-default">
<h5 class="block-title fs-lg fw-semibold" id="imageCombinerModalLabel" x-text="getTranslatedHTML('componentModalTitle')"></h5>
<div class="block-options">
<div class="pe-3 border-end btn-block-option">
<button type="button" class="btn-block-option historybackbtn" data-bs-toggle="tooltip" x-data="tooltip" :title="getTranslatedHTML('undoTitle')"
x-init="() => {
$store.elements.historyUndo = $el;
}" @click="canvasHistory.back()">
<i class="fa-solid fa-arrow-rotate-left fa-lg"></i>
</button>
<button type="button" class="btn-block-option historyforwardbtn" data-bs-toggle="tooltip" x-data="tooltip" :title="getTranslatedHTML('redoTitle')"
x-init ="() => {
$store.elements.historyRedo = $el;
$store.canvas.disableUndoRedoButtons();
}" @click="canvasHistory.forward()" >
<i class="fa-solid fa-arrow-rotate-right fa-lg"></i>
</button>
</div>
<div class="px-3 btn-block-option">
<a class="btn btn-outline-primary" download type="button" @click="$store.canvas.updateDownloadUrl()"
:href="$store.canvas.savedImageDownloadUrl">
<span x-text="getTranslatedHTML('downloadText')"></span>
</a>
<dropdown-menu datatemplateurl="./dropdownMenu.html" styles="global" shadow="true" x-data="dropdownMenu"
class="btn-group" dropdown-trigger-class="dropdown-toggle-split"
data-bs-auto-close="outside" data-bs-strategy="fixed">
<a class="btn btn-primary" type="button" @click="$store.canvas.saveCanvasImage(2000)"
slot="dropdown-append">
<span x-text="getTranslatedHTML('saveText')"></span>
</a>
<span slot="dropdown-trigger" class="pe-none">
<span class="visually-hidden">Toggle Dropdown</span>
</span>
<ul slot="dropdown-content" class="list-unstyled" >
<div class="form-check form-switch form-check-inline mb-2">
<input class="form-check-input" type="checkbox" value="" id="show-crop" name="show-crop" x-model="$store.canvas.showCropSelectionRect"
@change="$store.canvas.toggleCropSelectionRect()">
<label class="form-check-label" for="show-crop" x-text="getTranslatedHTML('crop')"></label>
</div>
<div class="mb-2" :class="!$store.canvas.showCropSelectionRect ? 'inactiveblock':''">
<div class="d-flex align-items-center mb-1">
<h6 class="mb-0" x-text="getTranslatedHTML('cropCanvas')"></h6>
<span class="linedesign ms-3 me-0"></span>
</div>
<div class="row">
<div class="col-6">
<label class="form-label" for="canvas-width" x-text="getTranslatedHTML('canvasCropWidth')"></label>
<input id="canvas-width" type="number" class="form-control form-control-sm"
x-model="$store.canvas.canvasCropWidth" @change="$store.canvas.updateCropSelectionRect()" />
</div>
<div class="col-6">
<label class="form-label" for="canvas-height" x-text="getTranslatedHTML('canvasCropHeight')"></label>
<input id="canvas-height" type="number" class="form-control form-control-sm"
x-model="$store.canvas.canvasCropHeight" @change="$store.canvas.updateCropSelectionRect()" />
</div>
</div>
</div>
<div>
<div class="d-flex align-items-center mb-1">
<h6 class="mb-0" x-text="getTranslatedHTML('imageDimensions')"></h6>
<span class="linedesign ms-3 me-0"></span>
</div>
<div class="row gy-2 mb-3">
<div class="col-6">
<label class="form-label" for="final-image-width" x-text="getTranslatedHTML('finalImageWidth')"></label>
<input id="final-image-width" type="number" min="1" :max="$store.canvas.maxCanvasWidth" class="form-control form-control-sm"
x-model="$store.canvas.finalImageWidth" @input="() => {
$store.canvas.finalImageWidth = Math.min($store.canvas.finalImageWidth,$el.max)
$store.canvas.finalImageWidth = Math.max($store.canvas.finalImageWidth,$el.min)
}" />
</div>
<div class="col-6">
<label class="form-label" for="final-image-height" x-text="getTranslatedHTML('finalImageHeight')"></label>
<input id="final-image-height" type="number" min="1" :max="$store.canvas.maxCanvasHeight" class="form-control form-control-sm"
x-model="$store.canvas.finalImageHeight" @input="() => {
$store.canvas.finalImageHeight = Math.min($store.canvas.finalImageHeight,$el.max)
$store.canvas.finalImageHeight = Math.max($store.canvas.finalImageHeight,$el.min)
}" />
</div>
</div>
<div class="space-x-2 mb-2">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" id="scaling-fit" value="fit" x-model="$store.canvas.scalingStretegy" />
<label class="form-check-label" for="scaling-fit" x-text="getTranslatedHTML('fit')"></label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" id="scaling-fill" value="fill" x-model="$store.canvas.scalingStretegy">
<label class="form-check-label" for="scaling-fill" x-text="getTranslatedHTML('fill')"></label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" id="scaling-stretch" value="stretch" x-model="$store.canvas.scalingStretegy">
<label class="form-check-label" for="scaling-stretch" x-text="getTranslatedHTML('stretch')"></label>
</div>
</div>
<div class="mt-3">
<label class="form-label" for="image-size-presets" x-text="getTranslatedHTML('templateImageSIzesLabel')"></label>
<select class="form-select form-select-sm border" id="image-size-presets" x-model="presetImageSize"
@change="updateFinalImageDim()">
<option value="1080x1920">Instagram Reels - <small>1080 x 1920 px</small></option>
<option value="820x312">Facebook Cover Photo - 820 x 312 px</option>
<option value="1500x500">Twitter Header Image - 1500 x 500 px</option>
<option value="1584x396">LinkedIn Banner Image - 1584 x 396 px</option>
<option value="1280x720">YouTube Thumbnail - 1280 x 720 px</option>
<option value="1000x1500">Pinterest Pin - 1000 x 1500 px</option>
<option value="250x250">Google+ Profile Picture - 250 x 250 px</option>
<option value="1080x1920">Snapchat Story - 1080 x 1920 px</option>
<option value="1080x1920">TikTok Video - 1080 x 1920 px</option>
<option value="1920x1080">Website Hero Image - 1920 x 1080 px</option>
</select>
</div>
<div class="mt-3">
<div class="d-flex align-items-center mb-1">
<h6 class="mb-0">Format</h6>
<span class="linedesign ms-3 me-0"></span>
</div>
<div class="space-x-2">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" id="format-png" value="png" x-model="$store.canvas.savedImageFormat" />
<label class="form-check-label" for="format-png">png</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" id="format-jpeg" value="jpeg" x-model="$store.canvas.savedImageFormat">
<label class="form-check-label" for="format-jpeg">jpeg</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" id="format-webp" value="webp" x-model="$store.canvas.savedImageFormat">
<label class="form-check-label" for="format-webp">webp</label>
</div>
</div>
</div>
<div class="mt-3">
<div class="d-flex align-items-center mb-1 position-relative">
<h6 class="mb-0" x-text="getTranslatedHTML('quality')"></h6>
<info-popover datatemplateurl="./infoPopover.html" styles="global" shadow="true"
class="d-inline-block align-middle ms-1 bg-transparent text-white"
data-bs-trigger="hover focus" data-bs-placement="bottom" x-data="infoPopover">
<span slot="info-popover-trigger" class="cursor-pointer">
<i class="fa-solid fa-circle-info fa-md text-warning lh-1"></i>
</span>
<div slot="info-popover-content" x-data="localization">
<small x-html="getTranslatedHTML('qualityApply')"></small>
</div>
</info-popover>
<span class="linedesign ms-3 me-0"></span>
</div>
<div class="row align-items-center" >
<div class="col-12" :class="$store.canvas.savedImageFormat === 'png' ? 'inactiveblock':''">
<div class="custom-range-slider">
<input class="w-100 custom-range-slider__control" type="range" id="imageQuality" min="0" max="100" x-model="$store.canvas.savedImageQuality" />
<span class="custom-range-slider__bubble" x-text="$store.canvas.savedImageQuality" :style="{left: setBubblePosition($store.canvas.savedImageQuality, 0, 100)}"></span>
</div>
</div>
<div class="col-12 text-end mt-4 d-flex justify-content-between align-items-center">
<button type="button" class="btn btn-lg btn-primary" @click="$store.canvas.getBundleFileWithSize()">
<span x-text="getTranslatedHTML('calculateImageSize')"></span>
<info-popover datatemplateurl="./infoPopover.html" styles="global" shadow="true"
class="d-inline-block align-middle ms-1 bg-transparent text-white"
data-bs-trigger="hover focus" data-bs-placement="bottom" x-data="infoPopover">
<span slot="info-popover-trigger" class="cursor-pointer">
<i class="fa-solid fa-circle-info align-middle fa-md"></i>
</span>
<div slot="info-popover-content" x-data="localization">
<small x-html="getTranslatedHTML('recalculationInfo')"></small>
</div>
</info-popover>
</button>
<span x-show="$store.canvas.savedImageFileSize">
<span x-text="$store.canvas.savedImageFileSize < 1 ? ($store.canvas.savedImageFileSize * 1024).toFixed(2) : $store.canvas.savedImageFileSize.toFixed(2)"></span>
<span x-text="$store.canvas.savedImageFileSize < 1 ? 'kb':'mb'"></span>
</span>
</div>
</div>
</div>
</div>
</ul>
</dropdown-menu>
</div>
<button type="button" class="btn-block-option" data-bs-dismiss="modal" aria-label="Close"
@click="$store.modal.closeModal($store.elements.containerModalEL)">
<i class="fas fa-times fa-xl"></i>
</button>
</div>
</div>
<div class="block-content bg-body p-0 position-relative">
<div class="editor-interface row gx-0 position-relative z-index-4 flex-nowrap">
<!-- <div class="col-lg-6 col-xl col-xxl-6 top-0" :class="[productBlockVisibleMobile ? 'd-block':'d-none d-lg-block',
!($store.canvas.isFullScreen) ? 'position-lg-sticky':'']">
</div> -->
<div class="col-1 d-flex flex-column p-1" :class="[productBlockVisibleMobile ? 'd-none d-lg-block':'d-block', currentLocale === 'de' ? 'de':'']"
>
<configurator-tabs class="d-flex flex-column flex-grow-1" datatemplateurl="./configuratorTabs.html" styles="global" shadow="true"></configurator-tabs>
</div>
<div class="col">
<configurator-component datatemplateurl="./configurator.html" styles="global"
shadow="true"></configurator-component>
<div class="position-absolute end-0 top-50 translate-middle-y d-none">
<layer-thumbnail datatemplateurl="./layerThumbnail.html" styles="global"
shadow="true"></layer-thumbnail>
</div>
</div>
</div>
<div class="position-absolute end-0 bottom-0 me-3 mb-3 z-index-5">
<a class="text-body" @click="toggleFullscreenMode($nextTick)" href="javascript:void(0)">
<i x-show="fullscreenMode" class="fa-solid fa-up-right-and-down-left-from-center"></i>
<i x-show="!fullscreenMode" class="fa-solid fa-down-left-and-up-right-to-center"></i>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal-backdrop fade show d-none" @imagecombinermodal-shown.window="($event) => {
$el.classList.remove('d-none');
}" @imagecombinermodal-hidden.window="($event) => {
$el.classList.add('d-none');
}" @click="$store.modal.closeModal($store.elements.containerModalEL)"></div>
</div>
<delete-confirm-modal datatemplateurl="./deleteConfirmModal.html" styles="global"
shadow="true"></delete-confirm-modal>
<!-- <background-crop-modal datatemplateurl="" shadow="true" styles="global"></background-crop-modal>
<shape-crop-modal datatemplateurl="./shapeCropModal.html" shadow="true" styles="global"></shape-crop-modal>
<main-picture-crop-modal datatemplateurl="./mainPictureCropModal.html" shadow="true" styles="global"></main-picture-crop-modal> -->
</div>
</div>