From 4232dfc7832846013e623d13f6157ee1e371bda3 Mon Sep 17 00:00:00 2001 From: wpxp123456 <2677556700@qq.com> Date: Fri, 28 Aug 2020 17:45:37 +0800 Subject: [PATCH] feat(image insert): image insert image insert --- src/controllers/constant.js | 55 ++++++ src/controllers/handler.js | 169 +++++++++++++++++- src/controllers/imageCtrl.js | 283 ++++++++++++++++++++++++++++++ src/css/luckysheet-core.css | 218 +++++++++++++++++++++++ src/expendPlugins/chart/plugin.js | 8 +- 5 files changed, 728 insertions(+), 5 deletions(-) create mode 100644 src/controllers/imageCtrl.js diff --git a/src/controllers/constant.js b/src/controllers/constant.js index 3731014a1..12739a513 100644 --- a/src/controllers/constant.js +++ b/src/controllers/constant.js @@ -127,6 +127,57 @@ const gridHTML = function(){
+
+ + +
\${flow} @@ -1209,6 +1260,10 @@ function menuToolBar (){ ${toolbar.splitColumn} + +
+ 插入图片 +
`; } diff --git a/src/controllers/handler.js b/src/controllers/handler.js index f3182ede9..559070e2e 100644 --- a/src/controllers/handler.js +++ b/src/controllers/handler.js @@ -4,6 +4,7 @@ import luckysheetFreezen from './freezen'; import pivotTable from './pivotTable'; import luckysheetDropCell from './dropCell'; import luckysheetPostil from './postil'; +import imageCtrl from './imageCtrl'; import menuButton from './menuButton'; import conditionformat from './conditionformat'; import alternateformat from './alternateformat'; @@ -1922,6 +1923,119 @@ export default function luckysheetHandler() { // resize chart Store.resizeChart(Store.chartparam.luckysheetCurrentChart) } + //image move + else if (imageCtrl.move) { + let mouse = mouseposition(event.pageX, event.pageY); + let x = mouse[0] + $("#luckysheet-cell-main").scrollLeft(); + let y = mouse[1] + $("#luckysheet-cell-main").scrollTop(); + + let myh = $("#luckysheet-modal-dialog-activeImage").outerHeight(), + myw = $("#luckysheet-modal-dialog-activeImage").outerWidth(); + + let top = y - imageCtrl.moveXY[1], + left = x - imageCtrl.moveXY[0]; + + if (top < 0) { + top = 0; + } + + if (top + myh + 42 + 6 > imageCtrl.currentWinH) { + top = imageCtrl.currentWinH - myh - 42 - 6; + } + + if (left < 0) { + left = 0; + } + + if (left + myw + 22 + 36 > imageCtrl.currentWinW) { + left = imageCtrl.currentWinW - myw - 22 - 36; + } + + $("#luckysheet-modal-dialog-activeImage").css({ "left": left, "top": top }); + } + //image resize + else if (!!imageCtrl.resize) { + let mouse = mouseposition(event.pageX, event.pageY); + let x = mouse[0] + $("#luckysheet-cell-main").scrollLeft(); + let y = mouse[1] + $("#luckysheet-cell-main").scrollTop(); + + if (x < 0 || y < 0) { + return false; + } + + let resizeXY = imageCtrl.resizeXY; + + let topchange = y - resizeXY[1], + leftchange = x - resizeXY[0]; + + let top = resizeXY[5], + height = resizeXY[3], + left = resizeXY[4], + width = resizeXY[2]; + + let resize = imageCtrl.resize; + + if (resize == "lm" || resize == "lt" || resize == "lb") { + left = x; + width = resizeXY[2] - leftchange; + + if (left > resizeXY[2] + resizeXY[4] - 60) { + left = resizeXY[2] + resizeXY[4] - 60; + width = resizeXY[2] - (resizeXY[2] + resizeXY[4] - 60 - resizeXY[0]); + } + else if (left <= 0) { + left = 0; + width = resizeXY[2] + resizeXY[0]; + } + } + + if (resize == "rm" || resize == "rt" || resize == "rb") { + width = resizeXY[2] + leftchange; + + if (width < 60) { + width = 60; + } + else if (width >= imageCtrl.currentWinW - resizeXY[4] - 22 - 36) { + width = imageCtrl.currentWinW - resizeXY[4] - 22 - 36; + } + } + + if (resize == "mt" || resize == "lt" || resize == "rt") { + top = y; + height = resizeXY[3] - topchange; + + if (top > resizeXY[3] + resizeXY[5] - 60) { + top = resizeXY[3] + resizeXY[5] - 60; + height = resizeXY[3] - (resizeXY[3] + resizeXY[5] - 60 - resizeXY[1]); + } + else if (top <= 0) { + top = 0; + height = resizeXY[3] + resizeXY[1]; + } + } + + if (resize == "mb" || resize == "lb" || resize == "rb") { + height = resizeXY[3] + topchange; + + if (height < 60) { + height = 60; + } + else if (height >= imageCtrl.currentWinH - resizeXY[5] - 42 - 6) { + height = imageCtrl.currentWinH - resizeXY[5] - 42 - 6; + } + } + + $("#luckysheet-modal-dialog-activeImage").css({ + "width": width, + "height": height, + "left": left, + "top": top + }); + $("#luckysheet-modal-dialog-activeImage .luckysheet-modal-dialog-content").css({ + "background-size": width + "px " + height + "px", + "background-position": "0px 0px" + }) + } else if (luckysheetPostil.move) { let mouse = mouseposition(event.pageX, event.pageY); let x = mouse[0] + $("#luckysheet-cell-main").scrollLeft(); @@ -2029,7 +2143,8 @@ export default function luckysheetHandler() { } else if (!!formula.rangeMove) { formula.rangeMoveDraging(event, formula.rangeMovexy, formula.rangeMoveObj.data("range"), formula.rangeMoveObj, Store.sheetBarHeight, Store.statisticBarHeight); - } else if (!!Store.chart_selection.rangeResize) { + } + else if (!!Store.chart_selection.rangeResize) { Store.chart_selection.rangeResizeDraging(event, Store.sheetBarHeight, Store.statisticBarHeight); } else if (!!Store.chart_selection.rangeMove) { @@ -2208,6 +2323,16 @@ export default function luckysheetHandler() { formula.rangeResizeDragged(event, formula.rangeResizeObj, formula.rangeResize, formula.rangeResizexy, formula.rangeResizeWinW, formula.rangeResizeWinH); } + //image move + if (imageCtrl.move) { + imageCtrl.moveImgItem(); + } + + //image resize + if (imageCtrl.resize) { + imageCtrl.resizeImgItem(); + } + //批注框 移动 if (luckysheetPostil.move) { luckysheetPostil.move = false; @@ -3414,6 +3539,48 @@ export default function luckysheetHandler() { splitColumn.init(); }); + //菜单栏 插入图片按钮 + $("#luckysheet-insertImg-btn-title").click(function () { + $("#luckysheet-imgUpload").click(); + }); + $("#luckysheet-imgUpload").click(function (e) { + e.stopPropagation(); + }); + $("#luckysheet-imgUpload").on("change", function(e){ + let file = e.currentTarget.files[0]; + let render = new FileReader(); + render.readAsDataURL(file); + + render.onload = function(event){ + let src = event.target.result; + + let rowIndex = Store.luckysheet_select_save[0].row_focus; + let colIndex = Store.luckysheet_select_save[0].column_focus; + let left = colIndex == 0 ? 0 : Store.visibledatacolumn[colIndex - 1]; + let top = rowIndex == 0 ? 0 : Store.visibledatarow[rowIndex - 1]; + + let image = new Image(); + image.onload = function(){ + let width = image.width, + height = image.height; + + let img = { + src: src, + left: left, + top: top, + originWidth: width, + originHeight: height + } + + imageCtrl.addImgItem(img); + $("#luckysheet-imgUpload").val(""); + } + image.src = src; + } + }); + + + //冻结行列 $("#luckysheet-freezen-btn-horizontal").click(function () { if ($.trim($(this).text()) == locale().freezen.freezenCancel) { diff --git a/src/controllers/imageCtrl.js b/src/controllers/imageCtrl.js new file mode 100644 index 000000000..c4fe94ab9 --- /dev/null +++ b/src/controllers/imageCtrl.js @@ -0,0 +1,283 @@ +import { + rowLocation, + colLocation, + mouseposition +} from '../global/location'; +import { setluckysheet_scroll_status } from '../methods/set'; + +const imageCtrl = { + imgItem: { + src: '', //图片url + originWidth: null, //图片原始宽度 + originHeight: null, //图片原始高度 + default: { + width: null, //图片 宽度 + height: null, //图片 高度 + left: null, //图片离表格左边的 位置 + top: null, //图片离表格顶部的 位置 + }, + crop: { + width: null, //图片裁剪后 宽度 + height: null, //图片裁剪后 高度 + offsetLeft: 0, //图片裁剪后离未裁剪时 左边的位移 + offsetTop: 0, //图片裁剪后离未裁剪时 顶部的位移 + } + }, + images: null, + currentImgId: null, + currentWinW: null, + currentWinH: null, + resize: null, + resizeXY: null, + move: false, + moveXY: null, + generateRandomId: function(prefix) { + if(prefix == null){ + prefix = "img"; + } + + let userAgent = window.navigator.userAgent.replace(/[^a-zA-Z0-9]/g, "").split(""); + + let mid = ""; + + for(let i = 0; i < 12; i++){ + mid += userAgent[Math.round(Math.random() * (userAgent.length - 1))]; + } + + let time = new Date().getTime(); + + return prefix + "_" + mid + "_" + time; + }, + modelHtml: function(id, imgItem) { + let src = imgItem.src; + + let width = imgItem.default.width, + height = imgItem.default.height, + left = imgItem.default.left, + top = imgItem.default.top; + + return `
+
+ +
+
`; + }, + init: function() { + let _this = this; + + //image active + $("#luckysheet-image-showBoxs").off("mousedown.active").on("mousedown.active", ".luckysheet-modal-dialog-image", function(e) { + $(this).hide(); + + let id = $(this).attr("id"); + _this.currentImgId = id; + + let item = _this.images[id]; + + let width = item.default.width, + height = item.default.height, + left = item.default.left, + top = item.default.top; + + if(item.crop.width != width || item.crop.height != height){ + width = item.crop.width; + height = item.crop.height; + left = left + item.crop.offsetLeft; + top = top + item.crop.offsetTop; + } + + $("#luckysheet-modal-dialog-activeImage").show().css({ + "width": width, + "height": height, + "left": left, + "top": top + }); + + $("#luckysheet-modal-dialog-activeImage .luckysheet-modal-dialog-content").css({ + "background-image": "url(" + item.src + ")", + "background-size": item.default.width + "px " + item.default.height + "px", + "background-position": -item.crop.offsetLeft + "px " + -item.crop.offsetTop + "px" + }) + + e.stopPropagation(); + }) + + //image move + $("#luckysheet-modal-dialog-activeImage").off("mousedown.move").on("mousedown.move", ".luckysheet-modal-dialog-content", function(e) { + _this.move = true; + + _this.currentWinW = $("#luckysheet-cell-main")[0].scrollWidth; + _this.currentWinH = $("#luckysheet-cell-main")[0].scrollHeight; + + let scrollTop = $("#luckysheet-cell-main").scrollTop(), + scrollLeft = $("#luckysheet-cell-main").scrollLeft(); + + let offset = $("#luckysheet-modal-dialog-activeImage").offset(); + let position = $("#luckysheet-modal-dialog-activeImage").position(); + + _this.moveXY = [ + e.pageX - offset.left, + e.pageY - offset.top, + position.left, + position.top, + scrollLeft, + scrollTop + ]; + + setluckysheet_scroll_status(true); + + e.stopPropagation(); + }) + + //image resize + $("#luckysheet-modal-dialog-activeImage").off("mousedown.resize").on("mousedown.resize", ".luckysheet-modal-dialog-resize-item", function(e) { + _this.currentWinW = $("#luckysheet-cell-main")[0].scrollWidth; + _this.currentWinH = $("#luckysheet-cell-main")[0].scrollHeight; + + _this.resize = $(this).data("type"); + + let scrollTop = $("#luckysheet-cell-main").scrollTop(), + scrollLeft = $("#luckysheet-cell-main").scrollLeft(); + let mouse = mouseposition(e.pageX, e.pageY); + let x = mouse[0] + scrollLeft; + let y = mouse[1] + scrollTop; + + let position = $("#luckysheet-modal-dialog-activeImage").position(); + let width = $("#luckysheet-modal-dialog-activeImage").width(); + let height = $("#luckysheet-modal-dialog-activeImage").height(); + + _this.resizeXY = [ + x, + y, + width, + height, + position.left + scrollLeft, + position.top + scrollTop, + scrollLeft, + scrollTop + ]; + + setluckysheet_scroll_status(true); + + e.stopPropagation(); + }) + + //image crop + $("#luckysheet-modal-dialog-activeImage").off("mousedown.crop").on("mousedown.crop", ".luckysheet-modal-controll-crop", function(e) { + $("#luckysheet-modal-dialog-activeImage").hide(); + + let item = _this.images[_this.currentImgId]; + + let width = item.default.width, + height = item.default.height, + left = item.default.left, + top = item.default.top; + + if(item.crop.width != width || item.crop.height != height){ + width = item.crop.width; + height = item.crop.height; + left = left + item.crop.offsetLeft; + top = top + item.crop.offsetTop; + } + + $("#luckysheet-modal-dialog-cropping").show().css({ + "width": width, + "height": height, + "left": left, + "top": top + }); + + $("#luckysheet-modal-dialog-cropping .cropping-mask").css({ + "width": item.default.width, + "height": item.default.height, + "background-image": "url(" + item.src + ")", + "left": -item.crop.offsetLeft, + "top": -item.crop.offsetTop + }) + + $("#luckysheet-modal-dialog-cropping .cropping-content").css({ + "background-image": "url(" + item.src + ")", + "background-size": item.default.width + "px " + item.default.height + "px", + "background-position": -item.crop.offsetLeft + "px " + -item.crop.offsetTop + "px" + }) + + e.stopPropagation(); + }) + + //image delete + $("#luckysheet-modal-dialog-activeImage").off("mousedown.delete").on("mousedown.delete", ".luckysheet-modal-controll-del", function(e) { + _this.removeImgItem(); + }) + + }, + addImgItem: function(img) { + let _this = this; + + let width, height; + let max = 400; + + if(img.originHeight < img.originWidth){ + height = Math.round(img.originHeight * (max / img.originWidth)); + width = max; + } + else{ + width = Math.round(img.originWidth * (max / img.originHeight)); + height = max; + } + + if(_this.images == null){ + _this.images = {}; + } + + let imgItem = $.extend(true, {}, _this.imgItem); + imgItem.src = img.src; + imgItem.originWidth = img.originWidth; + imgItem.originHeight = img.originHeight; + imgItem.default.width = width; + imgItem.default.height = height; + imgItem.default.left = img.left; + imgItem.default.top = img.top; + imgItem.crop.width = width; + imgItem.crop.height = height; + + let id = _this.generateRandomId(); + let modelHtml = _this.modelHtml(id, imgItem); + + $("#luckysheet-image-showBoxs").append(modelHtml); + + _this.images[id] = imgItem; + + _this.init(); + }, + moveImgItem: function() { + let _this = this; + + _this.move = false; + + let position = $("#luckysheet-modal-dialog-activeImage").position(); + _this.images[_this.currentImgId].left = position.left; + _this.images[_this.currentImgId].top = position.top; + }, + resizeImgItem: function() { + let _this = this; + + _this.resize = null; + + let position = $("#luckysheet-modal-dialog-activeImage").position(); + let width = $("#luckysheet-modal-dialog-activeImage").outerWidth(); + let height = $("#luckysheet-modal-dialog-activeImage").outerHeight(); + + _this.images[_this.currentImgId].width = width; + _this.images[_this.currentImgId].height = height; + _this.images[_this.currentImgId].left = position.left; + _this.images[_this.currentImgId].top = position.top; + }, + removeImgItem: function() { + let _this = this; + + delete _this.images[_this.currentImgId]; + $("#luckysheet-modal-dialog-activeImage").hide(); + }, +} + +export default imageCtrl; \ No newline at end of file diff --git a/src/css/luckysheet-core.css b/src/css/luckysheet-core.css index 9965371df..777039edf 100644 --- a/src/css/luckysheet-core.css +++ b/src/css/luckysheet-core.css @@ -6397,3 +6397,221 @@ fieldset[disabled] a.btn { background: #FC6666; cursor: pointer; } + +/* 图片 */ +#luckysheet-modal-dialog-activeImage .luckysheet-modal-dialog-content{ + width: 100%; + height: 100%; + position: absolute; + left: 0; + top: 0; + cursor: move; +} +#luckysheet-modal-dialog-cropping::before{ + content: ""; + outline: 1px solid #fff; + position: absolute; + left: 33.3%; + right: 33.3%; + top: 0; + bottom: 0; + z-index: 1; + pointer-events: none; +} +#luckysheet-modal-dialog-cropping::after{ + content: ""; + outline: 1px solid #fff; + position: absolute; + left: 0; + right: 0; + top: 33.3%; + bottom: 33.3%; + z-index: 1; + pointer-events: none; +} +#luckysheet-modal-dialog-cropping .cropping-mask{ + filter: brightness(.5); + position: absolute; + background-size: 100% 100%; + left: 0; + top: 0; +} +#luckysheet-modal-dialog-cropping .cropping-content{ + position: absolute; + overflow: hidden; + background-position: 0 0; + left: 0; + top: 0; + width: 100%; + height: 100%; +} +#luckysheet-modal-dialog-cropping .luckysheet-modal-dialog-resize{ + border: none; + position: absolute; + margin: 0px; + padding: 0px; + top: 0; + left: 0; + bottom: 0; + right: 0; +} +#luckysheet-modal-dialog-cropping .resize-item{ + width: 0; + height: 0; + background: none; + border: none; + position: absolute; + z-index: 3; +} +#luckysheet-modal-dialog-cropping .resize-item::before{ + content: ""; + display: block; + position: absolute; + background: #000; +} +#luckysheet-modal-dialog-cropping .resize-item::after{ + content: ""; + display: block; + position: absolute; + background: #000; +} +#luckysheet-modal-dialog-cropping .lt{ + left: 0; + top: 0; + cursor: nwse-resize; +} +#luckysheet-modal-dialog-cropping .lt::before{ + width: 18px; + height: 4px; + left: 0; + top: 0; + border-right: 2px solid #fff; + border-bottom: 2px solid #fff; +} +#luckysheet-modal-dialog-cropping .lt::after{ + width: 4px; + height: 14px; + left: 0; + top: 4px; + border-right: 2px solid #fff; + border-bottom: 2px solid #fff; +} +#luckysheet-modal-dialog-cropping .mt{ + left: 50%; + top: 0; + cursor: ns-resize; +} +#luckysheet-modal-dialog-cropping .mt::before{ + width: 18px; + height: 4px; + left: -11px; + top: 0; + border-left: 2px solid #fff; + border-right: 2px solid #fff; + border-bottom: 2px solid #fff; +} +#luckysheet-modal-dialog-cropping .rt{ + right: 0; + top: 0; + cursor: nesw-resize; +} +#luckysheet-modal-dialog-cropping .rt::before{ + width: 18px; + height: 4px; + right: 0; + top: 0; + border-left: 2px solid #fff; + border-bottom: 2px solid #fff; +} +#luckysheet-modal-dialog-cropping .rt::after{ + width: 4px; + height: 14px; + right: 0; + top: 4px; + border-left: 2px solid #fff; + border-bottom: 2px solid #fff; +} +#luckysheet-modal-dialog-cropping .lm{ + left: 0; + top: 50%; + cursor: ew-resize; +} +#luckysheet-modal-dialog-cropping .lm::before{ + width: 4px; + height: 18px; + left: 0; + top: -11px; + border-right: 2px solid #fff; + border-top: 2px solid #fff; + border-bottom: 2px solid #fff; +} +#luckysheet-modal-dialog-cropping .rm{ + right: 0; + top: 50%; + cursor: ew-resize; +} +#luckysheet-modal-dialog-cropping .rm::before{ + width: 4px; + height: 18px; + right: 0; + top: -11px; + border-left: 2px solid #fff; + border-top: 2px solid #fff; + border-bottom: 2px solid #fff; +} +#luckysheet-modal-dialog-cropping .lb{ + left: 0; + bottom: 0; + cursor: nesw-resize; +} +#luckysheet-modal-dialog-cropping .lb::before{ + width: 18px; + height: 4px; + left: 0; + bottom: 0; + border-right: 2px solid #fff; + border-top: 2px solid #fff; +} +#luckysheet-modal-dialog-cropping .lb::after{ + width: 4px; + height: 14px; + left: 0; + bottom: 4px; + border-right: 2px solid #fff; + border-top: 2px solid #fff; +} +#luckysheet-modal-dialog-cropping .rb{ + right: 0; + bottom: 0; + cursor: nwse-resize; +} +#luckysheet-modal-dialog-cropping .rb::before{ + width: 18px; + height: 4px; + right: 0; + bottom: 0; + border-left: 2px solid #fff; + border-top: 2px solid #fff; +} +#luckysheet-modal-dialog-cropping .rb::after{ + width: 4px; + height: 14px; + right: 0; + bottom: 4px; + border-left: 2px solid #fff; + border-top: 2px solid #fff; +} +#luckysheet-modal-dialog-cropping .mb{ + left: 50%; + bottom: 0; + cursor: ns-resize; +} +#luckysheet-modal-dialog-cropping .mb::before{ + width: 18px; + height: 4px; + left: -11px; + bottom: 0; + border-left: 2px solid #fff; + border-right: 2px solid #fff; + border-top: 2px solid #fff; +} \ No newline at end of file diff --git a/src/expendPlugins/chart/plugin.js b/src/expendPlugins/chart/plugin.js index 0132c46cb..adc57b8b2 100644 --- a/src/expendPlugins/chart/plugin.js +++ b/src/expendPlugins/chart/plugin.js @@ -1387,10 +1387,10 @@ function selectRangeBorderShow(chart_id) { //luckysheet取cell-main,后续扩展到其他的用户自定义元素 $('#luckysheet-cell-main') - .find('.luckysheet-modal-dialog-resize') + .find('.luckysheet-modal-dialog-chart .luckysheet-modal-dialog-resize') .hide() $('#luckysheet-cell-main') - .find('.luckysheet-modal-dialog-controll') + .find('.luckysheet-modal-dialog-chart .luckysheet-modal-dialog-controll') .hide() $t.css('z-index', chartInfo.chartparam.luckysheetCurrentChartZIndexRank++) @@ -1413,7 +1413,7 @@ function selectRangeBorderShow(chart_id) { //选择区域高亮隐藏 function selectRangeBorderHide(settingShow) { - $('#luckysheet-cell-main .luckysheet-modal-dialog-resize, #luckysheet-cell-main .luckysheet-modal-dialog-controll').hide() + $('#luckysheet-cell-main .luckysheet-modal-dialog-chart .luckysheet-modal-dialog-resize, #luckysheet-cell-main .luckysheet-modal-dialog-chart .luckysheet-modal-dialog-controll').hide() $('#luckysheet-cell-main').find('.luckysheet-datavisual-selection-set div').remove() chartInfo.chartparam.luckysheetCurrentChartActive = false @@ -1447,7 +1447,7 @@ function hideChartSettingComponent(refresh) { //隐藏设置界面 $('.chartSetting').hide(); //.luckysheet-modal-dialog-resize为图表显示框的缩放框,.luckysheet-modal-dialog-controll为显示框右边的控制按钮 - $('#luckysheet-cell-main .luckysheet-modal-dialog-resize, #luckysheet-cell-main .luckysheet-modal-dialog-controll').hide() + $('#luckysheet-cell-main .luckysheet-modal-dialog-chart .luckysheet-modal-dialog-resize, #luckysheet-cell-main .luckysheet-modal-dialog-chart .luckysheet-modal-dialog-controll').hide() $('#luckysheet-cell-main').find('.luckysheet-datavisual-selection-set div').remove()