| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804 |
- <!-- -->
- <template>
- <el-dialog title="编辑图片"
- style="padding:10px 0px 0px 0px;margin-top:0 !important;"
- class="myDialog"
- width="90%"
- top="0"
- :modal-append-to-body="false"
- :append-to-body="false"
- :close-on-click-modal="false"
- @close="closeWindow"
- :visible.sync="dialogFormVisible">
- <el-container class="outSide">
- <!-- <el-header style="height:100%;">
- <el-form :inline="true" class="demo-form-inline" style="text-align:center;height:40px;">
- <el-form-item label="画布宽度" style="margin-bottom: 0px;margin-right: 0px;">
- <el-input style="width:80px;" v-model="changeCanvasWidth" placeholder="宽"></el-input>
- </el-form-item>
- <i class="el-icon-close" style="padding:10px;"></i>
- <el-form-item style="margin-bottom: 0px;margin-right: 0px;">
- <el-input style="width:80px;" v-model="changeCanvasHeight" placeholder="高"></el-input>
- </el-form-item>
- <el-form-item style="margin-bottom: 0px;margin-right: 0px;">
- <el-button type="text" icon="el-icon-refresh" @click="changeCanvasSize"></el-button>
- </el-form-item>
- </el-form>
- </el-header> -->
- <el-main style="padding:0 3px 10px 3px;" >
- <!-- 绘制基础图层操作都是在这个里面进行的 -->
- <canvas id="canvas" style="margin: 0 auto;" :width="this.canvasWidth" :height="this.canvasHeight" ></canvas>
- <!-- 隐藏的图层====>是给剪切用的 -->
- <canvas v-if="false" id="canvas_crop"></canvas>
- </el-main>
- <el-footer style="padding:10px 3px;width: 30%;margin: 0 auto;height: 100%;">
- <el-card style="padding: 10px;" class="myCard">
- <!-- <div style="width:32px;height:32px;" class="cut_pic" @click="clipImage"></div> -->
- <el-row>
- <el-col :span="13">
- <el-popover
- style="min-width:95px;width:95px;z-index:20000;!important"
- placement="bottom"
- width="50"
- trigger="click">
- <div>
- <el-button type="text" v-if="showCutButton" @click="chooseCutArea">框选裁剪区域</el-button>
- <el-button type="text" v-if="!showCutButton" @click="clipImage">裁剪</el-button>
- </div>
- <div style="width:32px;height:32px;" slot="reference" class="cut_pic"></div>
- </el-popover><!--剪裁图层-->
- <!-- <div style="width:32px;height:32px;" class="turn_left" @click="flip"></div> -->
- <el-popover
- placement="bottom"
- width="400"
- trigger="click">
- <div>
- <ChooseLocalPic
- @addPicUrl="addPicUrlEvent">
- </ChooseLocalPic>
- </div>
- <div style="width:32px;height:32px;" slot="reference" class="add_pic_button"></div>
- </el-popover><!--添加图片-->
- <el-popover
- placement="bottom"
- width="400"
- trigger="click">
- <div>
- <ColorPicker
- @colorPickerFor_text="colorPickerFor_textEvent">
- </ColorPicker>
- </div>
- <div style="width:32px;height:32px;" slot="reference" class="add_text_button"></div>
- </el-popover><!--添加文字-->
- <el-tooltip class="item" effect="dark" content="重做" placement="bottom-start">
- <div id="redo" style="width:32px;height:32px;" class="refresh" @click="redoEvent"></div><!--全部重做-->
- </el-tooltip>
- <el-tooltip class="item" effect="dark" content="删除元素" placement="bottom-start">
- <div style="width:32px;height:32px;" class="deleteSelect" @click="deleteSelect"></div><!--删除选中图层-->
- </el-tooltip>
- <el-tooltip class="item" effect="dark" content="撤销操作" placement="bottom-start">
- <div style="width:32px;height:32px;" id="undo" class="undo" @click="unDoEvent"></div><!--返回上一步操作-->
- </el-tooltip>
- </el-col>
- <el-col :span="11" style="text-align:right;">
- <el-button style="" type="primary" icon="el-icon-download" @click="unloadEvent">下载到本地</el-button>
- <el-button style="" type="primary" icon="el-icon-upload2" @click="changeImageTo64baseCode">保存</el-button>
- </el-col>
- </el-row>
- </el-card>
- </el-footer>
- </el-container>
- </el-dialog>
- </template>
- <script>
- //这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
- //例如:import 《组件名称》 from '《组件路径》';
- //例如:import {函数名称1,函数名称2} from '《组件路径》';
- /*
- @ 模块名称:现在编辑图片
- @ 介绍:使用fabric插件初步实现图片编辑功能
- @ author:zhangyz
- @ version:0.0.1
- @ to-do list:
- @ 传递参数:picUrl(父组件的图片地址)
- */
- export default {
- //import引入的组件需要注入到对象中才能使用
- props:['picUrl'],
- components: {
- //1、直接挂载
- //组件名称1,
- //组件名称2,
- //2、懒加载
- //组件名称1: resolve => {require(['组件名称1.vue'], resolve);}
- ColorPicker: resolve => {
- require(["./ColorPicker.vue"], resolve);
- },
- ChooseLocalPic: resolve => {
- require(["./ChooseLocalPic.vue"], resolve);
- },
- },
- data() {
- return {
- //这里存放数据
- changeCanvasWidth:"",
- changeCanvasHeight:"",
- dialogFormVisible:true,
- canvasChangeSizeShow:true,
- elMain:false,
- dataURL:"",
- backgroudColor:'background: red;',
- canvasWidth:parseInt(window.innerWidth / 1.5),
- canvasHeight:parseInt(window.innerHeight / 1.5),
- a: [],
- cardPublic:null,
- rectPublic:null,
- textbox_Public:null,
- textLocation_left:50,
- textLocation_top:50,
- text_color:'red',
- obj_Pub:{},
- num: 1,
- pos: [0, 0],
- rvg:null,
- mousex:0,
- mousey:0,
- crop:false,
- disabled:false,
- object:null,
- objectCut:null,
- lastActive:null,
- el:null,
- selection_object_left: 0,
- selection_object_top: 0,
- isCropping: false,
- buttonConType: true,
- showCutButton: true,
- config : {
- canvasState : [],
- currentStateIndex : -1,
- redoStatus : false, //撤销状态
- undoStatus : false, // 重做状态
- undoFinishedStatus : 1,
- redoFinishedStatus : 1,
- undoButton : this.$refs.undo,
- redoButton : this.$refs.redo,
- }
- };
- },
- computed: {
- //监听属性 类似于data概念
- },
- watch: {
- //监控data中的数据变化
- picUrl(n,o){
- this.picUrl = n;
- this.initPicTools();
- this.canvasDataChange(); //监听canvas 事件
- }
- },
- methods: {
- //对话框初始化方法,代替mounted
- dialogMouted(){
- this.cardPublic = {};
- this.changeCanvasWidth = this.canvasWidth;
- this.changeCanvasHeight = this.canvasHeight;
- this.initPicTools();
- this.canvasDataChange(); //监听canvas 事件
- },
- changeCanvasSize(){
- this.canvasChangeSizeShow = false;
- this.canvasWidth = this.changeCanvasWidth;
- this.canvasHeight = this.changeCanvasHeight;
- this.canvasChangeSizeShow = true;
- },
- base64ToBlob ({b64data = '', contentType = '', sliceSize = 512} = {}) {
- return new Promise((resolve, reject) => {
- // 使用 atob() 方法将数据解码
- let byteCharacters = atob(b64data);
- let byteArrays = [];
- for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
- let slice = byteCharacters.slice(offset, offset + sliceSize);
- let byteNumbers = [];
- for (let i = 0; i < slice.length; i++) {
- byteNumbers.push(slice.charCodeAt(i));
- }
- // 8 位无符号整数值的类型化数组。内容将初始化为 0。
- // 如果无法分配请求数目的字节,则将引发异常。
- byteArrays.push(new Uint8Array(byteNumbers));
- }
- let result = new Blob(byteArrays, {
- type: contentType
- })
- result = Object.assign(result,{
- // jartto: 这里一定要处理一下 URL.createObjectURL
- preview: URL.createObjectURL(result),
- name: `图片示例.png`
- });
- resolve(result)
- })
- },
- //方法集合
- //初始化要修改的图片
- // getBase64Image(img) {
- // var canvas = document.createElement("canvas");
- // canvas.width = img.width;
- // canvas.height = img.height;
- // var ctx = canvas.getContext("2d");
- // ctx.drawImage(img, 0, 0, img.width, img.height);
- // var ext = img.src.substring(img.src.lastIndexOf(".")+1).toLowerCase();
- // canvas.setAttribute('crossOrigin', 'Anonymous');
- // var dataURL = canvas.toDataURL("image/"+ext);
- // return dataURL;
- // },
- //根据图片的URL转为64位码
- getBase64(url, callback){
- //通过构造函数来创建的 img 实例,在赋予 src 值后就会立刻下载图片,相比 createElement() 创建 <img> 省去了 append(),也就避免了文档冗余和污染
- var _self = this;
- _self.dataURL = _self.cardPublic.toDataURL("image/png"); //转换图片为dataURL
- callback?callback(_self.dataURL):null; //调用回调函数
- // var Img = new Image();
- // _self.dataURL="";
- // Img.src=url;
- // Img.setAttribute('crossOrigin', 'anonymous');
- // Img.onload=function(){ //要先确保图片完整获取到,这是个异步事件
- // var canvas = document.createElement("canvas"), //创建canvas元素
- // width = Img.width, //确保canvas的尺寸和图片一样
- // height = Img.height;
- // _self.cardPublic.width = width;
- // _self.cardPublic.height = height;
- // _self.cardPublic.getContext("2d").drawImage(Img,0,0,width,height); //将图片绘制到canvas中
- // _self.dataURL = canvas.toDataURL("image/png"); //转换图片为dataURL
- // callback?callback(_self.dataURL):null; //调用回调函数
- // };
- },
- //上传图片动作
- changeImageTo64baseCode(){
- var _self = this;
- var imgLink = _self.picUrl;
- this.cardPublic.backgroundColor = "transparent";
- // var tempImage = new Image();
- // tempImage.src = imgLink;
- // tempImage.setAttribute('crossOrigin', 'Anonymous');
- // tempImage.onload = function(){
- // var base64 = _self.getBase64Image(tempImage);
- // console.log(base64);
- // }
- this.getBase64(imgLink,(dataURL)=>{
- console.log(dataURL);
- var formData = new FormData();
- formData.append("file", _self.dataURLtoFile(dataURL,"zyz.png"));
- _self.$emit('editPicData',formData);
- let base64 = dataURL.split(',')[1]
- _self.base64ToBlob({b64data: base64, contentType: 'image/png'}).then(res => {
- console.log('blob', res)
- })
- });
- _self.object = {};
- _self.cardPublic = {};
- _self.canvasWidth = 12;
- _self.picUrl = "";
- },
- //将6位码转为图片
- dataURLtoFile(dataurl, filename) {//将base64转换为文件
- var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
- bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
- while(n--){
- u8arr[n] = bstr.charCodeAt(n);
- }
- return new File([u8arr], filename, {type:mime});
- },
- initPicTools(){
- var _self = this;
- //const canvas = new fabric.Canvas('canvas');
- this.cardPublic = new fabric.Canvas('canvas');//把 card对象给cardPublic供全局使用
- this.cardPublic.backgroundColor = "#848484";
- this.cardPublic.renderAll();
- // fabric.Image.fromURL('../src/assets/QQ20190913-000717@2x.png', (img) => {
- // img.set({
- // // 通过scale来设置图片大小,这里设置和画布一样大
- // scaleX: card.width / img.width,
- // scaleY: card.height / img.height,
- // });
- // // 设置背景
- // card.setBackgroundImage(img, card.renderAll.bind(card));
- // card.renderAll();
- // });
- // var rvg = document.getElementById('canvas').getBoundingClientRect();
- // _self.pos[0] = rvg.left;
- // _self.pos[1] = rvg.top;
- // let el = new fabric.Rect({
- // fill: 'transparent',
- // originX: 'left',
- // originY: 'top',
- // stroke: '#ccc',
- // strokeDashArray: [2, 2],
- // opacity: 1,
- // width: 1,
- // height: 1
- // });
- // el.visible = false;
- // _self.cardPublic.add(el);
- // let proxyPicUrl = _self.picUrl;
- // let proxyPicUrl = _self.picUrl.replace('10.1.102.136:8100','10.1.102.136:8080');
- // let proxyPicUrl = _self.picUrl.replace('10.1.102.136:8100','localhost:8085/api');
- let proxyPicUrl ="";
- console.log(window.location.href.split("/")[2])
- if(window.location.href.split("/")[2] == "10.1.102.64:8080"){
- console.log(_self.picUrl)
- proxyPicUrl = _self.picUrl.replace('10.1.102.240:8200','pdc.goldenwater.com.cn');
- }
- else if(window.location.href.split("/")[2] == "pdc.goldenwater.com.cn"){
- proxyPicUrl = _self.picUrl;
- }
- else{
- proxyPicUrl = _self.picUrl.replace('10.1.102.240:8200',window.location.href.split("/")[2] + "/pdcApi");
- }
- fabric.util.loadImage(proxyPicUrl, function (img) {
- // fabric.util.loadImage(_self.picUrl, function (img) {
- img.setAttribute('crossOrigin', 'anonymous');
- _self.object = new fabric.Image(img);
- _self.object.set({
- borderColor: 'red',
- // left: 100,
- // top: 100,
- scaleX: _self.cardPublic.width / img.width,
- scaleY: _self.cardPublic.height / img.height,
- selectable: true
- });
- //_self.cardPublic.setWidth(_self.object.width)
- //_self.cardPublic.setHeight(_self.object.height)
- _self.object.hasRotatingPoint = true;
- // _self.object.scaleX = canvas.width / _self.object.width;
- // _self.object.scaleX = canvas.height / _self.object.height;
- _self.cardPublic.add(_self.object);
- _self.cardPublic.renderAll();
- });
- },
- //添加文字
- addText(){
- var _self = this;
- this.obj_Pub['textbox' + _self.num] = new fabric.Textbox('添加文字', {
- left: _self.textLocation_left,
- top: _self.textLocation_top,
- width: 150,
- fontSize: 20, // 字体大小
- fontWeight: 800, // 字体粗细
- fill: _self.text_color, // 字体颜色
- // fontStyle: 'italic', // 斜体
- // fontFamily: 'Delicious', // 设置字体
- // stroke: 'green', // 描边颜色
- // strokeWidth: 3, // 描边宽度
- hasControls: false,
- borderColor: 'orange',
- editingBorderColor: 'blue' // 点击文字进入编辑状态时的边框颜色
- });
- this.cardPublic.add(this.obj_Pub['textbox' + _self.num]);
- _self.num ++;//多次添加文字
- // this._self.textLocation_top += 50;//多次添加文字纵向位置
- },
- //字体颜色组件冒上来的颜色值
- colorPickerFor_textEvent(item){
- this.text_color = item.color;
- this.addText();
- },
- //图片选择冒上来的图片URL
- addPicUrlEvent(item){
- // this.picUrl = item;
- // alert(this.picUrl)
- // 方式二(通过图片路径添加)
- var _self = this;
- for (var i = 0; i < item.length; i++) {
- fabric.Image.fromURL(item[i].url, function (img) {
- img.hasControls = true,
- img.borderColor = 'orange',
- img.scaleX = (_self.cardPublic.width / img.width) / 2,
- img.scaleY = (_self.cardPublic.height / img.height) / 2
- _self.cardPublic.add(img);
- });
- }
- // fabric.Image.fromURL(item, (img) => {
- // img.set({
- // scaleX: (this.cardPublic.width / img.width) / 2,
- // scaleY: (this.cardPublic.height / img.height) / 2,
- // hasControls: true, // 是否开启图层的控件
- // borderColor: 'orange', // 图层控件边框的颜色
- // });
- // // 添加对象后, 如下图
- // this.cardPublic.add(img);
- // });
- },
- //旋转
- flip(){
- // 顺时针90°旋转
- const currAngle = this.cardPublic.getActiveObject().angle; // 当前图层的角度
- const angle = currAngle === 360 ? 90 :currAngle + 90;
- this.cardPublic.getActiveObject().angle = angle;
- // 如果是通过滑块的方式控制旋转
- // this.selectedObj.rotate(slideValue);
- // 所有图层的操作之后,都需要调用这个方法
- this.cardPublic.renderAll()
- // const currAngle = this.cardPublic.getActiveObject();
- // const angle = currAngle === 360 ? 90 :currAngle - 90;
- // currAngle.rotate(angle);
- // const currAngle = this.cardPublic.backgroundImage.angle; // 当前图层的角度
- // this.cardPublic.backgroundImage.rotate(angle);
- // this.cardPublic.requestRenderAll();
- },
- //剪裁图层 =====>剪裁方法
- cropImage(png, left, top, height, width) {
- var _self = this;
- //将图片放进一个新的canvas中,经裁剪后导出一个新的图片。
- //如果用户选框大于原图片,则将选框缩至原图片大小
- if (top < png.top) {
- height = height - (png.top - top);
- top = png.top;
- }
- if (left < png.left) {
- width = width - (png.left - left);
- left = png.left;
- }
- if (top + height > png.top + png.height * png.scaleY)
- height = png.top + png.height * png.scaleY - top;
- if (left + width > png.left + png.width * png.scaleX)
- width = png.left + png.width * png.scaleX - left;
- var canvas_crop = new fabric.Canvas("canvas_crop");
- fabric.Image.fromURL(_self.cardPublic.toDataURL('png'), function(img) {
- img.set('left', -left);
- img.set('top', -top);
- canvas_crop.add(img)
- canvas_crop.setHeight(height);
- canvas_crop.setWidth(width);
- canvas_crop.renderAll();
- fabric.Image.fromURL(canvas_crop.toDataURL('png'), function(croppedImg) {
- croppedImg.set('left', left);
- croppedImg.set('top', top);
- //下一步是底图的特殊处理,判断是否是底图,然后在新的图层上添加红色边框,禁止剪裁动作
- if(_self.objectCut.hasOwnProperty("borderColor")&&_self.objectCut.borderColor == "red"){
- croppedImg.set('borderColor', 'red');
- }
- _self.cardPublic.add(croppedImg).renderAll();
- });
- });
- },
- //剪裁图层 =====>确定剪裁动作
- clipImage(){
- var _self = this;
- if (!_self.isCropping) {
- alert("请先框选裁剪区域。");
- return;
- }
- var left = _self.el.left - _self.objectCut.left;
- var top = _self.el.top - _self.objectCut.top;
- left *= 1;
- top *= 1;
- var width = _self.el.width * 1;
- var height = _self.el.height * 1;
- //将当前帧导出到一个新的canvas中并执行裁剪,在此期间暂停记录历史记录。
- this.cropImage(_self.objectCut, _self.el.left, _self.el.top, parseInt(_self.el.scaleY * height), parseInt(width * _self.el.scaleX));
- // for (var i = 0; i < $("#layers li").length; i++) {
- // canvas.item(i).selectable = true;
- // }
- // disabled = true;
- _self.cardPublic.remove(_self.objectCut);
- _self.cardPublic.remove(_self.cardPublic.getActiveObject());
- _self.lastActive = _self.objectCut;
- _self.cardPublic.renderAll();
- _self.isCropping = false;
- _self.showCutButton = true;
- },
- //剪裁图层 =====>选择要剪裁的图层
- chooseCutArea(){
- var _self = this;
- _self.cardPublic.remove(_self.el);
- if (_self.cardPublic.getActiveObject()) {
- if (_self.cardPublic.getActiveObject().type == 'sprite') {
- alert("所选对象不可裁剪。");
- return;
- }
- _self.objectCut = _self.cardPublic.getActiveObject();
- if (_self.lastActive !== _self.objectCut) {
- console.log('different object');
- } else {
- console.log('same object');
- }
- if (_self.lastActive && _self.lastActive !== _self.objectCut) {
- _self.lastActive.clipTo = null;
- }
- //生成一个和待裁剪元素相同大小的矩形用于框选裁剪区域
- _self.el = new fabric.Rect({
- fill: 'rgba(0,0,0,0)',
- originX: 'left',
- originY: 'top',
- stroke: '#ccc',
- //strokeDashArray: [2, 2],
- strokWidth: 5,
- //opacity: 1,
- width: 1,
- height: 1,
- borderColor: '#36fd00',
- cornerColor: 'green',
- hasRotatingPoint: false,
- selectable: true
- });
- _self.el.left = _self.cardPublic.getActiveObject().left;
- _self.selection_object_left = _self.cardPublic.getActiveObject().left;
- _self.selection_object_top = _self.cardPublic.getActiveObject().top;
- _self.el.top = _self.cardPublic.getActiveObject().top;
- _self.el.width = _self.cardPublic.getActiveObject().width * _self.cardPublic.getActiveObject().scaleX;
- _self.el.height = _self.cardPublic.getActiveObject().height * _self.cardPublic.getActiveObject().scaleY;
- _self.cardPublic.add(_self.el);
- _self.cardPublic.setActiveObject(_self.el);
- // for (var i = 0; i < $("#layers li").length; i++) {
- // _self.cardPublic.item(i).selectable = false;
- // }
- _self.showCutButton = false;
- } else {
- alert("请选中一个元素。");
- }
- _self.isCropping = true;
- },
- //删除所选元素
- deleteSelect(){
- let selectObj = this.cardPublic.getActiveObject(); // 返回当前画布中被选中的图层
- if(!selectObj){
- alert('请先点击选择元素');
- return;
- }else{
- if(selectObj.hasOwnProperty("borderColor")&&selectObj.borderColor == "red"){
- this.$message({
- type: 'warning',
- message: '底图不可删除!'
- });
- }else{
- this.cardPublic.remove(selectObj) // 传入需要移除的object
- this.cardPublic.renderAll()
- }
- }
- },
- //初始化记录画图状态为撤销操作准备
- canvasDataChange(){
- let _self = this;
- this.cardPublic.on('object:modified', function(){
- _self.updateCanvasState();
- });
- this.cardPublic.on('object:added', function(){
- _self.updateCanvasState()
- });
- this.cardPublic.on('object:removed', function(){
- _self.updateCanvasState()
- });
- this.cardPublic.on('object:rotating', function(){
- _self.updateCanvasState()
- });
- },
- //更新画布状态
- updateCanvasState() {
- var _self = this;
- if(this.config.undoStatus == false && this.config.redoStatus == false){
- var jsonData = _self.cardPublic.toJSON();
- var canvasAsJson = JSON.stringify(jsonData);
- if(_self.config.currentStateIndex < _self.config.canvasState.length-1){
- var indexToBeInserted = _self.config.currentStateIndex+1;
- _self.config.canvasState[indexToBeInserted] = canvasAsJson;
- var numberOfElementsToRetain = indexToBeInserted+1;
- _self.config.canvasState = _self.config.canvasState.splice(0,numberOfElementsToRetain);
- }else{
- _self.config.canvasState.push(canvasAsJson);
- }
- _self.config.currentStateIndex = _self.config.canvasState.length-1;
- if((_self.config.currentStateIndex == _self.config.canvasState.length-1) && _self.config.currentStateIndex != -1){
- // _self.config.redoButton.disabled= true
- }
- }
- },
- //撤销操作事件
- unDoEvent(){
- let _self =this;
- if(this.config.undoFinishedStatus){
- if(this.config.currentStateIndex == -1){
- this.config.undoStatus = false;
- }else{
- if (this.config.canvasState.length >= 1) {
- this.config.undoFinishedStatus = 0;
- if(this.config.currentStateIndex != 0){
- this.config.undoStatus = true;
- this.cardPublic.loadFromJSON(this.config.canvasState[this.config.currentStateIndex-1],function(){
- var jsonData = JSON.parse(_self.config.canvasState[_self.config.currentStateIndex-1]);
- _self.cardPublic.renderAll();
- _self.config.undoStatus = false;
- _self.config.currentStateIndex -= 1;
- if(_self.config.currentStateIndex !== _self.config.canvasState.length-1){
- }
- _self.config.undoFinishedStatus = 1;
- });
- }
- else if(_self.config.currentStateIndex == 0){
- if(_self.cardPublic._objects.length == 1){
- _self.$message({
- type: 'warning',
- message: '无可撤销动作!'
- });
- }else{
- _self.cardPublic.clear();
- _self.config.undoFinishedStatus = 1;
- _self.config.currentStateIndex -= 1;
- }
- }
- }
- }
- }
- },
- unloadEvent(event){
- this.cardPublic.backgroundColor = "transparent";
- // 图片导出为 png 格式
- var type = 'png';
- // 返回一个包含JPG图片的<img>元素
- var img_png_src = this.cardPublic.toDataURL("image/png"); //将画板保存为图片格式的函数
- // 加工image data,替换mime type
- var imgData = img_png_src.replace(this._fixType(type),'image/octet-stream');
- // 下载后的问题名
- var filename = '个人画板_' + (new Date()).getTime() + '.' + type;
- // download
- this.saveFile(imgData,filename);
- },
- /**
- * 在本地进行文件保存
- * @param {String} data 要保存到本地的图片数据
- * @param {String} filename 文件名
- */
- saveFile(data, filename){
- var save_link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
- save_link.href = data;
- save_link.download = filename;
- var event = document.createEvent('MouseEvents');
- event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
- save_link.dispatchEvent(event);
- },
- /**
- * 获取mimeType
- * @param {String} type the old mime-type
- * @return the new mime-type
- */
- _fixType(type) {
- type = type.toLowerCase().replace(/jpg/i, 'jpeg');
- var r = type.match(/png|jpeg|bmp|gif/)[0];
- return 'image/' + r;
- },
- //清除所有添加的对象
- redoEvent(){
- // this.cardPublic._objects.length = 0 ;
- // for(let i = 0; i < this.cardPublic._objects.length;){
- // this.cardPublic.remove(this.obj_Pub['textbox' + (this.cardPublic._objects.length)]);
- // }
- this.cardPublic._objects.splice(1,this.cardPublic._objects.length - 1);//保留this.cardPublic._objects中第一个元素,此元素为要修改的图片底层画布。
- this.obj_Pub={}//将添加的对象置空
- this.num = 1;//对象名称编号回归1
- this._self.textLocation_top = 50;//文字对象位置还原
- this.cardPublic.renderAll();
- },
- closeWindow() {
- this.$emit("cancelHandler");
- },
- },
- beforeCreate() {}, //生命周期 - 组件实例化之前执行的函数
- created() {
- }, //生命周期 - 组件实例化完毕,但页面还未显示(可以访问当前this实例)
- beforeMount() {}, //生命周期 - 组件挂载前,页面仍未显示,但虚拟DOM已经OK
- mounted() {
- this.elMain = true;
- this.$nextTick(() => {
- this.dialogMouted();
- });
- }, //生命周期 - 挂载完成,此方法执行后页面内容显示(可以访问DOM元素)
- beforeUpdate() {}, //生命周期 - 组件更新之前,页面仍未更新
- updated() {}, //生命周期 - 组件更新之后,此方法执行后页面更新
- beforeDestroy() {}, //生命周期 - 销毁之前
- destroyed() {}, //生命周期 - 销毁完成
- activated() {} //如果页面有keep-alive缓存功能,这个函数会触发
- };
- </script>
- <style lang='scss'>
- //@import url(); 引入公共css类
- .myCard .el-card__body{
- padding: 0;
- }
- .outSide .el-popover{
- min-width: 95px;
- z-index: 20000;
- }
- @mixin buttonBase{
- float: left;
- margin-left:10px;
- }
- .outSide{
- }
- .refresh{
- @include buttonBase;
- background: url("../../assets/img/refresh.png");
- cursor: pointer;
- }
- .deleteSelect{
- @include buttonBase;
- background: url("../../assets/img/deletePicEdit.png");
- cursor: pointer;
- }
- .add_text_button{
- @include buttonBase;
- background: url("../../assets/img/textIcon.png");
- cursor: pointer;
- }
- .add_pic_button{
- @include buttonBase;
- background: url("../../assets/img/addPic.png");
- cursor: pointer;
- }
- .cut_pic{
- @include buttonBase;
- background: url("../../assets/img/cut.png");
- cursor: pointer;
- }
- .turn_left{
- @include buttonBase;
- background: url("../../assets/img/turnleft.png");
- cursor: pointer;
- }
- .undo{
- @include buttonBase;
- background: url("../../assets/img/undo.png");
- cursor: pointer;
- }
- .unload{
- @include buttonBase;
- background: url("../../assets/img/downLoadToLocal.png");
- cursor: pointer;
- }
- .save{
- @include buttonBase;
- background: url("../../assets/img/save.png");
- cursor: pointer;
- }
- .myDialog .el-dialog__body{
- padding: 10px 0px;
- }
- .canvas-container{
- margin:0 auto;
- }
- </style>
|