[AVATAR] Fix JS cropping script and save square image, in case other themes need it

This commit is contained in:
Hugo Sales 2021-04-18 20:27:31 +00:00 committed by Diogo Peralta Cordeiro
parent c37a75cf7b
commit e105889a59
8 changed files with 321 additions and 39 deletions

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "public/assets/javascript/cropperjs"]
path = public/assets/javascript/cropperjs
url = https://github.com/fengyuanchen/cropperjs.git

View File

@ -0,0 +1,304 @@
/*!
* Cropper.js v1.5.11
* https://fengyuanchen.github.io/cropperjs
*
* Copyright 2015-present Chen Fengyuan
* Released under the MIT license
*
* Date: 2021-02-17T11:53:21.992Z
*/
.cropper-container {
direction: ltr;
font-size: 0;
line-height: 0;
position: relative;
-ms-touch-action: none;
touch-action: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.cropper-container img {
display: block;
height: 100%;
image-orientation: 0deg;
max-height: none !important;
max-width: none !important;
min-height: 0 !important;
min-width: 0 !important;
width: 100%;
}
.cropper-wrap-box,
.cropper-canvas,
.cropper-drag-box,
.cropper-crop-box,
.cropper-modal {
bottom: 0;
left: 0;
position: absolute;
right: 0;
top: 0;
}
.cropper-wrap-box,
.cropper-canvas {
overflow: hidden;
}
.cropper-drag-box {
background-color: #fff;
opacity: 0;
}
.cropper-modal {
background-color: #000;
opacity: 0.5;
}
.cropper-view-box {
display: block;
height: 100%;
outline: 1px solid #39f;
outline-color: rgba(51, 153, 255, 0.75);
overflow: hidden;
width: 100%;
}
.cropper-dashed {
border: 0 dashed #eee;
display: block;
opacity: 0.5;
position: absolute;
}
.cropper-dashed.dashed-h {
border-bottom-width: 1px;
border-top-width: 1px;
height: calc(100% / 3);
left: 0;
top: calc(100% / 3);
width: 100%;
}
.cropper-dashed.dashed-v {
border-left-width: 1px;
border-right-width: 1px;
height: 100%;
left: calc(100% / 3);
top: 0;
width: calc(100% / 3);
}
.cropper-center {
display: block;
height: 0;
left: 50%;
opacity: 0.75;
position: absolute;
top: 50%;
width: 0;
}
.cropper-center::before,
.cropper-center::after {
background-color: #eee;
content: ' ';
display: block;
position: absolute;
}
.cropper-center::before {
height: 1px;
left: -3px;
top: 0;
width: 7px;
}
.cropper-center::after {
height: 7px;
left: 0;
top: -3px;
width: 1px;
}
.cropper-face,
.cropper-line,
.cropper-point {
display: block;
height: 100%;
opacity: 0.1;
position: absolute;
width: 100%;
}
.cropper-face {
background-color: #fff;
left: 0;
top: 0;
}
.cropper-line {
background-color: #39f;
}
.cropper-line.line-e {
cursor: ew-resize;
right: -3px;
top: 0;
width: 5px;
}
.cropper-line.line-n {
cursor: ns-resize;
height: 5px;
left: 0;
top: -3px;
}
.cropper-line.line-w {
cursor: ew-resize;
left: -3px;
top: 0;
width: 5px;
}
.cropper-line.line-s {
bottom: -3px;
cursor: ns-resize;
height: 5px;
left: 0;
}
.cropper-point {
background-color: #39f;
height: 5px;
opacity: 0.75;
width: 5px;
}
.cropper-point.point-e {
cursor: ew-resize;
margin-top: -3px;
right: -3px;
top: 50%;
}
.cropper-point.point-n {
cursor: ns-resize;
left: 50%;
margin-left: -3px;
top: -3px;
}
.cropper-point.point-w {
cursor: ew-resize;
left: -3px;
margin-top: -3px;
top: 50%;
}
.cropper-point.point-s {
bottom: -3px;
cursor: s-resize;
left: 50%;
margin-left: -3px;
}
.cropper-point.point-ne {
cursor: nesw-resize;
right: -3px;
top: -3px;
}
.cropper-point.point-nw {
cursor: nwse-resize;
left: -3px;
top: -3px;
}
.cropper-point.point-sw {
bottom: -3px;
cursor: nesw-resize;
left: -3px;
}
.cropper-point.point-se {
bottom: -3px;
cursor: nwse-resize;
height: 20px;
opacity: 1;
right: -3px;
width: 20px;
}
@media (min-width: 768px) {
.cropper-point.point-se {
height: 15px;
width: 15px;
}
}
@media (min-width: 992px) {
.cropper-point.point-se {
height: 10px;
width: 10px;
}
}
@media (min-width: 1200px) {
.cropper-point.point-se {
height: 5px;
opacity: 0.75;
width: 5px;
}
}
.cropper-point.point-se::before {
background-color: #39f;
bottom: -50%;
content: ' ';
display: block;
height: 200%;
opacity: 0;
position: absolute;
right: -50%;
width: 200%;
}
.cropper-invisible {
opacity: 0;
}
.cropper-bg {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC');
}
.cropper-hide {
display: block;
height: 0;
position: absolute;
width: 0;
}
.cropper-hidden {
display: none !important;
}
.cropper-move {
cursor: move;
}
.cropper-crop {
cursor: crosshair;
}
.cropper-disabled .cropper-drag-box,
.cropper-disabled .cropper-face,
.cropper-disabled .cropper-line,
.cropper-disabled .cropper-point {
cursor: not-allowed;
}

View File

@ -81,7 +81,7 @@
.icon-avatar { .icon-avatar {
order: 1; order: 1;
height: calc(5 * var(--unit-size)); height: calc(5 * var(--unit-size));
calc(5 * var(--unit-size)); width: calc(5 * var(--unit-size));
margin-right: var(--small-size); margin-right: var(--small-size);
} }

View File

@ -88,7 +88,7 @@ input.larger {
.icon-avatar { .icon-avatar {
order: 1; order: 1;
height: calc(5 * var(--unit-size)); height: calc(5 * var(--unit-size));
calc(5 * var(--unit-size)); width: calc(5 * var(--unit-size));
margin-right: var(--small-size); margin-right: var(--small-size);
} }

View File

@ -88,7 +88,7 @@ input.larger {
.icon-avatar { .icon-avatar {
order: 1; order: 1;
height: calc(5 * var(--unit-size)); height: calc(5 * var(--unit-size));
calc(5 * var(--unit-size)); width: calc(5 * var(--unit-size));
margin-right: var(--small-size); margin-right: var(--small-size);
} }

View File

@ -1,37 +1,19 @@
function getRoundedCanvas(sourceCanvas) { var input = document.getElementById('save_avatar');
var canvas = document.createElement('canvas'); var container = document.getElementById('img-container');
var context = canvas.getContext('2d'); var cropImage = document.getElementById('img-cropped');
var width = sourceCanvas.width; var cropped = document.getElementById('save_hidden');
var height = sourceCanvas.height;
canvas.width = width;
canvas.height = height;
context.imageSmoothingEnabled = true;
context.drawImage(sourceCanvas, 0, 0, width, height);
context.globalCompositeOperation = 'destination-in';
context.beginPath();
context.arc(width / 2, height / 2, Math.min(width, height) / 2, 0, 2 * Math.PI, true);
context.fill();
return canvas;
}
var input = document.getElementById('form_avatar')
var container = document.getElementById('img-container')
var cropImage = document.getElementById('img-cropped')
var cropped = document.getElementById('form_hidden')
input.addEventListener('change', function (e) { input.addEventListener('change', function (e) {
if (!input.files || !input.files[0]) return; if (!input.files || !input.files[0]) return;
var reader = new FileReader() var reader = new FileReader()
reader.onload = function (e) { reader.onload = function (e) {
container.style = 'display: block' container.style = 'display: block';
cropImage.setAttribute('src', e.target.result) cropImage.setAttribute('src', e.target.result);
function update() { function update() {
var croppedCanvas = cropper.getCroppedCanvas() var croppedCanvas = cropper.getCroppedCanvas();
var roundedCanvas = getRoundedCanvas(croppedCanvas) cropped.value = croppedCanvas.toDataURL();
cropped.value = roundedCanvas.toDataURL() input.files = undefined;
input.files = undefined
} }
var cropper = new Cropper(cropImage, { var cropper = new Cropper(cropImage, {
aspectRatio: 1, aspectRatio: 1,
@ -40,6 +22,5 @@ input.addEventListener('change', function (e) {
ready: update, ready: update,
}) })
} }
reader.readAsDataURL(input.files[0]) reader.readAsDataURL(input.files[0]);
}) });

View File

@ -144,7 +144,7 @@ class Avatar extends Entity
'name' => 'avatar', 'name' => 'avatar',
'fields' => [ 'fields' => [
'gsactor_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'GSActor.id', 'multiplicity' => 'one to one', 'not null' => true, 'description' => 'foreign key to gsactor table'], 'gsactor_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'GSActor.id', 'multiplicity' => 'one to one', 'not null' => true, 'description' => 'foreign key to gsactor table'],
'attachment_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'File.id', 'multiplicity' => 'one to one', 'not null' => true, 'description' => 'foreign key to file table'], 'attachment_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Attachment.id', 'multiplicity' => 'one to one', 'not null' => true, 'description' => 'foreign key to attachment table'],
'created' => ['type' => 'datetime', 'not null' => true, 'description' => 'date this record was created', 'default' => 'CURRENT_TIMESTAMP'], 'created' => ['type' => 'datetime', 'not null' => true, 'description' => 'date this record was created', 'default' => 'CURRENT_TIMESTAMP'],
'modified' => ['type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified', 'default' => 'CURRENT_TIMESTAMP'], 'modified' => ['type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified', 'default' => 'CURRENT_TIMESTAMP'],
], ],

View File

@ -4,8 +4,8 @@
{% block stylesheets %} {% block stylesheets %}
{{ parent() }} {{ parent() }}
<link href="{{ asset('assets/javascript/cropperjs/dist/cropper.css') }}" rel="stylesheet"> <link href="{{ asset('assets/css/cropperjs/cropper.css') }}" rel="stylesheet">
<script src="{{ asset('assets/javascript/cropperjs/dist/cropper.js') }}"></script> <script src="{{ asset('assets/javascript/cropperjs/cropper.js') }}"></script>
{% endblock %} {% endblock %}
{% block body %} {% block body %}