From f9e5e407331b38f5b9c2566d8ec4b3f852df823c Mon Sep 17 00:00:00 2001 From: JackPu Date: Mon, 8 May 2017 16:06:28 +0800 Subject: [PATCH 01/47] add new component --- package.json | 2 +- .../components/doc/cn/CustomComponent.vue | 67 +++++++++++++++++++ site/client/components/doc/en/CropImage.vue | 3 +- .../components/doc/en/CustomComponent.vue | 65 ++++++++++++++++++ site/client/lib/constants.js | 4 ++ site/client/router/index.js | 5 ++ site/package.json | 2 +- 7 files changed, 144 insertions(+), 4 deletions(-) create mode 100644 site/client/components/doc/cn/CustomComponent.vue create mode 100644 site/client/components/doc/en/CustomComponent.vue diff --git a/package.json b/package.json index 425ae7b..7d2b8a4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vue-core-image-upload", - "version": "2.1.6", + "version": "2.1.7", "description": "a vue plgin for image upload and crop", "main": "src/index.js", "dependencies": { diff --git a/site/client/components/doc/cn/CustomComponent.vue b/site/client/components/doc/cn/CustomComponent.vue new file mode 100644 index 0000000..930a8d6 --- /dev/null +++ b/site/client/components/doc/cn/CustomComponent.vue @@ -0,0 +1,67 @@ + + + + + diff --git a/site/client/components/doc/en/CropImage.vue b/site/client/components/doc/en/CropImage.vue index 3849d90..2c320ae 100644 --- a/site/client/components/doc/en/CropImage.vue +++ b/site/client/components/doc/en/CropImage.vue @@ -77,14 +77,13 @@ text="Crop Image" @imageuploaded="crpoServerImageUploaded"> </vue-core-image-upload> - View Code Source diff --git a/site/client/lib/constants.js b/site/client/lib/constants.js index 8c48408..b9e00ae 100644 --- a/site/client/lib/constants.js +++ b/site/client/lib/constants.js @@ -16,6 +16,10 @@ let routers = [ name: 'Events', cn_name: '响应事件' }, + { + name: 'Custom Component', + cn_name: '自定义组件' + }, { name: 'Crop Image', cn_name: '裁剪图片' diff --git a/site/client/router/index.js b/site/client/router/index.js index 774dbaa..2bc66be 100644 --- a/site/client/router/index.js +++ b/site/client/router/index.js @@ -8,6 +8,7 @@ import CnProps from '../components/doc/cn/Props.vue'; import EnProps from '../components/doc/en/Props.vue'; import CnEvents from '../components/doc/cn/Events.vue'; import EnEvents from '../components/doc/en/Events.vue'; +import EnCustomComponent from '../components/doc/en/CustomComponent.vue'; import CnCropImage from '../components/doc/cn/CropImage.vue'; import EnCropImage from '../components/doc/en/CropImage.vue'; import CnResizeImage from '../components/doc/cn/ResizeImage.vue'; @@ -63,6 +64,10 @@ export default new Router({ path: '/en/events', component: EnEvents, }, + { + path: '/en/custom-component', + component: EnCustomComponent, + }, { path: '/cn/crop-image', component: CnCropImage diff --git a/site/package.json b/site/package.json index 3d9a6c8..1a8474c 100644 --- a/site/package.json +++ b/site/package.json @@ -23,7 +23,7 @@ "j-i-c": "^2.0.2", "promise-polyfill": "^6.0.2", "vue": "^2.2.2", - "vue-core-image-upload": "^2.1.2", + "vue-core-image-upload": "^2.1.7", "vue-highlight": "0.0.0", "vue-highlightjs": "^1.2.2", "vue-progressbar": "^0.7.1", From 2a23386ec2129e456dad06bd61bf0e8472611eeb Mon Sep 17 00:00:00 2001 From: JackPu Date: Mon, 8 May 2017 16:08:13 +0800 Subject: [PATCH 02/47] add new component --- site/client/components/doc/en/CropImage.vue | 2 +- site/client/router/index.js | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/site/client/components/doc/en/CropImage.vue b/site/client/components/doc/en/CropImage.vue index 2c320ae..024e228 100644 --- a/site/client/components/doc/en/CropImage.vue +++ b/site/client/components/doc/en/CropImage.vue @@ -83,7 +83,7 @@ diff --git a/site/package.json b/site/package.json index 1a8474c..9c641a8 100644 --- a/site/package.json +++ b/site/package.json @@ -20,16 +20,17 @@ }, "dependencies": { "babel-runtime": "^6.18.0", + "canvas-png-compression": "0.0.3", "j-i-c": "^2.0.2", "promise-polyfill": "^6.0.2", - "vue": "^2.2.2", - "vue-core-image-upload": "^2.1.7", + "vue": "^2.3.2", + "vue-core-image-upload": "^2.1.9", "vue-highlight": "0.0.0", "vue-highlightjs": "^1.2.2", "vue-progressbar": "^0.7.1", "vue-router": "^2.0.0", "vue-select": "^2.2.0", - "vue-template-compiler": "^2.2.2", + "vue-template-compiler": "^2.3.2", "vuex": "^2.0.0", "vuex-router-sync": "^4.0.0" }, @@ -37,6 +38,7 @@ "autoprefixer": "^6.4.0", "babel-core": "^6.16.0", "babel-loader": "^6.2.4", + "babel-plugin-transform-runtime": "^6.23.0", "babel-preset-es2015": "^6.24.1", "babel-preset-stage-2": "^6.24.1", "babel-preset-vue-app": "^1.1.1", @@ -47,7 +49,7 @@ "eslint-config-vue": "latest", "eslint-plugin-vue": "latest", "express": "^4.14.0", - "extract-text-webpack-plugin": "^2.0.0-rc.3", + "extract-text-webpack-plugin": "^2.1.0", "file-loader": "^0.9.0", "friendly-errors-webpack-plugin": "^1.1.2", "html-webpack-plugin": "^2.22.0", diff --git a/src/demo/index.js b/src/demo/index.js deleted file mode 100644 index 70a850d..0000000 --- a/src/demo/index.js +++ /dev/null @@ -1,45 +0,0 @@ -import Vue from 'vue/dist/vue'; - -const VueCoreImageUpload = require('../index'); - -Vue.config.silent = false; - -Vue.config.devtools = false; - -new Vue({ - el: '#app', - components: { - 'vue-core-image-upload': VueCoreImageUpload - }, - data: { - name: 'Jiraiya', - src: 'http://img1.vued.vanthink.cn/vued0a233185b6027244f9d43e653227439a.png', - cropSrc: 'http://img1.vued.vanthink.cn/vued7553a09a5d5209ebd00a48264394b7f3.png', - cropArgs: {}, - data: {token: '123123123'} - }, - methods: { - imageuploaded(res) { - if (res.errcode === 0) { - if (res.data.src) { - this.src = res.data.src; - return; - } - this.name = res.data.name; - this.cropArgs = { - toCropImgH: parseInt(res.data.post.toCropImgH), - toCropImgW: parseInt(res.data.post.toCropImgW), - toCropImgX: parseInt(res.data.post.toCropImgX), - toCropImgY: parseInt(res.data.post.toCropImgY) - } - this.cropSrc = 'http://img1.vued.vanthink.cn/vued41b900045d6d44f3b32e06049621b415.png'; - } - }, - imagechanged(res) { - console.log(res); - }, - errorhandle: function(msg) { - console.warn(msg); - } - } -}); \ No newline at end of file diff --git a/src/lib/helper.js b/src/lib/helper.js index 27c6ed2..9ff3900 100644 --- a/src/lib/helper.js +++ b/src/lib/helper.js @@ -3,12 +3,12 @@ module.exports = { setCssText: function(obj) { var cssArr = []; - for(let key in obj) { - let val = obj[key]; + for(var key in obj) { + var val = obj[key]; if (typeof val === 'number') { val = '' + val + 'px'; } - cssArr.push(`${key}:${val};`) + cssArr.push(key + ': ' + val + ';'); } return cssArr.join(''); } diff --git a/src/props.js b/src/props.js index 1c6ab76..ebfd035 100644 --- a/src/props.js +++ b/src/props.js @@ -6,12 +6,6 @@ export default { type:String, default: 'Upload Image' }, - class: { - type: Array, - default:function() { - return []; - } - }, extensions: { type: String, default:'png.jpg,jpeg,gif,svg,webp' diff --git a/src/resize-bar.vue b/src/resize-bar.vue index 99bea5b..5400341 100644 --- a/src/resize-bar.vue +++ b/src/resize-bar.vue @@ -92,7 +92,6 @@ export default { const move = function (ev) { const newCoor = drag(ev, self.el, coor); if (newCoor) { - console.log(self.minProgress); if((newCoor.left / width) < self.minProgress) { return; } diff --git a/webpack.config.js b/webpack.config.js index 29cc2ea..1eef187 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,14 +1,24 @@ const webpack = require( 'webpack' ); const path = require('path'); +const fse = require('fs-extra'); + +fse.copySync('./src', './dist'); module.exports = { context: path.resolve(__dirname, './src'), entry: { - 'index': './vue-core-image-upload.vue' + 'index': './vue-core-image-upload.vue', + 'dist/lib/canvas-helper': './lib/canvas-helper.js', + 'dist/lib/helper': './lib/helper.js', + 'dist/lib/drag': './lib/drag.js', + 'dist/lib/resize': './lib/resize.js', + 'dist/lib/xhr': './lib/xhr.js', + 'dist/lib/loading-gif': './lib/loading-gif.js', + }, output: { path: path.resolve(__dirname), - filename: 'index.js', + filename: '[name].js', library: 'VueCoreImageUpload', libraryTarget: 'umd', }, From 3a10380ad427b7f7517398c219807afd74084f8f Mon Sep 17 00:00:00 2001 From: JackPu Date: Fri, 12 May 2017 09:42:40 +0800 Subject: [PATCH 05/47] update new package.json --- package.json | 4 ++-- site/client/components/doc/en/CompressImage.vue | 2 +- site/client/components/doc/en/CropImage.vue | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index d44670e..8421648 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "vue-core-image-upload", - "version": "2.1.10", + "version": "2.1.11", "description": "a vue plgin for image upload and crop", - "main": "dist/index.js", + "main": "dist/vue-core-image-upload.vue", "dependencies": { "vue": "^2.0.5" }, diff --git a/site/client/components/doc/en/CompressImage.vue b/site/client/components/doc/en/CompressImage.vue index 20f15a0..6d92b6e 100644 --- a/site/client/components/doc/en/CompressImage.vue +++ b/site/client/components/doc/en/CompressImage.vue @@ -26,7 +26,7 @@ diff --git a/site/src/demo/index.js b/site/src/demo/index.js new file mode 100644 index 0000000..70a850d --- /dev/null +++ b/site/src/demo/index.js @@ -0,0 +1,45 @@ +import Vue from 'vue/dist/vue'; + +const VueCoreImageUpload = require('../index'); + +Vue.config.silent = false; + +Vue.config.devtools = false; + +new Vue({ + el: '#app', + components: { + 'vue-core-image-upload': VueCoreImageUpload + }, + data: { + name: 'Jiraiya', + src: 'http://img1.vued.vanthink.cn/vued0a233185b6027244f9d43e653227439a.png', + cropSrc: 'http://img1.vued.vanthink.cn/vued7553a09a5d5209ebd00a48264394b7f3.png', + cropArgs: {}, + data: {token: '123123123'} + }, + methods: { + imageuploaded(res) { + if (res.errcode === 0) { + if (res.data.src) { + this.src = res.data.src; + return; + } + this.name = res.data.name; + this.cropArgs = { + toCropImgH: parseInt(res.data.post.toCropImgH), + toCropImgW: parseInt(res.data.post.toCropImgW), + toCropImgX: parseInt(res.data.post.toCropImgX), + toCropImgY: parseInt(res.data.post.toCropImgY) + } + this.cropSrc = 'http://img1.vued.vanthink.cn/vued41b900045d6d44f3b32e06049621b415.png'; + } + }, + imagechanged(res) { + console.log(res); + }, + errorhandle: function(msg) { + console.warn(msg); + } + } +}); \ No newline at end of file diff --git a/site/src/index.js b/site/src/index.js new file mode 100644 index 0000000..a8c0731 --- /dev/null +++ b/site/src/index.js @@ -0,0 +1,2 @@ +import VueCoreImageUpload from './vue-core-image-upload.vue'; +export default VueCoreImageUpload; diff --git a/site/src/lib/canvas-helper.js b/site/src/lib/canvas-helper.js new file mode 100644 index 0000000..55c7882 --- /dev/null +++ b/site/src/lib/canvas-helper.js @@ -0,0 +1,91 @@ +/** +* compress image +* reference https://github.com/brunobar79/J-I-C +**/ + +export default { + _getImageType(str) { + let mimeType = 'image/jpeg'; + const outputType = str.match(/(image\/[\w]+)\.*/)[0]; + if (typeof outputType !== 'undefined'){ + mimeType = outputType; + } + return mimeType; + }, + + compress (src, quality, callback) { + const reader = new FileReader(); + const self = this; + reader.onload = function(event) { + let image = new Image(); + image.src = event.target.result; + image.onload = function() { + const mimeType = self._getImageType(src.type); + const cvs = self._getCanvas(image.naturalWidth, image.naturalHeight); + const ctx = cvs.getContext("2d").drawImage(image, 0, 0); + const newImageData = cvs.toDataURL(mimeType, quality/100); + callback(newImageData); + } + }; + reader.readAsDataURL(src); + }, + /** + * crop image via canvas and generate data + **/ + crop(image, options, callback) { + const checkNumber = function(num) { + return (typeof num === 'number'); + }; + // check crop options + if(checkNumber(options.toCropImgX) && checkNumber(options.toCropImgY) && options.toCropImgW > 0 && options.toCropImgH > 0) { + let w = options.toCropImgW; + let h = options.toCropImgH; + if(options.maxWidth && options.maxWidth < w) { + w = options.maxWidth; + h = options.toCropImgH * w / options.toCropImgW; + } + if (options.maxHeight && options.maxHeight < h) { + h = options.maxHeight + } + const cvs = this._getCanvas(w, h); + const ctx = cvs.getContext('2d').drawImage(image, options.toCropImgX, options.toCropImgY, options.toCropImgW, options.toCropImgH, 0 , 0, w, h); + const mimeType = this._getImageType(image.src); + const data = cvs.toDataURL(mimeType, options.compress/100); + callback(data); + } + }, + + resize(image, options, callback) { + const checkNumber = function(num) { + return (typeof num === 'number'); + }; + if(checkNumber(options.toCropImgX) && checkNumber(options.toCropImgY) && options.toCropImgW > 0 && options.toCropImgH > 0) { + let w = options.toCropImgW * options.imgChangeRatio; + let h = options.toCropImgH * options.imgChangeRatio; + const cvs = this._getCanvas(w, h); + const ctx = cvs.getContext('2d').drawImage(image, 0, 0, options.toCropImgW, options.toCropImgH, 0 , 0, w , h); + const mimeType = this._getImageType(image.src); + const data = cvs.toDataURL(mimeType, options.compress/100); + callback(data); + } + }, + + _loadImage(data, callback) { + const image = new Image(); + image.src = data; + image.onload = function () { + callback(image); + } + image.onerror = function() { + console.log('Error: image error!'); + } + }, + + _getCanvas(width, height) { + const canvas = document.createElement('canvas'); + canvas.width = width; + canvas.height = height; + return canvas; + }, + +}; diff --git a/site/src/lib/drag.js b/site/src/lib/drag.js new file mode 100644 index 0000000..0e5e3c6 --- /dev/null +++ b/site/src/lib/drag.js @@ -0,0 +1,29 @@ +import helper from './helper'; + +const isMobile = helper.isMobile; +export default function drag(e, el, coor) { + if (!el) { + return; + } + const currentX = isMobile ? e.changedTouches[0]['clientX'] : e.clientX; + const currentY = isMobile ? e.changedTouches[0]['clientY'] : e.clientY; + + let left = currentX - coor.x; + let top = currentY - coor.y; + if (left <= coor.minLeft) { + left = coor.minLeft; + } + if (left >= coor.maxLeft) { + left = coor.maxLeft; + } + if (top <= coor.minTop) { + top = coor.minTop; + } + if (top >= coor.maxTop) { + top = coor.maxTop; + } + return { + left, + top + }; +}; diff --git a/site/src/lib/helper.js b/site/src/lib/helper.js new file mode 100644 index 0000000..9ff3900 --- /dev/null +++ b/site/src/lib/helper.js @@ -0,0 +1,15 @@ +module.exports = { + isMobile: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent), + + setCssText: function(obj) { + var cssArr = []; + for(var key in obj) { + var val = obj[key]; + if (typeof val === 'number') { + val = '' + val + 'px'; + } + cssArr.push(key + ': ' + val + ';'); + } + return cssArr.join(''); + } +}; diff --git a/site/src/lib/loading-gif.js b/site/src/lib/loading-gif.js new file mode 100644 index 0000000..e9c6f19 --- /dev/null +++ b/site/src/lib/loading-gif.js @@ -0,0 +1,3 @@ +const GIF_LOADING_SRC = 'data:image/gif;base64,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'; + +export default GIF_LOADING_SRC; diff --git a/site/src/lib/resize.js b/site/src/lib/resize.js new file mode 100644 index 0000000..446d328 --- /dev/null +++ b/site/src/lib/resize.js @@ -0,0 +1,88 @@ +/** Reszie + * @el dom + * @container dom + * @ratio string '1:1' like this + * e events + **/ +import helper from './helper'; + +const isMobile = helper.isMobile; +const W = document.body.offsetWidth; +export default function resize(e, el, container, coor, ratio) { + if (!el) { + return ; + } + const H = document.body.offsetHeight; + const ratioRemainder = 1 / ratio; + const dotBoxW = parseInt(window.getComputedStyle(container).width); + const dotBoxH = parseInt(window.getComputedStyle(container).height); + const $topH = document.querySelector('.info-aside'); + const halfX = (W - dotBoxW) / 2; + const topH = parseInt(window.getComputedStyle($topH).height); + const halfY = (H - dotBoxH - topH)/2; + const resetX = isMobile ? e.changedTouches[0]['clientX'] : e.clientX; + const resetY = isMobile ? e.changedTouches[0]['clientY'] : e.clientY; + const elOffsetWidth = parseInt(el.offsetWidth); + const elOffsetHeight = parseInt(el.offsetHeight); + const CSSObj = {}; + if (ratio >= 1 && resetX <= halfX + dotBoxW) { + if (elOffsetWidth >= dotBoxW) { + CSSObj.width = dotBoxW; + } + CSSObj.width = (coor.w + resetX - coor.x); + CSSObj.height = elOffsetWidth * ratioRemainder; + if (dotBoxW > dotBoxH) { + if (elOffsetWidth > dotBoxH) { + CSSObj.height = dotBoxH; + CSSObj.width = dotBoxH * ratio; + } + } else if (dotBoxW < dotBoxH) { + if (elOffsetWidth > dotBoxW) { + CSSObj.width = dotBoxW; + CSSObj.height = dotBoxW * ratioRemainder; + } + } else if (elOffsetWidth >= dotBoxW) { + CSSObj.width = dotBoxW ; + CSSObj.height = dotBoxW * ratioRemainder; + } + } else if (ratio < 1 && resetY < (halfY + dotBoxH + topH)) { + CSSObj.height = (coor.h + resetY - coor.y); + CSSObj.width = parseInt(el.style.height) * ratio; + // 限制拖拉的范围在图片内 + if (dotBoxW > dotBoxH) { + if (elOffsetHeight > dotBoxH) { + CSSObj.height = dotBoxH; + CSSObj.width = dotBoxH * ratio; + } + } else if (dotBoxW < dotBoxH) { + if (elOffsetWidth > dotBoxW) { + CSSObj.width = dotBoxW; + CSSObj.height = dotBoxW * ratioRemainder; + } + } else if (elOffsetWidth > dotBoxW) { + CSSObj.width = dotBoxW; + CSSObj.height = dotBoxW * ratioRemainder; + } + } else if(ratio == 'auto' && resetY <= (halfY + dotBoxH + topH) && resetX <= halfY + dotBoxW) { + CSSObj.height = (coor.h + resetY - coor.y); + CSSObj.width = (coor.w + resetX - coor.x); + } else if (resetX <= halfX + dotBoxW) { + CSSObj.width = (coor.w + resetX - coor.x); + CSSObj.height = el.style.width; + // limit the crop box area + if (dotBoxW > dotBoxH) { + if (elOffsetHeight > dotBoxH) { + CSSObj.height = dotBoxH; + CSSObj.width = dotBoxH; + } + } else if (dotBoxW < dotBoxH) { + if (elOffsetWidth > dotBoxW) { + CSSObj.width = dotBoxW; + CSSObj.height = dotBoxW; + } + } else if (elOffsetWidth > dotBoxW) { + CSSObj.width = el.style.height = dotBoxW; + } + } + return CSSObj; +}; diff --git a/site/src/lib/xhr.js b/site/src/lib/xhr.js new file mode 100644 index 0000000..518ec4e --- /dev/null +++ b/site/src/lib/xhr.js @@ -0,0 +1,107 @@ +/** + * simple ajax handler + **/ + + //ADD sendAsBinary compatibilty to older browsers + if (XMLHttpRequest.prototype.sendAsBinary === undefined) { + XMLHttpRequest.prototype.sendAsBinary = function(string) { + var bytes = Array.prototype.map.call(string, function(c) { + return c.charCodeAt(0) & 0xff; + }); + this.send(new Uint8Array(bytes).buffer); + }; + } + +module.exports = function (method, url, headers, data, callback, err, isBinary) { + + const r = new XMLHttpRequest(); + const error = err || function () { + console.error('AJAX ERROR!'); + }; + const boundary = 'vuecodeimageupload'; + // Binary? + let binary = false; + if (method === 'blob') { + binary = method; + method = 'GET'; + } + console.log(data); + method = method.toUpperCase(); + // Xhr.responseType 'json' is not supported in any of the vendors yet. + r.onload = function () { + let json = r.response; + try { + json = JSON.parse(r.responseText); + } catch (_e) { + if (r.status === 401) { + json = error('access_denied', r.statusText); + } + } + let headers = headersToJSON(r.getAllResponseHeaders()); + headers.statusCode = r.status; + callback(json || (method === 'GET' ? error('empty_response', 'Could not get resource') : {}), headers); + }; + r.onerror = function () { + let json = r.responseText; + try { + json = JSON.parse(r.responseText); + } catch (_e) { + console.error(_e); + } + callback(json || error('access_denied', 'Could not get resource')); + }; + let x; + // Should we add the query to the URL? + if (method === 'GET' || method === 'DELETE') { + data = null; + } else if (isBinary) { + const keyData = data; + const code = data.base64Code.replace('data:' + data.type + ';base64,', ''); + data = ['--' + boundary, 'Content-Disposition: form-data; name="' + data.filed + '"; filename="' + data.filename + '"', 'Content-Type: ' + data.type, '', window.atob(code), ''].join('\r\n'); + const keyArr = Object.keys(keyData); + if (keyArr.length > 4) { + for (const k of keyArr) { + if (['filed', 'filename', 'type', 'base64Code'].indexOf(k) == -1) { + data += ['--' + boundary, 'Content-Disposition: form-data; name="' + k + '";', '', ''].join('\r\n'); + data += [typeof keyData[k] === 'object' ? JSON.stringify(keyData[k]) : keyData[k], ''].join('\r\n'); + } + } + } + data += '--' + boundary + '--'; + } + // Open the path, async + r.open(method, url, true); + if (binary) { + if ('responseType' in r) { + r.responseType = binary; + } + else { + r.overrideMimeType('text/plain; charset=x-user-defined'); + } + } + // Set any bespoke headers + if (headers) { + for (x in headers) { + r.setRequestHeader(x, headers[x]); + } + if (isBinary) { + r.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary); + } + } + if (isBinary) { + return r.sendAsBinary(data); + } + r.withCredentials = true; + r.send(data); + return r; + // Headers are returned as a string + function headersToJSON(s) { + const o = {}; + const reg = /([a-z\-]+):\s?(.*);?/gi; + let m; + while (m = reg.exec(s)) { + o[m[1]] = m[2]; + } + return o; + } +}; diff --git a/site/src/props.js b/site/src/props.js new file mode 100644 index 0000000..ebfd035 --- /dev/null +++ b/site/src/props.js @@ -0,0 +1,93 @@ +export default { + url: { + type: String, + }, + text: { + type:String, + default: 'Upload Image' + }, + extensions: { + type: String, + default:'png.jpg,jpeg,gif,svg,webp' + }, + inputOfFile: { + type: String, + default: 'files' + }, + crop: { + type: [String, Boolean], + default: '' + }, + cropBtn: { + type: Object, + default: function() { + return { + ok: 'Ok', + cancel: 'Cancel', + } + } + }, + cropRatio: { + type: String, + default: '1:1' + }, + resize: { + type: [String, Boolean], + default: false, + }, + ResizeBtn: { + type: Object, + default: function() { + return { + ok: 'Ok', + cancel: 'Cancel' + } + } + }, + maxFileSize:{ + type: Number, + default: 1024 * 1024 * 100, + }, + maxWidth:{ + type: Number, + }, + maxHeight:{ + type: Number, + }, + inputAccept:{ + type: String, + default: 'image/jpg,image/jpeg,image/png' + }, + isXhr: { + type: Boolean, + default: true + }, + headers: { + type: Object, + default: function() { + return {}; + } + }, + data: { + type: Object, + default: function() { + return {}; + } + }, + multiple: { + type: Boolean, + default: false + }, + multipleSize: { + type: Number, + default: 0 + }, + minWidth: { + type: Number, + default: 50, + }, + compress: { + type: [Number, String], + default: 0, + } +} diff --git a/site/src/resize-bar.vue b/site/src/resize-bar.vue new file mode 100644 index 0000000..ccd634d --- /dev/null +++ b/site/src/resize-bar.vue @@ -0,0 +1,119 @@ + + + + + diff --git a/site/src/style/style.css b/site/src/style/style.css new file mode 100644 index 0000000..b0a78a4 --- /dev/null +++ b/site/src/style/style.css @@ -0,0 +1,106 @@ +.g-core-image-upload-btn{ + position: relative; + overflow: hidden; +} +.g-core-image-upload-form{ + position: absolute; + left:0; + right: 0; + top:0; + bottom:0; + opacity: 0; +} +.g-core-image-upload-container{ + position: absolute; + background: #111; + z-index: 900; +} +.g-core-image-upload-modal{ + position: absolute; + left:0; + right:0; + width: 100%; + height: 100%; + border:1px solid #ccc; + z-index: 899; +} +.dropped{ + border:4px solid #ea6153; +} +.g-core-image-corp-container{ + z-index: 1900; + position:fixed; + left:0; + right:0; + top:0; + bottom: 0; + background: rgba(0,0,0,.9); + color:#f1f1f1; +} +.g-core-image-corp-container .image-aside{ + position: absolute; + right: 30px; + left:30px; + top:60px; + bottom:20px; + text-align: center; +} +.g-core-image-corp-container .image-aside img{ + max-width: 100%; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.g-core-image-corp-container .info-aside{ + position: absolute; + left:0; + right: 0; + top:0; + height: 40px; + padding-left: 10px; + padding-right: 10px; + background: #fefefe; + color:#777; +} +.g-core-image-corp-container .btn-groups{ + text-align: right; + margin: 5px 0 0; +} +.g-core-image-corp-container .btn{ + display: inline-block; + padding: 0 15px; + height: 32px; + margin-left: 15px; + background: #fff; + border:1px solid #ccc; + border-radius: 2px; + font-size: 13px; + color:#222; + line-height: 32px; + transition: all .1s ease-in; +} +.g-core-image-corp-container .btn:hover{ + border:1px solid #777; + box-shadow: 0 1px 3px rgba(0,0,0,.05); +} +.g-core-image-corp-container .btn:active{ + background: #ddd; +} +.g-core-image-corp-container .btn:disabled{ + background: #eee !important; + border-color:#ccc; + cursor: not-allowed; +} +.g-core-image-corp-container .btn-upload{ + background: #27ae60; + border-color:#27ae60; + color:#fff; +} +.g-core-image-corp-container .btn-upload:hover{ + background: #2dc26c; + border-color:#27ae60; + box-shadow: 0 1px 3px rgba(0,0,0,.05); +} diff --git a/site/src/vue-core-image-upload.vue b/site/src/vue-core-image-upload.vue new file mode 100644 index 0000000..d364632 --- /dev/null +++ b/site/src/vue-core-image-upload.vue @@ -0,0 +1,263 @@ + + + + + From c4e95050da96b7a83241a7c2128608c12880a634 Mon Sep 17 00:00:00 2001 From: JackPu Date: Fri, 12 May 2017 15:19:03 +0800 Subject: [PATCH 08/47] update new doc --- dist/crop.vue | 339 ++++++++++++++++++ dist/index.js | 2 + dist/lib/canvas-helper.js | 1 + dist/lib/drag.js | 1 + dist/lib/helper.js | 1 + dist/lib/loading-gif.js | 1 + dist/lib/resize.js | 1 + dist/lib/xhr.js | 1 + dist/props.js | 93 +++++ dist/resize-bar.vue | 127 +++++++ dist/style/style.css | 110 ++++++ dist/vue-core-image-upload.vue | 273 ++++++++++++++ site/client/components/Header.vue | 17 +- site/client/components/NavList.vue | 12 +- site/client/components/doc/en/CropImage.vue | 2 +- .../client/components/doc/en/MultipleFile.vue | 2 +- site/client/less/modules/m-layout.less | 64 +++- site/src/vue-core-image-upload.vue | 8 +- src/vue-core-image-upload.vue | 8 +- 19 files changed, 1047 insertions(+), 16 deletions(-) create mode 100644 dist/crop.vue create mode 100644 dist/index.js create mode 100644 dist/lib/canvas-helper.js create mode 100644 dist/lib/drag.js create mode 100644 dist/lib/helper.js create mode 100644 dist/lib/loading-gif.js create mode 100644 dist/lib/resize.js create mode 100644 dist/lib/xhr.js create mode 100644 dist/props.js create mode 100644 dist/resize-bar.vue create mode 100644 dist/style/style.css create mode 100644 dist/vue-core-image-upload.vue diff --git a/dist/crop.vue b/dist/crop.vue new file mode 100644 index 0000000..29a54fd --- /dev/null +++ b/dist/crop.vue @@ -0,0 +1,339 @@ + + + + + diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 0000000..a8c0731 --- /dev/null +++ b/dist/index.js @@ -0,0 +1,2 @@ +import VueCoreImageUpload from './vue-core-image-upload.vue'; +export default VueCoreImageUpload; diff --git a/dist/lib/canvas-helper.js b/dist/lib/canvas-helper.js new file mode 100644 index 0000000..cc87c9d --- /dev/null +++ b/dist/lib/canvas-helper.js @@ -0,0 +1 @@ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.VueCoreImageUpload=e():t.VueCoreImageUpload=e()}(this,function(){return function(t){function e(r){if(o[r])return o[r].exports;var n=o[r]={i:r,l:!1,exports:{}};return t[r].call(n.exports,n,n.exports,e),n.l=!0,n.exports}var o={};return e.m=t,e.c=o,e.i=function(t){return t},e.d=function(t,o,r){e.o(t,o)||Object.defineProperty(t,o,{configurable:!1,enumerable:!0,get:r})},e.n=function(t){var o=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(o,"a",o),o},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=20)}({20:function(t,e,o){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default={_getImageType:function(t){var e="image/jpeg",o=t.match(/(image\/[\w]+)\.*/)[0];return void 0!==o&&(e=o),e},compress:function(t,e,o){var r=new FileReader,n=this;r.onload=function(r){var a=new Image;a.src=r.target.result,a.onload=function(){var r=n._getImageType(t.type),i=n._getCanvas(a.naturalWidth,a.naturalHeight),g=(i.getContext("2d").drawImage(a,0,0),i.toDataURL(r,e/100));o(g)}},r.readAsDataURL(t)},crop:function(t,e,o){var r=function(t){return"number"==typeof t};if(r(e.toCropImgX)&&r(e.toCropImgY)&&e.toCropImgW>0&&e.toCropImgH>0){var n=e.toCropImgW,a=e.toCropImgH;e.maxWidth&&e.maxWidth0&&e.toCropImgH>0){var n=e.toCropImgW*e.imgChangeRatio,a=e.toCropImgH*e.imgChangeRatio,i=this._getCanvas(n,a),g=(i.getContext("2d").drawImage(t,0,0,e.toCropImgW,e.toCropImgH,0,0,n,a),this._getImageType(t.src));o(i.toDataURL(g,e.compress/100))}},_loadImage:function(t,e){var o=new Image;o.src=t,o.onload=function(){e(o)},o.onerror=function(){console.log("Error: image error!")}},_getCanvas:function(t,e){var o=document.createElement("canvas");return o.width=t,o.height=e,o}}}})}); \ No newline at end of file diff --git a/dist/lib/drag.js b/dist/lib/drag.js new file mode 100644 index 0000000..0f90314 --- /dev/null +++ b/dist/lib/drag.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.VueCoreImageUpload=t():e.VueCoreImageUpload=t()}(this,function(){return function(e){function t(o){if(n[o])return n[o].exports;var r=n[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,t),r.l=!0,r.exports}var n={};return t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=12)}({0:function(e,t,n){"use strict";e.exports={isMobile:/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),setCssText:function(e){var t=[];for(var n in e){var o=e[n];"number"==typeof o&&(o+="px"),t.push(n+": "+o+";")}return t.join("")}}},12:function(e,t,n){"use strict";function o(e,t,n){if(t){var o=u?e.changedTouches[0].clientX:e.clientX,r=u?e.changedTouches[0].clientY:e.clientY,i=o-t.parentElement.offsetLeft-n.x,f=r-t.parentElement.offsetTop-document.getElementsByClassName("image-aside")[0].offsetTop-n.y;return i<=0&&(i=0),i>=n.maxLeft&&(i=n.maxLeft),f<=0&&(f=0),f>=n.maxTop&&(f=n.maxTop),{left:i,top:f}}}Object.defineProperty(t,"__esModule",{value:!0}),t.default=o;var r=n(0),i=function(e){return e&&e.__esModule?e:{default:e}}(r),u=i.default.isMobile}})}); \ No newline at end of file diff --git a/dist/lib/helper.js b/dist/lib/helper.js new file mode 100644 index 0000000..7018694 --- /dev/null +++ b/dist/lib/helper.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.VueCoreImageUpload=t():e.VueCoreImageUpload=t()}(this,function(){return function(e){function t(o){if(r[o])return r[o].exports;var n=r[o]={i:o,l:!1,exports:{}};return e[o].call(n.exports,n,n.exports,t),n.l=!0,n.exports}var r={};return t.m=e,t.c=r,t.i=function(e){return e},t.d=function(e,r,o){t.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(r,"a",r),r},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=0)}([function(e,t,r){"use strict";e.exports={isMobile:/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),setCssText:function(e){var t=[];for(var r in e){var o=e[r];"number"==typeof o&&(o+="px"),t.push(r+": "+o+";")}return t.join("")}}}])}); \ No newline at end of file diff --git a/dist/lib/loading-gif.js b/dist/lib/loading-gif.js new file mode 100644 index 0000000..73a1290 --- /dev/null +++ b/dist/lib/loading-gif.js @@ -0,0 +1 @@ +!function(A,Q){"object"==typeof exports&&"object"==typeof module?module.exports=Q():"function"==typeof define&&define.amd?define([],Q):"object"==typeof exports?exports.VueCoreImageUpload=Q():A.VueCoreImageUpload=Q()}(this,function(){return function(A){function Q(C){if(o[C])return o[C].exports;var g=o[C]={i:C,l:!1,exports:{}};return A[C].call(g.exports,g,g.exports,Q),g.l=!0,g.exports}var o={};return Q.m=A,Q.c=o,Q.i=function(A){return A},Q.d=function(A,o,C){Q.o(A,o)||Object.defineProperty(A,o,{configurable:!1,enumerable:!0,get:C})},Q.n=function(A){var o=A&&A.__esModule?function(){return A.default}:function(){return A};return Q.d(o,"a",o),o},Q.o=function(A,Q){return Object.prototype.hasOwnProperty.call(A,Q)},Q.p="",Q(Q.s=13)}({13:function(A,Q,o){"use strict";Object.defineProperty(Q,"__esModule",{value:!0});Q.default="data:image/gif;base64,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"}})}); \ No newline at end of file diff --git a/dist/lib/resize.js b/dist/lib/resize.js new file mode 100644 index 0000000..e532e60 --- /dev/null +++ b/dist/lib/resize.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.VueCoreImageUpload=t():e.VueCoreImageUpload=t()}(this,function(){return function(e){function t(n){if(i[n])return i[n].exports;var o=i[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var i={};return t.m=e,t.c=i,t.i=function(e){return e},t.d=function(e,i,n){t.o(e,i)||Object.defineProperty(e,i,{configurable:!1,enumerable:!0,get:n})},t.n=function(e){var i=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(i,"a",i),i},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=21)}({0:function(e,t,i){"use strict";e.exports={isMobile:/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),setCssText:function(e){var t=[];for(var i in e){var n=e[i];"number"==typeof n&&(n+="px"),t.push(i+": "+n+";")}return t.join("")}}},21:function(e,t,i){"use strict";function n(e,t,i,n,o){if(t){var r=document.body.offsetHeight,d=1/o,s=parseInt(window.getComputedStyle(i).width),f=parseInt(window.getComputedStyle(i).height),c=document.querySelector(".info-aside"),a=(u-s)/2,l=parseInt(window.getComputedStyle(c).height),p=(r-f-l)/2,g=h?e.changedTouches[0].clientX:e.clientX,w=h?e.changedTouches[0].clientY:e.clientY,y=parseInt(t.offsetWidth),b=parseInt(t.offsetHeight),x={};return o>=1&&g<=a+s?(y>=s&&(x.width=s),x.width=n.w+g-n.x,x.height=y*d,s>f?y>f&&(x.height=f,x.width=f*o):ss&&(x.width=s,x.height=s*d):y>=s&&(x.width=s,x.height=s*d)):o<1&&wf?b>f&&(x.height=f,x.width=f*o):y>s&&(x.width=s,x.height=s*d)):"auto"==o&&w<=p+f+l&&g<=p+s?(x.height=n.h+w-n.y,x.width=n.w+g-n.x):g<=a+s&&(x.width=n.w+g-n.x,x.height=t.style.width,s>f?b>f&&(x.height=f,x.width=f):ss&&(x.width=s,x.height=s):y>s&&(x.width=t.style.height=s)),x}}Object.defineProperty(t,"__esModule",{value:!0}),t.default=n;var o=i(0),r=function(e){return e&&e.__esModule?e:{default:e}}(o),h=r.default.isMobile,u=document.body.offsetWidth}})}); \ No newline at end of file diff --git a/dist/lib/xhr.js b/dist/lib/xhr.js new file mode 100644 index 0000000..4abce26 --- /dev/null +++ b/dist/lib/xhr.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.VueCoreImageUpload=t():e.VueCoreImageUpload=t()}(this,function(){return function(e){function t(n){if(o[n])return o[n].exports;var r=o[n]={i:n,l:!1,exports:{}};return e[n].call(r.exports,r,r.exports,t),r.l=!0,r.exports}var o={};return t.m=e,t.c=o,t.i=function(e){return e},t.d=function(e,o,n){t.o(e,o)||Object.defineProperty(e,o,{configurable:!1,enumerable:!0,get:n})},t.n=function(e){var o=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(o,"a",o),o},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=22)}({22:function(e,t,o){"use strict";var n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};void 0===XMLHttpRequest.prototype.sendAsBinary&&(XMLHttpRequest.prototype.sendAsBinary=function(e){var t=Array.prototype.map.call(e,function(e){return 255&e.charCodeAt(0)});this.send(new Uint8Array(t).buffer)}),e.exports=function(e,t,o,r,s,a,i){function u(e){for(var t={},o=/([a-z\-]+):\s?(.*);?/gi,n=void 0;n=o.exec(e);)t[n[1]]=n[2];return t}var p=new XMLHttpRequest,f=a||function(){console.error("AJAX ERROR!")},c="vuecodeimageupload",l=!1;"blob"===e&&(l=e,e="GET"),console.log(r),e=e.toUpperCase(),p.onload=function(){var t=p.response;try{t=JSON.parse(p.responseText)}catch(e){401===p.status&&(t=f("access_denied",p.statusText))}var o=u(p.getAllResponseHeaders());o.statusCode=p.status,s(t||("GET"===e?f("empty_response","Could not get resource"):{}),o)},p.onerror=function(){var e=p.responseText;try{e=JSON.parse(p.responseText)}catch(e){console.error(e)}s(e||f("access_denied","Could not get resource"))};var d=void 0;if("GET"===e||"DELETE"===e)r=null;else if(i){var y=r,m=r.base64Code.replace("data:"+r.type+";base64,","");r=["--"+c,'Content-Disposition: form-data; name="'+r.filed+'"; filename="'+r.filename+'"',"Content-Type: "+r.type,"",window.atob(m),""].join("\r\n");var b=Object.keys(y);if(b.length>4){var v=!0,x=!1,C=void 0;try{for(var T,g=b[Symbol.iterator]();!(v=(T=g.next()).done);v=!0){var h=T.value;-1==["filed","filename","type","base64Code"].indexOf(h)&&(r+=["--"+c,'Content-Disposition: form-data; name="'+h+'";',"",""].join("\r\n"),r+=["object"===n(y[h])?JSON.stringify(y[h]):y[h],""].join("\r\n"))}}catch(a){x=!0,C=a}finally{try{!v&&g.return&&g.return()}finally{if(x)throw C}}}r+="--"+c+"--"}if(p.open(e,t,!0),l&&("responseType"in p?p.responseType=l:p.overrideMimeType("text/plain; charset=x-user-defined")),o){for(d in o)p.setRequestHeader(d,o[d]);i&&p.setRequestHeader("Content-Type","multipart/form-data; boundary="+c)}return i?p.sendAsBinary(r):(p.withCredentials=!0,p.send(r),p)}}})}); \ No newline at end of file diff --git a/dist/props.js b/dist/props.js new file mode 100644 index 0000000..ebfd035 --- /dev/null +++ b/dist/props.js @@ -0,0 +1,93 @@ +export default { + url: { + type: String, + }, + text: { + type:String, + default: 'Upload Image' + }, + extensions: { + type: String, + default:'png.jpg,jpeg,gif,svg,webp' + }, + inputOfFile: { + type: String, + default: 'files' + }, + crop: { + type: [String, Boolean], + default: '' + }, + cropBtn: { + type: Object, + default: function() { + return { + ok: 'Ok', + cancel: 'Cancel', + } + } + }, + cropRatio: { + type: String, + default: '1:1' + }, + resize: { + type: [String, Boolean], + default: false, + }, + ResizeBtn: { + type: Object, + default: function() { + return { + ok: 'Ok', + cancel: 'Cancel' + } + } + }, + maxFileSize:{ + type: Number, + default: 1024 * 1024 * 100, + }, + maxWidth:{ + type: Number, + }, + maxHeight:{ + type: Number, + }, + inputAccept:{ + type: String, + default: 'image/jpg,image/jpeg,image/png' + }, + isXhr: { + type: Boolean, + default: true + }, + headers: { + type: Object, + default: function() { + return {}; + } + }, + data: { + type: Object, + default: function() { + return {}; + } + }, + multiple: { + type: Boolean, + default: false + }, + multipleSize: { + type: Number, + default: 0 + }, + minWidth: { + type: Number, + default: 50, + }, + compress: { + type: [Number, String], + default: 0, + } +} diff --git a/dist/resize-bar.vue b/dist/resize-bar.vue new file mode 100644 index 0000000..5400341 --- /dev/null +++ b/dist/resize-bar.vue @@ -0,0 +1,127 @@ + + + + + diff --git a/dist/style/style.css b/dist/style/style.css new file mode 100644 index 0000000..f193446 --- /dev/null +++ b/dist/style/style.css @@ -0,0 +1,110 @@ +.g-core-image-upload-btn{ + position: relative; + overflow: hidden; +} +.g-core-image-upload-form{ + position: absolute; + left:0; + right: 0; + top:0; + bottom:0; + opacity: 0; +} +.g-core-image-upload-container{ + position: absolute; + background: #111; + z-index: 900; +} +.g-core-image-upload-modal{ + position: absolute; + left:0; + right:0; + width: 100%; + height: 100%; + border:1px solid #ccc; + z-index: 899; +} +.dropped{ + border:4px solid #ea6153; +} + +.g-core-image-corp-container{ + z-index: 1900; + position:fixed; + left:0; + right:0; + top:0; + bottom: 0; + background: rgba(0,0,0,.9); + color:#f1f1f1; +} +.g-core-image-corp-container .image-aside{ + position: absolute; + right: 30px; + left:30px; + top:60px; + bottom:20px; + text-align: center; +} +.g-core-image-corp-container .image-aside img{ + max-width: 100%; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.g-core-image-corp-container .info-aside{ + position: absolute; + left:0; + right: 0; + top:0; + height: 40px; + padding-left: 10px; + padding-right: 10px; + background: #fefefe; + color:#777; +} +.g-core-image-corp-container .btn-groups{ + text-align: right; + margin: 5px 0 0; +} +.g-core-image-corp-container .btn{ + display: inline-block; + padding: 0 15px; + height: 32px; + margin-left: 15px; + background: #fff; + border:1px solid #ccc; + border-radius: 2px; + font-size: 13px; + color:#222; + line-height: 32px; + transition: all .1s ease-in; +} +.g-core-image-corp-container .btn:hover{ + border:1px solid #777; + box-shadow: 0 1px 3px rgba(0,0,0,.05); +} +.g-core-image-corp-container .btn:active{ + background: #ddd; +} +.g-core-image-corp-container .btn:disabled{ + background: #eee !important; + border-color:#ccc; + cursor: not-allowed; +} +.g-core-image-corp-container .btn-upload{ + background: #27ae60; + border-color:#27ae60; + color:#fff; +} +.g-core-image-corp-container .btn-upload:hover{ + background: #2dc26c; + border-color:#27ae60; + box-shadow: 0 1px 3px rgba(0,0,0,.05); +} +.g-core-image-corp-container .g-crop-image-box,.g-core-image-corp-container .g-crop-image-box .g-crop-image-principal{ + position: relative; +} diff --git a/dist/vue-core-image-upload.vue b/dist/vue-core-image-upload.vue new file mode 100644 index 0000000..06345c0 --- /dev/null +++ b/dist/vue-core-image-upload.vue @@ -0,0 +1,273 @@ + + + + + diff --git a/site/client/components/Header.vue b/site/client/components/Header.vue index 00cbdf3..dfe0c21 100644 --- a/site/client/components/Header.vue +++ b/site/client/components/Header.vue @@ -1,6 +1,9 @@ - -