cropper.jsp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. <%@ page language="java" pageEncoding="UTF-8" isELIgnored="false" %>
  2. <%@ taglib uri="/ssTag" prefix="ss"%>
  3. <html>
  4. <head>
  5. <script src="/js/load.js"></script><%-- 改为新的路径 Ben(20251205) --%>
  6. <%-- <script src="../ss/js/base.js"></script>--%>
  7. <!-- <script src="../ss/js/cropper.js" type="text/javascript" charset="utf-8"></script> -->
  8. <style type="text/css">
  9. html,
  10. body {
  11. overflow: hidden;
  12. }
  13. .content {
  14. width: 100%;
  15. height: 100%;
  16. overflow: hidden;
  17. }
  18. .cropper-content {
  19. width: 100%;
  20. height: calc(100% - 160px);
  21. background-color: #f2f2f2;
  22. }
  23. .cropper-tool-bra {
  24. width: 100%;
  25. height: 52px;
  26. margin: 10px 0px;
  27. }
  28. .cropper-tool-bra-list {
  29. padding: 0;
  30. height: 52px;
  31. margin: 0 auto;
  32. list-style: none;
  33. display: flex;
  34. justify-content: center;
  35. }
  36. .cropper-tool-bra-list li {
  37. width: 36px;
  38. font-size: 26px;
  39. font-weight: bolder;
  40. text-align: center;
  41. /* line-height: 52px; */
  42. color: #99a9bf;
  43. float: left;
  44. transition: all 0.3s;
  45. }
  46. .cropper-tool-bra-list li:hover {
  47. cursor: pointer;
  48. color: #409EFF;
  49. }
  50. .el-slider__bar {
  51. background-color: #E4E7ED;
  52. }
  53. .cropper-tool-bra-list .slider-wrap {
  54. width: 220px;
  55. padding: 6px;
  56. }
  57. .cat {
  58. display: inline-block;
  59. width: 30px !important;
  60. height: 30px !important;
  61. background: url(/skin/easy/images/cat.png) center center no-repeat !important; <%-- (/newUI/skin/easy/images/cat.png)。Lin(新UI) --%>
  62. }
  63. .rotate-icon {
  64. transform: rotate(90deg);
  65. }
  66. </style>
  67. </head>
  68. <body>
  69. <div id="app">
  70. <div class="content">
  71. <div class="cropper-content">
  72. <img id="cropper-content-img" src="" />
  73. </div>
  74. <div class="cropper-tool-bra">
  75. <ul class="cropper-tool-bra-list">
  76. <!-- <li onclick="cropper.zoom('-0.1')" style="line-height: 46px;">
  77. <el-tooltip class="item" effect="dark" content="缩小" placement="top-start">
  78. <i style="font-size: 20px;" class="el-icon-picture-outline"></i>
  79. </el-tooptip>
  80. </li>
  81. <li style="" class="slider-wrap">
  82. <el-slider v-model="sliderValue" :show-tooltip="false" :disabled="isDisabled"
  83. @input="sliderInput()" @change="sliderChange" :min="-50" :max="50"></el-slider>
  84. </li>
  85. <li onclick="cropper.zoom('0.1')">
  86. <el-tooltip class="item" effect="dark" content="放大" placement="top-start"><i
  87. class="el-icon-picture-outline"></i></el-tooptip>
  88. </li> -->
  89. <li onclick="cropper.maxCrop();" title="设置最大裁剪框" >
  90. <ss-icon name="full-screen"></ss-icon>
  91. <!-- <el-tooltip class="item" effect="dark" content="设置最大裁剪框" placement="top-start"><i
  92. class="el-icon-crop"></i></el-tooptip> -->
  93. </li>
  94. <!-- <li onclick="cropper.locaToTopBottomCenter();">
  95. <el-tooltip class="item" effect="dark" content="裁剪框上下居中" placement="top-start"><i
  96. class="el-icon-sort"></i></el-tooptip>
  97. </li>
  98. <li onclick="cropper.locaToLeftRightCenter();">
  99. <el-tooltip class="item" effect="dark" content="裁剪框左右居中" placement="top-start"><i
  100. class="el-icon-sort rotate-icon"></i></el-tooptip>
  101. </li> -->
  102. <li onclick='cropper.reset();' title="重置">
  103. <ss-icon name="refresh"></ss-icon>
  104. </li>
  105. <li onclick="cropper.rotate('-45')" title="逆时针旋转45°">
  106. <ss-icon name="back"></ss-icon>
  107. </li>
  108. <li class="slider-wrap">
  109. <el-slider v-model="rotateValue" :show-tooltip="false" :disabled="isRotateDisabled"
  110. @input="rotateSliderInput()" @change="rotateSliderChange" :min="-50" :max="50"></el-slider>
  111. </li>
  112. <li onclick="cropper.rotate('45')" title="顺时针旋转45°">
  113. <ss-icon name="reset"></ss-icon>
  114. </li>
  115. </ul>
  116. </div>
  117. <!-- <div class="bottom-div">
  118. <el-button type="primary">确定</el-button>
  119. <el-button
  120. type="success">原图上传</el-button>
  121. <el-button onclick="SS.closeDialog();" type="danger">取消</el-button>
  122. </div> -->
  123. <div class="bottom-div" style="bottom: 0;position: fixed;width: 100%;">
  124. <ss-bottom-button
  125. text="取消"
  126. onclick="SS.closeDialog()"
  127. icon-class="bottom-div-close"
  128. ></ss-bottom-button>
  129. <ss-bottom-button
  130. text="保存"
  131. onclick="cropper.getCroppedCanvas()"
  132. icon-class="bottom-div-save"
  133. ></ss-bottom-button>
  134. <!-- <button onclick="SS.closeDialog()" type="button">
  135. <span><ss-icon name="close-thin" size="20px" /></span>
  136. <span>取消</span>
  137. </button>
  138. <button onclick="onDialogClose" type="button" v-if="originalPhotoUploadFlag" onclick="cropper.originalPhotoUpload();">
  139. <span><ss-icon name="close-thin" size="20px" /></span>
  140. <span>原图上传</span>
  141. </button>
  142. <button onclick="cropper.getCroppedCanvas()">
  143. <span><ss-icon name="check-thin" size="14px" /></span>
  144. <span>保存</span>
  145. </button> -->
  146. </div>
  147. </div>
  148. </div>
  149. </body>
  150. <script type="module">
  151. var setting = undefined;
  152. var cropper = {
  153. $image: undefined,
  154. init: function () {
  155. console.log('cropper初始化了');
  156. $("#cropper-content-img").attr("src", setting.data);
  157. cropper.$image = $("#cropper-content-img");
  158. console.log("cropper.$image", cropper.$image)
  159. setting.viewMode = setting.photoSize == undefined ? 0 : 1;
  160. if (setting.photoSize && !setting.photoSize.width && !setting.photoSize.height) {
  161. setting.viewMode = 0;
  162. }
  163. if (setting.viewMode == 0) {
  164. vue.$data.originalPhotoUploadFlag = true;
  165. setting.aspectRatio = undefined;
  166. }
  167. else {
  168. if (setting.photoSize && setting.photoSize.width && setting.photoSize.height) {
  169. setting.aspectRatio = setting.photoSize.width / setting.photoSize.height;
  170. }
  171. }
  172. cropper.$image.cropper({
  173. aspectRatio: setting.aspectRatio,
  174. viewMode: setting.viewMode, // 视点模式:【0:无限制;1:不能超出裁剪区域;】
  175. dragMode: 'move', // 拖曳模式:'crop'*创建一个新的麦田盒,'move'*移动画布,'none'*无所事事
  176. modal: true, // 是否显示黑色遮罩
  177. guides: false, // 显示麦田盒上方的虚线。
  178. center: true, // 显示位于“作物”框上方的中心指示器。
  179. highlight: true, // 在“作物”框上方显示白色模式(突出显示“作物”框)。
  180. background: true, // 是否显示透明背景
  181. movable: true, // 是否可以移动图像
  182. rotatable: true, // 可旋转
  183. scalable: true, // 可伸缩
  184. zoomable: true, // 可缩放
  185. responsive: true, // 调整窗口大小时,重新渲染裁剪器
  186. zoomOnWheel: true, // 通过移动鼠标使图像能够缩放
  187. wheelZoomRatio: 0.1, // 定义缩放比率时,通过鼠标旋转放大图像。(滚动时放大或缩小的比例)
  188. cropBoxMovable: true, // 通过拖动启用移动“裁剪”框。
  189. CropBoxResizable: true, // 可以通过拖动调整裁剪框的大小
  190. MinCropBoxWidth: 100,
  191. minCropBoxHeight: 100,
  192. ready: function () {
  193. cropper.initStyle();
  194. }
  195. });
  196. },
  197. initStyle: function () {
  198. $(".cropper-bg").css("width", "100%");
  199. $(".line-e").remove();
  200. $(".line-n").remove();
  201. $(".line-w").remove();
  202. $(".line-s").remove();
  203. $(".point-e").remove();
  204. $(".point-n").remove();
  205. $(".point-w").remove();
  206. $(".point-s").remove();
  207. $(".point-ne").remove();
  208. $(".point-nw").remove();
  209. $(".point-sw").remove();
  210. if (setting.box == '0') {
  211. $(".cropper-view-box").css({
  212. "outline": "none",
  213. "outline-color": "none",
  214. "border-radius": "100%",
  215. "border": "2px solid #39f"
  216. });
  217. $(".point-se").css("border-radius", "100%");
  218. $(".cropper-face").css("border-radius", "100%");
  219. } else {
  220. $(".point-se").addClass("cat");
  221. }
  222. },
  223. replace: function replace(url) { // 重新渲染裁剪框
  224. cropper.$image.data('cropper').replace(url, false);
  225. },
  226. zoom: function (num) {
  227. cropper.$image.data('cropper').zoom(num);
  228. },
  229. zoomTo: function (num) {
  230. cropper.$image.data('cropper').zoomTo(num);
  231. },
  232. rotate: function (num) {
  233. cropper.$image.data('cropper').rotate(num);
  234. },
  235. reset: function () {
  236. cropper.$image.data('cropper').reset();
  237. },
  238. maxCrop: function () {
  239. cropper.$image.data('cropper').setCropBoxData({
  240. width: 9999,
  241. height: 9999
  242. });
  243. },
  244. // 裁剪框上下居中
  245. locaToTopBottomCenter: function () {
  246. var corpBoxData = cropper.$image.data('cropper').getCropBoxData();
  247. var containerData = cropper.$image.data('cropper').getContainerData();
  248. var top = ((containerData.height - corpBoxData.height) / 2);
  249. cropper.$image.data('cropper').setCropBoxData({
  250. top: top
  251. });
  252. },
  253. // 裁剪框左右居中
  254. locaToLeftRightCenter: function () {
  255. var containerData = cropper.$image.data('cropper').getContainerData();
  256. var corpBoxData = cropper.$image.data('cropper').getCropBoxData();
  257. var left = ((containerData.width - corpBoxData.width) / 2);
  258. cropper.$image.data('cropper').setCropBoxData({
  259. left: left
  260. });
  261. },
  262. getCroppedCanvas: function () { // 获取上传裁剪图片
  263. // space.plugins.loading.show();
  264. var hce = undefined;
  265. if (setting.photoSize) {
  266. hce = cropper.$image.data('cropper').getCroppedCanvas({
  267. width: setting.photoSize.width,
  268. height: setting.photoSize.height,
  269. imageSmoothingQuality: 'high',
  270. fillColor: '#fff'
  271. });
  272. } else {
  273. hce = cropper.$image.data('cropper').getCroppedCanvas({
  274. imageSmoothingQuality: 'high',
  275. fillColor: '#fff'
  276. });
  277. }
  278. hce.toBlob((blob) => {
  279. // console.log('xxxsetting:'+JSON.stringify(setting))
  280. const urlParams = new URLSearchParams(window.location.search);
  281. const paramsStr = urlParams.get('params');
  282. const params = JSON.parse(decodeURIComponent(paramsStr));
  283. // space.plugins.loading.show();
  284. const formData = new FormData();
  285. formData.append('fileEdit', new File([blob], setting.fileName));
  286. formData.append("application", "");//如果没有这个,后台会报错
  287. $.ajax(setting.uploadUrl, {
  288. method: "POST",
  289. data: formData,
  290. processData: false,
  291. contentType: false,
  292. dataType: 'json',
  293. success(data) {
  294. if (data.fileList.length > 0) {
  295. const uploaderId = params.uploaderId;
  296. if(window.parent && window.parent.SS && window.parent.SS.cropper) {
  297. const setting = window.top.SS.cropper.getSetting(uploaderId);
  298. if(setting && setting.success) {
  299. // 执行成功回调
  300. setting.success(data.fileList[0].path);
  301. if (setting.context && setting.context.SS) {
  302. setting.context.SS.closeDialog();
  303. } else {
  304. // 降级处理
  305. window.parent.SS.closeDialog();
  306. }
  307. // 清理设置
  308. window.top.SS.cropper.clearSetting(uploaderId);
  309. }
  310. }
  311. } else {
  312. console.log('data.data[0].msg',data.data[0].msg)
  313. // space.plugins.loading.close();
  314. // space.message.error(data.data[0].msg);
  315. }
  316. },
  317. error() {
  318. alert('error');
  319. // console.log(setting.success)
  320. // space.plugins.loading.close();
  321. // space.message.error("系统繁忙,请稍后再试");
  322. }
  323. });
  324. });
  325. },
  326. // 原图上传
  327. originalPhotoUpload: function () {
  328. // space.plugins.loading.show();
  329. const formData = new FormData();
  330. formData.append('fileEdit', setting.file);
  331. $.ajax("@service{ name:'uploadAjax' }@", {
  332. method: "POST",
  333. data: formData,
  334. processData: false,
  335. contentType: false,
  336. dataType: 'json',
  337. success(data) {
  338. if (data.code == "success") {
  339. setting.success(data.data[0].msg);
  340. // space.allFunction.closeDialog();
  341. } else {
  342. // space.plugins.loading.close();
  343. // space.message.error(data.data[0].msg);
  344. }
  345. },
  346. error() {
  347. // space.plugins.loading.close();
  348. // space.message.error("系统繁忙,请稍后再试");
  349. }
  350. });
  351. }
  352. }
  353. window.cropper = cropper;
  354. SS.ready(function () {
  355. SS.vue = SS.dom.initializeFormApp({
  356. el: '#app',
  357. data() {
  358. return {
  359. sliderValue: 0, //滑块初始值
  360. sliderBeforeValue: 0,
  361. isDisabled: true, //滑块是否禁用
  362. rotateValue: 0, //旋转滑块初始值
  363. rotateBeforeValue: 0,
  364. isRotateDisabled: true, //旋转滑块是否禁用
  365. originalPhotoUploadFlag: false,
  366. }
  367. },
  368. methods: {
  369. formatTooltip(val) {
  370. return val / 100;
  371. },
  372. sliderInput() {
  373. if (downFlag) {
  374. if (this.sliderBeforeValue > this.sliderValue) {
  375. cropper.zoom("-0.1");
  376. } else {
  377. cropper.zoom("0.1");
  378. }
  379. this.sliderBeforeValue = this.sliderValue;
  380. }
  381. },
  382. sliderChange() {
  383. var _this = this;
  384. var timer;
  385. if (this.sliderValue > 0) {
  386. timer = setInterval(function () {
  387. _this.sliderValue -= 10;
  388. if (_this.sliderValue <= 0) {
  389. _this.sliderValue = 0
  390. clearInterval(timer)
  391. }
  392. }, _this.sliderValue / 2)
  393. } else {
  394. timer = setInterval(function () {
  395. _this.sliderValue += 10;
  396. if (_this.sliderValue >= 0) {
  397. _this.sliderValue = 0
  398. clearInterval(timer)
  399. }
  400. }, -_this.sliderValue / 2)
  401. }
  402. },
  403. rotateSliderInput() {
  404. if (downFlag) {
  405. if (this.rotateBeforeValue > this.rotateValue) {
  406. cropper.rotate("-1");
  407. } else {
  408. cropper.rotate("1");
  409. }
  410. this.rotateBeforeValue = this.rotateValue;
  411. }
  412. },
  413. rotateSliderChange() {
  414. var _this = this;
  415. var timer;
  416. if (this.rotateValue > 0) {
  417. timer = setInterval(function () {
  418. _this.rotateValue -= 10;
  419. if (_this.rotateValue <= 0) {
  420. _this.rotateValue = 0
  421. clearInterval(timer)
  422. }
  423. }, _this.rotateValue / 2)
  424. } else {
  425. timer = setInterval(function () {
  426. _this.rotateValue += 10;
  427. if (_this.rotateValue >= 0) {
  428. _this.rotateValue = 0
  429. clearInterval(timer)
  430. }
  431. }, -_this.rotateValue / 2)
  432. }
  433. }
  434. }
  435. });
  436. var downFlag = false;
  437. var winInterval = undefined;
  438. $(document).ready(function () {
  439. // space.plugins.loading.show();
  440. $(window).on("mousedown", function () {
  441. downFlag = true;
  442. });
  443. $(window).on("mouseup", function () {
  444. downFlag = false;
  445. });
  446. // 获取到vue实例
  447. console.log(SS.vue.$data)
  448. //滑块禁用模式改为启用
  449. SS.vue.$data.isDisabled = false;
  450. SS.vue.$data.isRotateDisabled = false;
  451. var param = SS.getQueryParams();
  452. window.cropperSetting = param.params;
  453. console.log('初始化裁剪插件',window.cropperSetting);
  454. // console.log("cropper.html中的window.cropperSetting", window.cropperSetting)
  455. winInterval = setInterval(function () {
  456. if (!window.cropperSetting) {
  457. return;
  458. }
  459. window.clearInterval(winInterval);
  460. setting = window.cropperSetting;
  461. cropper.init();
  462. // space.plugins.loading.close();
  463. }, 100);
  464. });
  465. });
  466. </script>
  467. </html>