摘要:版本裁切工具,包含預覽功能最終效果源碼地址第一步先用安裝腳手架不會安裝的看官網初始化第二步創建文件新建里新建,在配置訪問路由具體看源碼最終生成的文件結構如下圖第三步注冊組件引用所有插件導入插件入口文件如果已安裝就跳過注冊插件全
vue版本裁切工具,包含預覽功能
最終效果: https://qiuyaofan.github.io/vue-crop-demo/
源碼地址: https://github.com/qiuyaofan/vue-crop
第一步:先用vue-cli安裝腳手架(不會安裝的看 vue-cli官網)// 初始化vue-cli vue init webpack my-plugin第二步:創建文件
新建src/views/validSlideDemo.vue, src/components里新建VueCrop/index.js,VueCrop.vue, 在routes/index.js配置訪問路由(具體看github源碼)
最終生成的文件結構如下圖:
// 導入插件入口文件 import VueCrop from "./VueCrop/index.js" const install = function (Vue, opts = {}) { /* 如果已安裝就跳過 */ if (install.installed) return // 注冊插件 Vue.component(VueCrop.name, VueCrop) } // 全局情況下注冊插件 if (typeof window !== "undefined" && window.Vue) { install(window.Vue) } export { install, // 此處是為了兼容在vue內多帶帶引入這個插件,如果是main.js全局引入就可以去掉 VueCrop }
import Vue from "vue" import App from "./App" import router from "./router" // 新加的:導入入口文件 import { install } from "src/components/index.js" // 全局調用,相當于調用 `MyPlugin.install(Vue)` Vue.use(install) Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: "#app", router, components: { App }, template: "" })
// 導入vue import VueCrop from "./VueCrop.vue" // Vue.js 的插件應當有一個公開方法 install 。這個方法的第一個參數是 Vue 構造器 VueCrop.install = function (Vue) { // 注冊組件 Vue.component(VueCrop.name, VueCrop) } export default VueCrop
function MyPlugin(){ console.info("構造函數") } MyPlugin.prototype.install=function(vue,options){ console.info("構造器vue:"+vue); }
而真正注冊組件的是:Vue.component()
所以,vue插件注冊的過程是:
1.調用main.js中: import { install } from "src/components/index.js" vue.use(install) 2.index.js添加install方法,調用Vue.component注冊組件 3.組件內的index.js同所有組件的index.js一樣第四步:設計開發自己的組件,構建組件結構
在此之前,可以先了解下組件的命名規范等,可參考文章 掘金:Vue前端開發規范,其中第2點有詳細講解
首先,確定自己的調用方式和需要暴露的參數
>
其中,@afterCrop="afterCrop"是裁切完成的回調函數,其他是屬性配置
在組件src/components/VueCrop/VueCrop.vue內,可以用this.$emit("afterCrop")觸發demo里的afterCrop事件
組件結構上,主要分為:裁切主體部分(VueCrop.vue),選框組件(VueCropTool.vue),裁切框寬度、位置坐標等計算(VueCropMove.js),拖拽事件注冊公共js(components/utils/draggable.js)
裁切插件的裁切主體由圖片,選框,預覽結構組成
選框(VueCropTool.vue)負責拖拽改變其大小,坐標位置等并返回給VueCrop.vue
主體計算數值同步預覽顯示(c-crop--preview)
主體觸發調用頁面(VueCropDemo.vue)的afterCrop事件,從而傳遞參數返回裁切后的url,left,top,bottom,right,x,y,w,h等
備注:此組件不具備真實的裁切功能,最終的裁切是傳遞給后臺去裁,你如果想擴展可以在afterCrop函數里根據坐標等信息進行處理
接下來我們對各個組件和js進行講解
export default function (element, options) { const moveFn = function (event) { if (options.drag) { options.drag(event) } } // mousedown fn const downFn = function (event) { if (options.start) { // 調用參數中start函數 options.start(event) } } // mouseup fn const upFn = function (event) { document.removeEventListener("mousemove", moveFn) document.removeEventListener("mouseup", upFn) document.onselectstart = null document.ondragstart = null if (options.end) { // 調用參數中end函數 options.end(event) } } // 綁定事件 element.addEventListener("mousedown", event => { if (options.stop && options.stop(event, element) === false) { return false } document.onselectstart = function () { return false } document.ondragstart = function () { return false } document.addEventListener("mousedown", downFn) document.addEventListener("mousemove", moveFn) document.addEventListener("mouseup", upFn) }) }
draggable(this.$el.querySelector(".c-crop--drap_screen"), { start: (event) => { this.startPos = [event.x, event.y] }, drag: (event) => { this.handleDragLocation(event) }, end: (event) => { this.handleDragLocation(event) } })
//script部分
//script部分
// 12種形態,四條邊,邊的中點,邊的四個角。e:東,w:西,n:北,s:南,ne:東南以此類推 const movePos = { 0: e, 4: e, 1: s, 5: s, 2: w, 6: w, 3: n, 7: n, 8: ne, 9: se, 10: sw, 11: nw } let width, height, result, ratio // 獲取某種形態類型的寬或高最大值 function getMaxSize (json, startJson, dire, type) { if (type === "w") { switch (dire) { case "e": case "s": case "n": case "ne": case "se": return json.screen.right - json.l case "w": case "nw": case "sw": return startJson.r - json.screen.left } } else if (type === "h") { switch (dire) { case "n": case "nw": case "ne": return startJson.b - json.screen.top case "s": case "w": case "e": case "sw": case "se": return json.screen.bottom - startJson.t } } } // 判斷是否有ratio,返回修改后的尺寸 function setRatioSize (type, json, startJson, ratio, width, height) { if (ratio) { if (width / ratio >= height) { var maxHeight = getMaxSize(json, startJson, type, "h") height = width / ratio if (height > maxHeight) { height = maxHeight width = height * ratio } } else { var maxWidth = getMaxSize(json, startJson, type, "w") width = height * ratio if (width > maxWidth) { width = maxWidth height = width / ratio } } } return { width: width, height: height } } // 拖拽東邊,高度是不變的,除非有比例拖拽時 function e (_this, json, startJson) { ratio = _this.cropJson.r width = range(getWidth(json, startJson, "e"), getMaxSize(json, startJson, "e", "w")) if (ratio) { // 有比例時,計算高度,并對比最大值是否超出 height = range(width / ratio, getMaxSize(json, startJson, "e", "h")) result = setRatioSize("e", json, startJson, ratio, width, height) setSize(_this, result) } else { _this.width = width } return _this } // 拖拽南邊,寬度是不變的,除非有比例拖拽時 function s (_this, json, startJson) { ratio = _this.cropJson.r height = range(getHeight(json, startJson, "s"), getMaxSize(json, startJson, "s", "h")) if (ratio) { // 有比例時,計算寬度,并對比最大值是否超出 width = range(height * ratio, getMaxSize(json, startJson, "s", "w")) result = setRatioSize("s", json, startJson, ratio, width, height) setSize(_this, result) } else { _this.height = height } return _this } // 以下同上,以此類推 function w (_this, json, startJson) { ratio = _this.cropJson.r width = range(getWidth(json, startJson, "w"), getMaxSize(json, startJson, "w", "w")) if (ratio) { height = range(width / ratio, getMaxSize(json, startJson, "w", "h")) result = setRatioSize("w", json, startJson, ratio, width, height) setSize(_this, result) _this.left = getLeft(_this, json, startJson) } else { _this.width = width _this.left = rangeMax(json.x - json.screen.left, startJson.r) } return _this } function n (_this, json, startJson) { ratio = _this.cropJson.r height = range(getHeight(json, startJson, "n"), getMaxSize(json, startJson, "n", "h")) if (ratio) { width = range(height * ratio, getMaxSize(json, startJson, "n", "w")) result = setRatioSize("n", json, startJson, ratio, width, height) setSize(_this, result) _this.top = getTop(_this, json, startJson) } else { _this.height = height _this.top = rangeMax(json.y - json.screen.top, startJson.b) } return _this } function ne (_this, json, startJson) { height = range(getHeight(json, startJson, "n"), getMaxSize(json, startJson, "ne", "h")) width = range(getWidth(json, startJson, "e"), getMaxSize(json, startJson, "ne", "w")) result = setRatioSize("ne", json, startJson, _this.cropJson.r, width, height) setSize(_this, result) _this.top = getTop(_this, json, startJson) return _this } function se (_this, json, startJson) { height = range(getHeight(json, startJson, "s"), getMaxSize(json, startJson, "se", "h")) width = range(getWidth(json, startJson, "e"), getMaxSize(json, startJson, "se", "w")) result = setRatioSize("se", json, startJson, _this.cropJson.r, width, height) setSize(_this, result) return _this } function sw (_this, json, startJson) { width = range(getWidth(json, startJson, "w"), getMaxSize(json, startJson, "sw", "w")) height = range(getHeight(json, startJson, "s"), getMaxSize(json, startJson, "sw", "h")) result = setRatioSize("sw", json, startJson, _this.cropJson.r, width, height) setSize(_this, result) _this.left = getLeft(_this, json, startJson) return _this } function nw (_this, json, startJson) { width = range(getWidth(json, startJson, "w"), getMaxSize(json, startJson, "nw", "w")) height = range(getHeight(json, startJson, "n"), getMaxSize(json, startJson, "nw", "h")) result = setRatioSize("nw", json, startJson, _this.cropJson.r, width, height) setSize(_this, result) _this.left = getLeft(_this, json, startJson) _this.top = getTop(_this, json, startJson) return _this } // 匹配范圍 function range (value, max) { value = value > max ? max : value return value < 20 ? 20 : value } // 最大值 function rangeMax (value, max) { return value > max ? max : value } // top function getTop (_this, json, startJson) { return rangeMax(startJson.b - _this.height - json.screen.top, startJson.b) } // left function getLeft (_this, json, startJson) { return rangeMax(startJson.r - _this.width - json.screen.left, startJson.r) } // height:只存在于s||n類型 function getHeight (json, startJson, type) { return type === "n" ? startJson.b - json.y : json.y - startJson.t } // width:只存在于w||e類型 function getWidth (json, startJson, type) { return type === "w" ? startJson.r - json.x : json.x - startJson.l } // setSize function setSize (_this, result) { _this.width = result.width _this.height = result.height } export default movePos
今天就分享到這里啦~喜歡這個插件可以去 github star~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/94799.html
摘要:手把手教你寫組件庫最近在研究的實現,發現網上很少有關于插件具體實現的文章,官方的文檔也只是一筆帶過,對于新手來說并不算友好。 手把手教你寫 Vue UI 組件庫 最近在研究 muse-ui 的實現,發現網上很少有關于 vue 插件具體實現的文章,官方的文檔也只是一筆帶過,對于新手來說并不算友好。 筆者結合官方文檔,與自己的摸索總結,以最簡單的 FlexBox 組件為例子,帶大家入門 v...
摘要:終極解決方案所以我們要統一環境,直接使用渲染我們的組件,文檔可以參照音樂標題歌手專輯時長省去一些細節注意需要放在中,的透傳也不要忘了,這樣我們在外部想使用的一些屬性和事件才比較方便。 背景介紹 最近在做vue高仿網易云音樂的項目,在做的過程中發現音樂表格這個組件會被非常多的地方復用,而且需求比較復雜的和靈活。 預覽地址 源碼地址 圖片預覽 歌單詳情 showImg(https://se...
摘要:組件結構同組件結構通過方法獲取元素的大小及其相對于視口的位置,之后對提示信息進行定位。可以用來進行一些復雜帶校驗的彈窗信息展示,也可以只用于簡單信息的展示。可以通過屬性來顯示任意標題,通過屬性來修改顯示區域的寬度。 手把手教你擼個vue2.0彈窗組件 在開始之前需要了解一下開發vue插件的前置知識,推薦先看一下vue官網的插件介紹 預覽地址 http://haogewudi.me/k...
閱讀 3469·2021-09-02 09:53
閱讀 1792·2021-08-26 14:13
閱讀 2750·2019-08-30 15:44
閱讀 1313·2019-08-30 14:03
閱讀 1962·2019-08-26 13:42
閱讀 3014·2019-08-26 12:21
閱讀 1302·2019-08-26 11:54
閱讀 1899·2019-08-26 10:46