appBannerManage.html 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. {% load staticfiles %}
  2. <!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>基于cropper.js的图片裁剪</title>
  7. <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
  8. <meta name="format-detection" content="telephone=no">
  9. <link href="{% static '/lib/bootstrap-3.3.7/css/bootstrap.css' %}" rel="stylesheet">
  10. <link rel="stylesheet" href="{% static '/lib/font-awesome/4.5.0/css/font-awesome.css' %}">
  11. <link rel="stylesheet" href="{% static '/lib/css/ace.min.css' %}" />
  12. <link rel="stylesheet" href="{% static '/lib/css/ace-skins.min.css' %}">
  13. <link rel="stylesheet" href="{% static '/lib/css/ace-rtl.min.css' %}">
  14. <link rel="stylesheet" href="{% static '/lib/layui/css/layui.css' %}">
  15. <link rel="stylesheet" href="{% static '/lib/css/cropper.css' %}">
  16. <link rel="stylesheet" href="{% static '/css/ImgCropping.css' %}">
  17. <style>
  18. body {
  19. overflow: hidden;
  20. background: #fff;
  21. }
  22. .baseedit>div {
  23. margin-top: 20px;
  24. }
  25. .titleTxt {
  26. color: #626262;
  27. display: inline-block;
  28. width: 200px;
  29. text-align: right;
  30. vertical-align: top;
  31. }
  32. .baseContent {
  33. display: inline-block;
  34. }
  35. #baseName {
  36. border-radius: 0!important;
  37. color: #858585;
  38. background-color: #FFF;
  39. border: 1px solid #D5D5D5;
  40. padding: 5px 4px 6px;
  41. font-size: 14px;
  42. font-family: inherit;
  43. width: 220px;
  44. }
  45. #finalImg {
  46. width: 100%;
  47. }
  48. .cancel {
  49. background: #ABBAC3;
  50. color: #fff;
  51. border: solid 1px #ABBAC3;
  52. }
  53. .cancel:hover {
  54. background: #d4d9db;
  55. color: #fff;
  56. border: solid 1px #d4d9db;
  57. }
  58. #hint {
  59. display: none;
  60. position: fixed;
  61. left: 50%;
  62. top: 50%;
  63. background: #b2b2b2;
  64. padding: 20px;
  65. border-radius: 5px;
  66. color: #fff;
  67. transform: translateX(-50%) translateY(-50%);
  68. }
  69. /* 图片列表 */
  70. .refresh {
  71. font-size: 16px;
  72. color: #4C8FBD;
  73. margin-right: 30px;
  74. }
  75. .bannerList >div{
  76. margin-bottom: 20px;
  77. }
  78. .showimg {
  79. position: relative;
  80. width: 100%;
  81. height: 280px;
  82. background: #eee;
  83. border-radius: 8px;
  84. overflow: hidden;
  85. }
  86. .showimg:hover .bottomDiv {
  87. height: 32px;
  88. }
  89. .showimg>img {
  90. width: 100%;
  91. height: 100%;
  92. }
  93. .bottomDiv {
  94. position: absolute;
  95. bottom: 0;
  96. left: 0;
  97. right: 0;
  98. height: 0;
  99. background: rgba(0, 0, 0, 0.57);
  100. text-align: right;
  101. padding-right: 20px;
  102. transition: all .3s linear;
  103. -moz-transition: all .3s linear;
  104. /* Firefox 4 */
  105. -webkit-transition: all .3s linear;
  106. /* Safari and Chrome */
  107. -o-transition: all .3s linear;
  108. /* Opera */
  109. }
  110. .bottomDiv>a {
  111. color: #fff;
  112. line-height: 32px;
  113. }
  114. /* 空数据 */
  115. .vrnull {
  116. text-align: center;
  117. padding-top: 12%;
  118. line-height: 30px;
  119. }
  120. </style>
  121. </head>
  122. <body>
  123. <div class="content">
  124. <div class="page-header">
  125. <h1>
  126. <font style="vertical-align: inherit;">
  127. <font style="vertical-align: inherit;">
  128. 轮播图管理
  129. </font>
  130. </font>
  131. <!-- <a class="refresh" href="javascript:;" style="float: right;">
  132. <i class="add">
  133. <img src="{% static '/img/addicon.png' %}" alt="" width="28">
  134. </i>添加轮播图 </a> -->
  135. {% if app_img|length < 8 %}
  136. <button id="replaceImg" class="l-btn" style="float: right;">添加轮播图</button>
  137. {% else %}{% endif %}
  138. </h1>
  139. </div>
  140. <div class="row bannerList">
  141. {% if app_img|length %}
  142. {% for i in app_img %}
  143. <div class="col-xs-6 col-sm-6 col-md-4 col-lg-3">
  144. <div class="showimg">
  145. <img src="{{i.img}}" alt="">
  146. <div class="bottomDiv">
  147. <a href="javascipt:;" onclick="del('{{i.id}}')"><i class="fa fa-trash" aria-hidden="true"></i> 删除</a>
  148. </div>
  149. </div>
  150. </div>
  151. {% endfor %}
  152. {% else %}
  153. <div class="vrnull">
  154. <div><img src="../static/img/vrnull.png" alt=""></div>
  155. <div>暂无数据</div>
  156. </div>
  157. {% endif %}
  158. </div>
  159. </div>
  160. <div style="display: none" class="tailoring-container">
  161. <div class="black-cloth" onclick="closeTailor(this)"></div>
  162. <div class="tailoring-content">
  163. <div class="tailoring-content-one">
  164. <label title="上传图片" for="chooseImg" class="l-btn choose-btn">
  165. <input type="file" accept="image/jpg,image/jpeg,image/png" name="file" id="chooseImg" class="hidden" onchange="selectImg(this)"> 选择图片
  166. </label>
  167. <div class="close-tailoring" onclick="closeTailor(this)">×</div>
  168. </div>
  169. <div class="tailoring-content-two">
  170. <div class="tailoring-box-parcel">
  171. <img id="tailoringImg">
  172. </div>
  173. <div class="preview-box-parcel">
  174. <p>图片预览:</p>
  175. <div class="square previewImg"></div>
  176. <!-- <div class="circular previewImg"></div> -->
  177. </div>
  178. </div>
  179. <div class="tailoring-content-three">
  180. <button class="l-btn cropper-reset-btn">复位</button>
  181. <button class="l-btn cropper-rotate-btn">旋转</button>
  182. <button class="l-btn cropper-scaleX-btn">换向</button>
  183. <button class="l-btn sureCut" id="sureCut">确定</button>
  184. </div>
  185. </div>
  186. </div>
  187. <div id="hint"></div>
  188. <!-- <script src="{% static '/lib/js/jquery-2.1.4.min.js' %}"></script> -->
  189. <script src="{% static '/lib/layui/layui.all.js' %}"></script>
  190. <script src="http://www.jq22.com/jquery/jquery-1.10.2.js"></script>
  191. <script src="{% static '/lib/js/cropper.js' %}" type="text/javascript" charset="utf-8"></script>
  192. <script>
  193. //弹出框水平垂直居中
  194. (window.onresize = function () {
  195. var win_height = $(window).height();
  196. var win_width = $(window).width();
  197. if (win_width <= 768) {
  198. $(".tailoring-content").css({
  199. "top": (win_height - $(".tailoring-content").outerHeight()) / 2,
  200. "left": 0
  201. });
  202. } else {
  203. $(".tailoring-content").css({
  204. "top": (win_height - $(".tailoring-content").outerHeight()) / 2,
  205. "left": (win_width - $(".tailoring-content").outerWidth()) / 2
  206. });
  207. }
  208. })();
  209. //弹出图片裁剪框
  210. $("#replaceImg").on("click", function () {
  211. $(".tailoring-container").toggle();
  212. });
  213. //图像上传
  214. function selectImg(file) {
  215. if (!file.files || !file.files[0]) {
  216. return;
  217. }
  218. var reader = new FileReader();
  219. reader.onload = function (evt) {
  220. var replaceSrc = evt.target.result;
  221. //更换cropper的图片
  222. $('#tailoringImg').cropper('replace', replaceSrc, false);//默认false,适应高度,不失真
  223. }
  224. reader.readAsDataURL(file.files[0]);
  225. }
  226. //cropper图片裁剪
  227. $('#tailoringImg').cropper({
  228. aspectRatio: 75 / 37,//默认比例
  229. viewMode: 1,
  230. preview: '.previewImg',//预览视图
  231. guides: false, //裁剪框的虚线(九宫格)
  232. autoCropArea: 0.5, //0-1之间的数值,定义自动剪裁区域的大小,默认0.8
  233. movable: false, //是否允许移动图片
  234. dragCrop: true, //是否允许移除当前的剪裁框,并通过拖动来新建一个剪裁框区域
  235. movable: true, //是否允许移动剪裁框
  236. resizable: true, //是否允许改变裁剪框的大小
  237. zoomable: false, //是否允许缩放图片大小
  238. mouseWheelZoom: false, //是否允许通过鼠标滚轮来缩放图片
  239. touchDragZoom: true, //是否允许通过触摸移动来缩放图片
  240. rotatable: true, //是否允许旋转图片
  241. crop: function (e) {
  242. // 输出结果数据裁剪图像。
  243. }
  244. });
  245. //旋转
  246. $(".cropper-rotate-btn").on("click", function () {
  247. $('#tailoringImg').cropper("rotate", 45);
  248. });
  249. //复位
  250. $(".cropper-reset-btn").on("click", function () {
  251. $('#tailoringImg').cropper("reset");
  252. });
  253. //换向
  254. var flagX = true;
  255. $(".cropper-scaleX-btn").on("click", function () {
  256. if (flagX) {
  257. $('#tailoringImg').cropper("scaleX", -1);
  258. flagX = false;
  259. } else {
  260. $('#tailoringImg').cropper("scaleX", 1);
  261. flagX = true;
  262. }
  263. flagX != flagX;
  264. });
  265. //裁剪后的处理
  266. $("#sureCut").on("click", function () {
  267. if ($("#tailoringImg").attr("src") == null) {
  268. return false;
  269. } else {
  270. var cas = $('#tailoringImg').cropper('getCroppedCanvas');//获取被裁剪后的canvas
  271. var base64url = cas.toDataURL('image/png'); //转换为base64地址形式
  272. $("#finalImg").prop("src", base64url);//显示为图片的形式
  273. savemsg(base64url)
  274. //关闭裁剪框
  275. closeTailor();
  276. }
  277. });
  278. //关闭裁剪框
  279. function closeTailor() {
  280. $(".tailoring-container").toggle();
  281. }
  282. function savemsg(base64url) {
  283. var fileObj = dataURLtoFile(base64url, 'filename')
  284. var formFile = new FormData();
  285. formFile.append("photo", fileObj);
  286. var data = formFile;
  287. $.ajax({
  288. url: "app_img_upload",
  289. data: data,
  290. type: "Post",
  291. dataType: "json",
  292. cache: false,//上传文件无需缓存
  293. processData: false,//用于对data参数进行序列化处理 这里必须false
  294. contentType: false, //必须
  295. success: function (result) {
  296. $('#hint').html('保存成功');
  297. $('#hint').show();
  298. $('#hint').fadeOut(2000)
  299. location.reload();
  300. },
  301. })
  302. }
  303. function dataURLtoFile(dataurl, filename) {
  304. var arr = dataurl.split(',');
  305. var mime = arr[0].match(/:(.*?);/)[1];
  306. var bstr = atob(arr[1]);
  307. var n = bstr.length;
  308. var u8arr = new Uint8Array(n);
  309. while (n--) {
  310. u8arr[n] = bstr.charCodeAt(n);
  311. }
  312. //转换成file对象
  313. return new File([u8arr], filename, { type: mime });
  314. //转换成成blob对象
  315. //return new Blob([u8arr],{type:mime});
  316. }
  317. function del(id) {
  318. layer.confirm('您确定要删除此轮播图?', {
  319. btn: ['确定', '取消'] //按钮
  320. }, function () {
  321. $.ajax({
  322. url: 'app_img_delete',
  323. type: 'post',
  324. data: {
  325. id: id
  326. },
  327. success: function (data) {
  328. if (data == 1) {
  329. layer.closeAll();
  330. location.reload();
  331. } else {
  332. layer.msg('删除失败!', { icon: 2 });
  333. }
  334. },
  335. error: function (type) {
  336. layer.msg('删除失败!', { icon: 2 });
  337. }
  338. })
  339. }, function () {
  340. });
  341. }
  342. </script>
  343. </body>
  344. </html>