avatar.html 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. <!DOCTYPE html>
  2. <html lang="zh" xmlns:th="http://www.thymeleaf.org" >
  3. <head>
  4. <th:block th:include="include :: header('修改用户头像')" />
  5. <th:block th:include="include :: cropper-css" />
  6. <style type='text/css'>
  7. /* avator css start */
  8. .container {
  9. margin: 10px 5px 5px 5px;
  10. }
  11. .action {
  12. padding: 5px 0px;
  13. }
  14. .cropped {
  15. width: 200px;
  16. border: 1px #ddd solid;
  17. box-shadow: 0px 0px 12px #ddd;
  18. }
  19. .img-preview {
  20. border-radius: 50%;
  21. box-shadow: 0px 0px 12px #7e7e7e;
  22. display: inline-block;
  23. }
  24. .preview-box {
  25. text-align: center;
  26. margin: 0px auto;
  27. margin-top: 10px;
  28. color: #bbb;
  29. }
  30. .preview-md {
  31. width: 128px;
  32. height: 128px;
  33. }
  34. .preview-sm {
  35. width: 96px;
  36. height: 96px;
  37. }
  38. .preview-xs {
  39. width: 64px;
  40. height: 64px;
  41. }
  42. .imageBox {
  43. border: 1px solid #aaa;
  44. overflow: hidden;
  45. cursor: move;
  46. box-shadow: 4px 4px 12px #B0B0B0;
  47. margin: 0px auto;
  48. }
  49. .btn-custom {
  50. float: right;
  51. width: 46px;
  52. display: inline-block;
  53. margin-bottom: 10px;
  54. height: 37px;
  55. line-height: 37px;
  56. font-size: 14px;
  57. color: #FFFFFF;
  58. margin: 0px 2px;
  59. background-color: #f38e81;
  60. border-radius: 3px;
  61. text-decoration: none;
  62. cursor: pointer;
  63. box-shadow: 0px 0px 5px #B0B0B0;
  64. border: 0px #fff solid;
  65. }
  66. /*选择文件上传*/
  67. .new-contentarea {
  68. width: 165px;
  69. overflow: hidden;
  70. margin: 0 auto;
  71. position: relative;
  72. float: left;
  73. }
  74. .new-contentarea label {
  75. width: 100%;
  76. height: 100%;
  77. display: block;
  78. }
  79. .new-contentarea input[type=file] {
  80. width: 188px;
  81. height: 60px;
  82. background: #333;
  83. margin: 0 auto;
  84. position: absolute;
  85. right: 50%;
  86. margin-right: -94px;
  87. top: 0;
  88. right/*\**/: 0px\9;
  89. margin-right/*\**/: 0px\9;
  90. width/*\**/: 10px\9;
  91. opacity: 0;
  92. filter: alpha(opacity=0);
  93. z-index: 2;
  94. }
  95. a.upload-img {
  96. width: 165px;
  97. display: inline-block;
  98. margin-bottom: 10px;
  99. height: 37px;
  100. line-height: 37px;
  101. font-size: 14px;
  102. color: #FFFFFF;
  103. background-color: #f38e81;
  104. border-radius: 3px;
  105. text-decoration: none;
  106. cursor: pointer;
  107. border: 0px #fff solid;
  108. box-shadow: 0px 0px 5px #B0B0B0;
  109. }
  110. a.upload-img:hover {
  111. background-color: #ec7e70;
  112. }
  113. .tc {
  114. text-align: center;
  115. }
  116. /* avator css end */
  117. </style>
  118. </head>
  119. <body class="white-bg">
  120. <div class="row container">
  121. <div class="col-md-10">
  122. <div class="imageBox">
  123. <img id="avatar" th:src="(${#strings.isEmpty(user.avatar)}) ? @{/img/profile.jpg} : @{${user.avatar}}" th:onerror="'this.src=\'' + @{'/img/profile.jpg'} + '\''">
  124. </div>
  125. <div class="action">
  126. <div class="new-contentarea tc">
  127. <a href="javascript:void(0)" class="upload-img"><label for="inputImage">上传图像</label> </a>
  128. <input type="file" name="avatar" id="inputImage" accept="image/*"/>
  129. </div>
  130. <button type="button" class="btn-custom" data-method="zoom" data-option="0.1"><i class="fa fa-search-plus"></i></button>
  131. <button type="button" class="btn-custom" data-method="zoom" data-option="-0.1"><i class="fa fa-search-minus"></i></button>
  132. <button type="button" class="btn-custom" data-method="rotate" data-option="-45"><i class="fa fa-rotate-left"></i></button>
  133. <button type="button" class="btn-custom" data-method="rotate" data-option="45"><i class="fa fa-rotate-right"></i></button>
  134. <button type="button" class="btn-custom" data-method="scaleX" data-option="-1"><i class="fa fa-arrows-h"></i></button>
  135. <button type="button" class="btn-custom" data-method="scaleY" data-option="-1"><i class="fa fa-arrows-v"></i></button>
  136. <button type="button" class="btn-custom" data-method="reset"><i class="fa fa-refresh"></i></button>
  137. </div>
  138. </div>
  139. <div class="col-md-2">
  140. <div class="cropped">
  141. <div class="preview-box">
  142. <div class="img-preview preview-xs"></div>
  143. </div>
  144. <div class="preview-box">
  145. <div class="img-preview preview-sm"></div>
  146. </div>
  147. <div class="preview-box">
  148. <div class="img-preview preview-md"></div>
  149. </div>
  150. </div>
  151. </div>
  152. </div>
  153. <th:block th:include="include :: footer" />
  154. <th:block th:include="include :: cropper-js" />
  155. <script type="text/javascript">
  156. var cropper;
  157. var croppable = false;
  158. $(window).load(function() {
  159. var image = document.getElementById('avatar');
  160. cropper = new Cropper(image, {
  161. aspectRatio: 1,
  162. viewMode: 1,
  163. autoCropArea: 0.9,
  164. preview: '.img-preview',
  165. ready: function () {
  166. croppable = true;
  167. }
  168. })
  169. $('#inputImage').on('change', function() {
  170. var reader = new FileReader();
  171. var file = $('#inputImage')[0].files[0];
  172. if (/^image\/\w+$/.test(file.type)) {
  173. reader.onload = function(e) {
  174. if(croppable){
  175. cropper.replace(e.target.result)
  176. }
  177. }
  178. reader.readAsDataURL(this.files[0]);
  179. } else {
  180. $.modal.alertWarning('请选择一个图片文件。');
  181. }
  182. });
  183. $('.btn-custom').on('click',function (e) {
  184. if (!croppable) {
  185. $.modal.alertWarning("裁剪框加载中,请稍后...");
  186. return;
  187. }
  188. var data = {
  189. method: $(this).data('method'),
  190. option: $(this).data('option') || undefined,
  191. };
  192. var result = cropper[data.method](data.option, data.secondOption);
  193. if(['scaleX','scaleY'].indexOf(data.method) !== -1){
  194. $(this).data('option', -data.option)
  195. }
  196. })
  197. });
  198. function submitHandler() {
  199. if (!croppable) {
  200. $.modal.alertWarning("裁剪框加载中,请稍后...");
  201. return
  202. }
  203. cropper.getCroppedCanvas().toBlob(function(img) {
  204. var formdata = new FormData();
  205. formdata.append("avatarfile", img);
  206. $.ajax({
  207. url: ctx + "system/user/profile/updateAvatar",
  208. data: formdata,
  209. type: "post",
  210. processData: false,
  211. contentType: false,
  212. success: function(result) {
  213. $.operate.saveSuccess(result);
  214. }
  215. })
  216. });
  217. }
  218. $(window).resize(function() {
  219. $('.imageBox').height($(window).height() - 80);
  220. $('.cropped').height($(window).height() - 40);
  221. }).resize();
  222. if (!HTMLCanvasElement.prototype.toBlob) {
  223. Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', {
  224. value: function(callback, type, quality) {
  225. var canvas = this;
  226. setTimeout(function() {
  227. var binStr = atob(canvas.toDataURL(type, quality).split(',')[1]);
  228. var len = binStr.length;
  229. var arr = new Uint8Array(len);
  230. for (var i = 0; i < len; i++) {
  231. arr[i] = binStr.charCodeAt(i);
  232. }
  233. callback(new Blob([arr], {
  234. type: type || 'image/png'
  235. }));
  236. });
  237. }
  238. });
  239. }
  240. </script>
  241. </body>
  242. </html>