123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435 |
- <!-- 基本图片的属性框 -->
- <template>
- <div class="base-image">
- <div class="title">属性</div>
- <ul>
- <li>
- <div class="small-title">尺寸大小</div>
- <div class="property">
- <div>
- <span>W</span>
- <el-input style="width: 74px; margin-left: 6px" size="mini" type="number" v-model="width" placeholder="输入宽度"></el-input>
- </div>
- <div>
- <span>H</span>
- <el-input style="width: 74px; margin-left: 6px" size="mini" type="number" v-model="height" placeholder="输入高度"></el-input>
- </div>
- <div @click="lockItem" :title="isLock ? '锁定' : '解锁'">
- <i class="el-icon-link" :style="{ color: isLock ? '#409EFF' : '', cursor: 'pointer' }"></i>
- </div>
- <div class="rotate">
- <span>R</span>
- <el-input
- disabled
- style="width: 74px; margin-left: 6px"
- size="mini"
- type="number"
- v-model="rotate"
- placeholder="输入角度"
- >
- <template slot="suffix">°</template>
- </el-input>
- </div>
- </div>
- </li>
- <li class="m-picture">
- <p class="title">图片</p>
- <el-upload
- class="avatar-uploader"
- drag
- action="/#"
- :show-file-list="false"
- :before-upload="beforeAvatarUpload"
- accept="image/jpeg,image/jpg,image/png,"
- >
- <i class="el-icon-upload"></i>
- <div class="el-upload__text">
- 将文件拖动到这里替换
- <p><em>本地上传</em></p>
- </div>
- </el-upload>
- </li>
- <li>
- <div class="small-title">边框</div>
- <div class="property">
- <div class="color-box">
- <div class="cololorSelect">
- <el-color-picker show-alpha popper-class="imgae-color-picker" class="fix-box-1" v-model="color"></el-color-picker>
- </div>
- <span class="text">颜色</span>
- </div>
- <div class="line-width">
- <el-input style="width: 80px" v-model="lineWidth" type="number" size="mini" placeholder="输入线宽"></el-input>
- <span class="text">线宽</span>
- </div>
- <div class="line-width">
- <el-select
- v-model="lineStyle"
- popper-class="image-select"
- :default-value="borderLineOption[0].id"
- size="mini"
- style="width: 80px"
- placeholder="请选择"
- :ref="`selectLine`"
- >
- <el-option v-for="item in borderLineOption" :key="item.id" :label="item.src" :value="item.id">
- <img :src="item.src" alt width="60" />
- </el-option>
- </el-select>
- <span class="text">线型</span>
- </div>
- </div>
- </li>
- </ul>
- </div>
- </template>
- <script>
- import bus from "@/bus/bus";
- import { imgBaseUrl, imgServeUpload } from "@/api/imageservice";
- import { SColor } from "@persagy-web/draw";
- import { rgbaNum } from "@persagy-web/big-edit/lib/until";
- import { findIndex } from "lodash";
- import { dataURLtoBlob } from "@/utils/utils";
- export default {
- props: ["ImageItem"],
- data() {
- return {
- borderLineOption: [
- {
- id: "Solid",
- src: require("@/assets/images/solidLine.png"),
- },
- {
- id: "Dashed",
- src: require("@/assets/images/dashedLine.png"),
- },
- {
- id: "Dotted",
- src: require("@/assets/images/dotLine.png"),
- },
- ],
- isLock: true, //锁定图片宽高比
- aspectRatio: 1, // 图片宽高比
- };
- },
- computed: {
- /**
- * 图片宽度
- */
- width: {
- get: function () {
- return this.ImageItem.width;
- },
- set: function (newV) {
- if (!newV) newV = 0;
- newV = Number(newV);
- const oldV = this.ImageItem.width;
- if (this.isLock) {
- this.ImageItem.height = newV * this.aspectRatio;
- }
- this.ImageItem.width = newV;
- bus.$emit("undoAttr", this.ImageItem, "width", oldV, newV);
- },
- },
- /**
- * 图片高度
- */
- height: {
- get: function () {
- return this.ImageItem.height;
- },
- set: function (newV) {
- if (!newV) newV = 0;
- newV = Number(newV);
- const oldV = this.ImageItem.height;
- if (this.isLock) {
- this.ImageItem.width = newV / this.aspectRatio;
- }
- this.ImageItem.height = newV;
- bus.$emit("undoAttr", this.ImageItem, "height", oldV, newV);
- },
- },
- /**
- * 图片角度
- */
- rotate: {
- get() {
- return this.ImageItem.rotate
- },
- set(newV) {
- const oldV = this.ImageItem.rotate
- // 宽度改变,修改对象的宽度
- if (newV !== oldV) {
- this.ImageItem.rotate = newV;
- bus.$emit("undoAttr", this.ImageItem, "rotate", oldV, newV);
- }
- }
- },
- /**
- * 边框线宽
- */
- lineWidth: {
- get: function () {
- return this.ImageItem.lineWidth;
- },
- set: function (newV) {
- if (!newV) newV = 0;
- newV = Number(newV);
- const oldV = this.ImageItem.lineWidth;
- // 宽度最大20
- if (newV > 20) {
- newV = 20
- } else if (newV < 0) { //宽度最小0
- newV = 0
- }
- // 宽度改变,修改对象的宽度
- if (newV !== oldV) {
- this.ImageItem.lineWidth = newV;
- bus.$emit("undoAttr", this.ImageItem, "lineWidth", oldV, newV);
- }
- },
- },
- /**
- * 边框颜色
- */
- color: {
- get: function () {
- return this.ImageItem.strokeColor.toRgba();
- },
- set: function (val) {
- const colorList = rgbaNum(val);
- const oldVal = this.ImageItem.strokeColor;
- const newVal = new SColor(Number(colorList[0]), Number(colorList[1]), Number(colorList[2]), colorList[3] * 255);
- this.ImageItem.strokeColor = newVal;
- bus.$emit("undoAttr", this.ImageItem, "strokeColor", oldVal, newVal);
- },
- },
- /**
- * 边框线型
- */
- lineStyle: {
- get: function () {
- const id = this.borderLineOption[this.ImageItem.lineStyle].id;
- // 修改线型下啦菜单样式
- this.$nextTick(() => {
- this.setLineStyle(id);
- });
- return id;
- },
- set: function (newV) {
- newV = findIndex(this.borderLineOption, ["id", newV]);
- const oldV = this.ImageItem.lineStyle;
- this.ImageItem.lineStyle = newV;
- bus.$emit("undoAttr", this.ImageItem, "lineStyle", oldV, newV);
- },
- },
- },
- mounted() {
- console.log(this.ImageItem)
- },
- methods: {
- /**
- * 切换锁状态
- */
- lockItem() {
- this.isLock = !this.isLock;
- if (this.isLock) {
- this.aspectRatio = this.width / this.height;
- }
- },
- /**
- * 修改线型下啦菜单样式
- * @param {String} id 选中的线型id
- */
- setLineStyle(id) {
- const img = this.borderLineOption.filter((v) => v.id === id)[0]?.src;
- if (img) {
- this.$refs.selectLine?.$el?.children[0].children[0].setAttribute(
- "style",
- `
- background: url(${img}) no-repeat;
- color: rgba(0,0,0,0);
- text-indent: -9999px;
- background-position: 15px center;
- background-size: 40px 1px;
- `
- );
- } else {
- this.$refs.selectLine?.$el?.children[0].children[0].setAttribute(
- "style",
- `
- background: inherit;
- color:inherit;
- text-indent: 0;
- `
- );
- }
- },
- /**
- * 图片上传
- */
- beforeAvatarUpload(file) {
- const fileReader = new FileReader();
- fileReader.readAsDataURL(file); //读取图片
- const ftype = file.type;
- const fname = file.name;
- const uploadKey = file.uid;
- fileReader.addEventListener("load", () => {
- // 读取完成
- const res = fileReader.result;
- //将canvas的base64位图片转换成图片png的file
- const blob = dataURLtoBlob(res, ftype);
- //将其转换成file对象
- const file = new File([blob], fname, {
- type: ftype,
- lastModified: Date.now(),
- }); //blob转file
- // try sending
- const reader = new FileReader();
- const fileType = file.name.split(".");
- const imgType = fileType[fileType.length - 1];
- reader.onloadend = () => {
- // 这个事件在读取结束后,无论成功或者失败都会触发
- if (reader.error) {
- //
- } else {
- // 构造 XMLHttpRequest 对象,发送文件 Binary 数据
- const xhr = new XMLHttpRequest();
- xhr.open("POST", `${imgServeUpload}${uploadKey}.${imgType}`);
- xhr.send(reader.result);
- xhr.onreadystatechange = () => {
- if (xhr.readyState == 4) {
- if (xhr.status == 200) {
- const olDefaultUrl = this.ImageItem.defaultUrl;
- const oldUrl = this.ImageItem.url;
- const newDefaultUrl = `${uploadKey}.${imgType}`;
- const newUrl = `${imgBaseUrl}${uploadKey}.${imgType}`;
- bus.$emit("undoAttr", this.ImageItem, "defaultUrl", olDefaultUrl, newDefaultUrl);
- bus.$emit("undoAttr", this.ImageItem, "url", oldUrl, newUrl);
- this.ImageItem.defaultUrl = newDefaultUrl;
- this.ImageItem.url = newUrl;
- }
- }
- };
- }
- };
- reader.readAsArrayBuffer(file);
- });
- },
- },
- };
- </script>
- <style lang="less">
- .image-select {
- .el-select-dropdown__item {
- text-align: center;
- }
- }
- .imgae-color-picker {
- /deep/.el-input__inner {
- padding-right: 0 !important;
- }
- }
- </style>
- <style lang="less" scoped>
- ul,
- li {
- margin: 0;
- padding: 0;
- list-style-type: none;
- }
- .base-image {
- & > .title {
- height: 40px;
- line-height: 40px;
- color: #000000;
- background: #f8f9fa;
- font-size: 14px;
- padding-left: 12px;
- box-sizing: border-box;
- font-weight: 600;
- }
- ul {
- width: 100%;
- li {
- padding: 0 12px;
- margin-bottom: 16px;
- .small-title {
- font-size: 12px;
- color: #8d9399;
- margin: 12px 0;
- font-weight: 600;
- }
- .property {
- display: flex;
- align-items: center;
- justify-content: space-around;
- flex-wrap: wrap;
- .color-box {
- display: flex;
- align-items: center;
- flex-direction: column;
- .cololorSelect {
- width: 32px;
- height: 20px;
- overflow: hidden;
- position: relative;
- margin: 4px 0;
- .fix-box-1 {
- margin-top: -8px;
- margin-left: -8px;
- /deep/ .el-color-picker__trigger {
- width: 200px;
- height: 200px;
- }
- }
- }
- }
- .line-width {
- display: flex;
- align-items: center;
- flex-direction: column;
- margin-left: 8px;
- position: relative;
- }
- .text {
- font-size: 12px;
- color: #1f2429;
- font-weight: 600;
- margin-top: 4px;
- }
- .rotate {
- flex-basis: 100%;
- margin-left: 7px;
- margin-top: 10px;
- }
- }
- }
- li.m-picture {
- border-top: 1px solid #e4e5e7;
- border-bottom: 1px solid #e4e5e7;
- padding: 12px 0 18px 0;
- .title {
- padding: 0 12px;
- margin-bottom: 12px;
- color: #8d9399;
- font-size: 14px;
- line-height: 16px;
- font-weight: 600;
- }
- .avatar-uploader {
- width: 100%;
- text-align: center;
- /deep/ .el-upload-dragger {
- width: 200px !important;
- }
- }
- }
- }
- /deep/ .el-input-number .el-input__inner {
- padding-right: 40px !important;
- }
- }
- </style>
|