From 2029ca865d7a099a3f5f0ad53e2e14559e9578ae Mon Sep 17 00:00:00 2001 From: Alexandre Bourlier <alexandre@happy-dev.fr> Date: Tue, 15 May 2018 03:54:34 +0200 Subject: [PATCH] Profile picture cropping coded --- package.json | 1 + src/html/dependencies-dev.php | 2 + src/html/dependencies-prod.php | 30 +++++----- src/html/edit-profile.html | 106 +++++++++++++++++++++++++++++++-- src/html/menu.html | 5 +- src/js/hd-app.js | 1 + src/scss/_edit-profile.scss | 39 ++++++++++++ src/scss/_forms.scss | 20 +++++++ src/scss/_mixins.scss | 5 ++ src/scss/_variables.scss | 2 +- src/scss/main.scss | 1 + 11 files changed, 190 insertions(+), 22 deletions(-) create mode 100644 src/scss/_edit-profile.scss diff --git a/package.json b/package.json index a0c175d8..cc80597f 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ }, "dependencies": { "bootstrap": "^4.0.0", + "cropper": "^4.0.0", "font-awesome": "^4.7.0", "jquery": "^3.3.1" } diff --git a/src/html/dependencies-dev.php b/src/html/dependencies-dev.php index 88c48cca..2534619c 100644 --- a/src/html/dependencies-dev.php +++ b/src/html/dependencies-dev.php @@ -1,11 +1,13 @@ <!-- Stylesheets --> <link rel="stylesheet" href="<?php echo $dn; ?>/node_modules/bootstrap/dist/css/bootstrap.min.css" /> + <link rel="stylesheet" href="<?php echo $dn; ?>/node_modules/cropper/dist/cropper.min.css" /> <link rel="stylesheet" href="<?php echo $dn; ?>/dist/css/hd-app.css?v=<?php echo $v ?>" /> <link rel="stylesheet" href="<?php echo $dn; ?>/node_modules/font-awesome/css/font-awesome.min.css" /> <!-- Javascript --> <script type="text/javascript" src="<?php echo $dn; ?>/node_modules/jquery/dist/jquery.min.js"></script> <script type="text/javascript" src="<?php echo $dn; ?>/node_modules/bootstrap/dist/js/bootstrap.min.js"></script> + <script type="text/javascript" src="<?php echo $dn; ?>/node_modules/cropper/dist/cropper.min.js"></script> <script type="text/javascript" src="<?php echo $dn; ?>/dist/lib/webcomponentsjs/webcomponents-loader.js"></script> <script type="text/javascript" src="<?php echo $dn; ?>/src/js/hd-app.js?v=<?php echo $v ?>"></script> diff --git a/src/html/dependencies-prod.php b/src/html/dependencies-prod.php index adfcc21f..f21882e0 100644 --- a/src/html/dependencies-prod.php +++ b/src/html/dependencies-prod.php @@ -1,16 +1,18 @@ - <!-- Stylesheets --> - <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous"> - <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"> - <link rel="stylesheet" href="<?php echo $dn; ?>/dist/css/hd-app.css?v=<?php echo $v ?>" /> +<!-- Stylesheets --> +<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous"> +<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"> +<link href="https://cdn.bootcss.com/cropper/4.0.0/cropper.min.css" rel="stylesheet"> +<link rel="stylesheet" href="<?php echo $dn; ?>/dist/css/hd-app.css?v=<?php echo $v ?>" /> - <!-- Javascript --> - <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> - <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js" integrity="sha384-cs/chFZiN24E4KMATLdqdvsezGxaGsi4hLGOzlXwp5UZB1LY//20VyM2taTB4QvJ" crossorigin="anonymous"></script> - <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js" integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm" crossorigin="anonymous"></script> - <script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/1.2.0/webcomponents-loader.js" integrity="sha256-fUVqCtpScUF69qkFkeuHmcShr2N2UleRQJhRG4etHds=" crossorigin="anonymous"></script> - <script type="text/javascript" src="<?php echo $dn; ?>/dist/js/hd-app.js?v=<?php echo $v ?>"></script> +<!-- Javascript --> +<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> +<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js" integrity="sha384-cs/chFZiN24E4KMATLdqdvsezGxaGsi4hLGOzlXwp5UZB1LY//20VyM2taTB4QvJ" crossorigin="anonymous"></script> +<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js" integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm" crossorigin="anonymous"></script> +<script src="https://cdn.bootcss.com/cropper/4.0.0/cropper.min.js"></script> +<script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/1.2.0/webcomponents-loader.js" integrity="sha256-fUVqCtpScUF69qkFkeuHmcShr2N2UleRQJhRG4etHds=" crossorigin="anonymous"></script> +<script type="text/javascript" src="<?php echo $dn; ?>/dist/js/hd-app.js?v=<?php echo $v ?>"></script> - <!-- Web components --> - <link rel="import" href="https://cdn.happy-dev.fr/ldp-display/ldp-display.html?v=<?php echo $v ?>" /> - <link rel="import" href="https://cdn.happy-dev.fr/ldp-display/ldp-router.html?v=<?php echo $v ?>" /> - <link rel="import" href="https://xmpp-chat-component.happy-dev.fr/chat-window-component.html?v=<?php echo $v ?>"> +<!-- Web components --> +<link rel="import" href="https://cdn.happy-dev.fr/ldp-display/ldp-display.html?v=<?php echo $v ?>" /> +<link rel="import" href="https://cdn.happy-dev.fr/ldp-display/ldp-router.html?v=<?php echo $v ?>" /> +<link rel="import" href="https://xmpp-chat-component.happy-dev.fr/chat-window-component.html?v=<?php echo $v ?>"> diff --git a/src/html/edit-profile.html b/src/html/edit-profile.html index c48991ca..cbde15fb 100644 --- a/src/html/edit-profile.html +++ b/src/html/edit-profile.html @@ -1,8 +1,106 @@ +<script> + //class LDPFormImgUpload extends LDPWidget { + // get template() { + // return `<label for="${this.name}"><img id="${this.name}-preview" src="${this.value}"/></label> + // <input id="${this.name}" type="file" name="${this.name}" value="${this.value}" />`; + // } + + // render() { + // store.get(this.value).then( (value) => { + // this._value = value; + // this.innerHTML = this.template; + // }); + // } + //} + //customElements.define("ldp-form-img-upload", LDPFormImgUpload); + + //widget-avatar="ldp-form-img-upload" +</script> + <div id="edit-profile" style="display: none"> - <ldp-form - data-fields="" + <!--ldp-form + class="edit-form" + data-src="<?php echo $sdn; ?>/members/1/" bind-resources - ></ldp-form> + ></ldp-form--> - <h1>BOOM</h1> + + <label for="avatar-input"> + <img id="avatar-preview" src="http://cdn.hd-app.local/members/alexandre-bourlier.jpg" style="width: 100%;"/> + </label> + <input type="file" id="avatar-input" name="avatar" value="http://cdn.hd-app.local/members/alexandre-bourlier.jpg" />`; </div> + +<div id="crop-modal"> + <div class="crop-wrapper"> + <img id="crop-preview" src="" /> + </div> + + <div class="control-bar"> + <button id="cancel-img-cropping" class="btn btn-link">Annuler</button> + <i id="rotate-img" class="fa fa-undo" aria-hidden="true"></i> + <button id="crop-img" class="btn btn-link">Valider</button> + </div> +</div> + +<script> + // Constant declaration + const avatarPreview = document.querySelector("#avatar-preview"); + const avatarInput = document.querySelector("#avatar-input"); + const cropModal = document.querySelector("#crop-modal"); + const cropPreview = cropModal.querySelector("#crop-preview"); + const $cropPreview = $(cropPreview); + + // Triggers cropping on image upload + avatarInput.addEventListener("change", (e) => { + var img = avatarInput.files[0]; + var reader = new FileReader(); + + reader.onloadend = function () { + cropPreview.src = reader.result; + } + + if (img) { + reader.readAsDataURL(img);//reads the data as a URL + cropModal.classList.add("cropping-mode"); + } + }); + cropPreview.addEventListener("load", () => { + $cropPreview.cropper({ + aspectRatio: 1/1, + viewMode: 3, + zoomable: false, + }); + }); + + + // Rotate image + cropModal.querySelector("#rotate-img").addEventListener("click", () => { + $cropPreview.cropper("rotate", -90); + }); + + + // Cancel cropping + cropModal.querySelector("#cancel-img-cropping").addEventListener("click", () => { + closeCropping(); + }); + + // Shortcut + document.querySelector("body").addEventListener("keydown", function(e) { + // Escape key + if (e.keyCode == 27 && cropModal.classList.contains("cropping-mode")) { + closeCropping(); + } + }); + function closeCropping() { + cropModal.classList.remove("cropping-mode"); + avatarInput.value = null; + } + + + // Validating cropping + cropModal.querySelector("#crop-img").addEventListener("click", () => { + avatarPreview.src = $cropPreview.cropper("getCroppedCanvas").toDataURL() + closeCropping(); + }); +</script> diff --git a/src/html/menu.html b/src/html/menu.html index 9822e37a..2598d69d 100644 --- a/src/html/menu.html +++ b/src/html/menu.html @@ -10,9 +10,8 @@ <i class="fa fa-users" aria-hidden="true"></i> <span class="d-none d-md-inline"> Membres</span> </ldp-route> - <ldp-route class="nav-item d-none" name="member" id-prefix="<?php echo $sdn; ?>/members/"> - Membre - </ldp-route> + <ldp-route class="d-none" name="member" id-prefix="<?php echo $sdn; ?>/members/"></ldp-route> + <ldp-route class="d-none" name="edit-profile" id-prefix="<?php echo $sdn; ?>/members/"></ldp-route> <ldp-route class="nav-item pb-2 align-self-stretch text-center text-md-left" name="projects"> <i class="fa fa-tasks" aria-hidden="true"></i> diff --git a/src/js/hd-app.js b/src/js/hd-app.js index 7e1b390e..a1b05714 100644 --- a/src/js/hd-app.js +++ b/src/js/hd-app.js @@ -15,6 +15,7 @@ document.addEventListener("DOMContentLoaded", function(event) { openSearchBar(); } + // Escape key else if (e.keyCode == 27 && navBar.classList.contains("search-mode")) { closeSearchBar(); } diff --git a/src/scss/_edit-profile.scss b/src/scss/_edit-profile.scss new file mode 100644 index 00000000..4c01e67a --- /dev/null +++ b/src/scss/_edit-profile.scss @@ -0,0 +1,39 @@ +#crop-modal { + position: absolute; + z-index: 1111; + top: $menu-height; + bottom: 0px; + left: 0px; + right: 0px; + background-color: black; + display: none; + + &.cropping-mode { + display: block; + } + + .crop-wrapper { + img { + width: 100%; + } + } + + .control-bar { + display: flex; + justify-content: space-between; + color: white; + font-size: 30px; + + button { + text-transform: uppercase; + color: white; + font-size: 18px; + font-weight: bold; + } + + i { + padding-top: 4px; + } + } +} + diff --git a/src/scss/_forms.scss b/src/scss/_forms.scss index a0f6eb44..5ae2f5eb 100644 --- a/src/scss/_forms.scss +++ b/src/scss/_forms.scss @@ -54,3 +54,23 @@ ldp-display { } } } + +ldp-form.edit-form { + ldp-form-text { + @extend %form-group; + + label { + text-transform: capitalize; + } + + input { + @extend %form-control; + @extend %form-control-sm; + } + } + + input[type="submit"] { + @extend %btn; + @extend %btn-primary; + } +} diff --git a/src/scss/_mixins.scss b/src/scss/_mixins.scss index 5a0da003..21425546 100644 --- a/src/scss/_mixins.scss +++ b/src/scss/_mixins.scss @@ -33,6 +33,11 @@ background-color: transparent; } +%form-group { + display: block; + margin-bottom: 1rem; +} + %form-control { display: block; width: 100%; diff --git a/src/scss/_variables.scss b/src/scss/_variables.scss index ae35db06..4b078135 100644 --- a/src/scss/_variables.scss +++ b/src/scss/_variables.scss @@ -2,7 +2,7 @@ $hd-color: rgb(253, 200, 21); $hd-color-faded: rgba(253, 200, 21, 0.8); $twitter-color: grey; -$menu-height: 46px; +$menu-height: 43px; $menu-font-size: 16px; $vertical-menu-width: 50px; $sm-with: 576px; diff --git a/src/scss/main.scss b/src/scss/main.scss index cd2f4181..8bd56395 100644 --- a/src/scss/main.scss +++ b/src/scss/main.scss @@ -11,6 +11,7 @@ @import "dashboard"; @import "members"; @import "member"; +@import "edit-profile"; @import "projects"; @import "project"; @import "channels"; -- GitLab