VUE 自定義取色器組件的實(shí)現(xiàn)
本文主要介紹了VUE 自定義取色器組件的實(shí)現(xiàn),分享給大家,具體如下:
效果:
功能:
1。點(diǎn)擊色塊中任何一點(diǎn),色塊中的正方形顯示該點(diǎn)的顏色。
2。點(diǎn)擊色塊上方的顏色圓點(diǎn),色塊選中該顏色所在的位置,并在正方形中顯示相應(yīng)顏色。
3。上方圓點(diǎn)如果不是rgb格式,需要轉(zhuǎn)換。
4。組件的大小從調(diào)用它的頁面中傳過去。
組件代碼(CanvasColor2.vue):
<template> <!-- ? ?<div>--> ? ? <div id='outDiv' style="position: relative"> <!-- ? ? ? ?<canvas class="box" id="show" :style="{width:canvasWidth+'px',height:canvasHeight+'px'}"></canvas>--> ? ? ? ? <canvas class="box" id="show" width="300px" height="150px"></canvas> ? ? ? ? <div class="cover" id='cover'></div> ? ? ? ? <em id="cur"></em> ? ? </div> </template> ? <script> ? ? export default { ? ? ? ? name: "CanvasColor2", ? ? ? ? data() { ? ? ? ? ? ? return { ? ? ? ? ? ? ? ? canvas:null, ? ? ? ? ? ? ? ? context:null, ? ? ? ? ? ? ? ? paramColor:'', ? ? ? ? ? ? ? ? viewWidth:0, ? ? ? ? ? ? ? ? viewHeight:0 ? ? ? ? ? ? } ? ? ? ? }, ? ? ? ? props:{ ? ? ? ? ? ? data:String, ? ? ? ? ? ? canvasWidth:Number, ? ? ? ? ? ? canvasHeight:Number, ? ? ? ? }, ? ? ? ? created() { ? ? ? ? ? ? this.viewWidth = this.canvasWidth; ? ? ? ? ? ? this.viewHeight = this.canvasHeight; ? ? ? ? }, ? ? ? ? mounted() { ? ? ? ? ? ? this.getParamColor('rgb(0,3,243)'); ? ? ? ? ? ? this.initData(); ? ? ? ? ? ? this.getDotList(); ? ? ? ? }, ? ? ? ? methods:{ ? ? ? ? ? ? async getDotList(){ ? ? ? ? ? ? ? ? this.canvas = document.getElementById("show"); ? ? ? ? ? ? ? ? this.context = this.canvas.getContext("2d"); ? ? ? ? ? ? ? ? console.log('getDotList',this.canvas.offsetLeft); ? ? ? ? ? ? ? ? // 獲取整個(gè) canvas 的像素信息 ? ? ? ? ? ? ? ? var imgData = this.context.getImageData(0, 0,this.canvas.width+this.canvas.offsetLeft, this.canvas.height+this.canvas.offsetTop); ? ? ? ? ? ? ? ? // 清空數(shù)組 ? ? ? ? ? ? ? ? var dotList = []; ? ? ? ? ? ? ? ? // 最后實(shí)現(xiàn)的效果每個(gè)點(diǎn)之間有一定的距離,gap 就是控制這個(gè)距離的 ? ? ? ? ? ? ? ? var gap = 1; ? ? ? ? ? ? ? ? // 通過 width 和 height 遍歷 imgData 對象,每隔 gap 個(gè)點(diǎn)取一次像素,找到紅色的像素, ? ? ? ? ? ? ? ? // 每找到一個(gè)紅色點(diǎn),就創(chuàng)建一個(gè) Dot 對象,并添加到 dotList 數(shù)組中 ? ? ? ? ? ? ? ? for (var x = 0; x < imgData.width; x += gap) { ? ? ? ? ? ? ? ? ? ? for (var y = 0; y < imgData.height; y += gap) { ? ? ? ? ? ? ? ? ? ? ? ? var i = (y * imgData.width + x) * 4; ? ? ? ? ? ? ? ? ? ? ? ? // console.log('getDotList',i); ? ? ? ? ? ? ? ? ? ? ? ? // 判斷像素點(diǎn)是不是紅色 ? ? ? ? ? ? ? ? ? ? ? ? if (imgData.data[i] == this.paramColor[0] && imgData.data[i + 1] == this.paramColor[1] && imgData.data[i + 2] == this.paramColor[2]) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? var dot = {x,y} ; ? ? ? ? ? ? ? ? ? ? ? ? ? ? dotList.push(dot); ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? if (dotList && dotList.length != 0) { ? ? ? ? ? ? ? ? ? ? var cur = document.getElementById('cur'); ? ? ? ? ? ? ? ? ? ? cur.style.left = (dotList[0].x+this.canvas.offsetLeft)+'px'; ? ? ? ? ? ? ? ? ? ? cur.style.top = (dotList[0].y+this.canvas.offsetTop)+'px'; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? console.log('dot',dotList); ? ? ? ? ? ? ? ? return dotList; ? ? ? ? ? ? }, ? ? ? ? ? ? initData() { ? ? ? ? ? ? ? ? var show = document.getElementById("show"); ? ? ? ? ? ? ? ? show.setAttribute("width",this.canvasWidth); ? ? ? ? ? ? ? ? show.setAttribute("height",this.canvasHeight); ? ? ? ? ? ? ? ? // var cover = document.getElementById("cover"); ? ? ? ? ? ? ? ? var cur = document.getElementById("cur"); ? ? ? ? ? ? ? ? if (show.getContext) {//首先判斷getcontext方法是否存在,這是一個(gè)良好的習(xí)慣 ? ? ? ? ? ? ? ? ? ? var context = show.getContext('2d'); ? ? ? ? ? ? ? ? ? ? var gradientBar = context.createLinearGradient(0, show.height, show.width, show.height);//創(chuàng)建漸變,前兩個(gè)參數(shù)是漸變開始的橫縱坐標(biāo),后兩個(gè)參數(shù)是漸變結(jié)束的橫縱坐標(biāo) ? ? ? ? ? ? ? ? ? ? ? gradientBar.addColorStop(0, '#ff0000'); ? ? ? ? ? ? ? ? ? ? gradientBar.addColorStop(1 / 6, '#ff00ff'); ? ? ? ? ? ? ? ? ? ? gradientBar.addColorStop(2 / 6, '#0000ff'); ? ? ? ? ? ? ? ? ? ? gradientBar.addColorStop(3 / 6, '#00ffff'); ? ? ? ? ? ? ? ? ? ? gradientBar.addColorStop(4 / 6, '#00ff00'); ? ? ? ? ? ? ? ? ? ? gradientBar.addColorStop(5 / 6, '#ffff00'); ? ? ? ? ? ? ? ? ? ? gradientBar.addColorStop(1, '#ff0000'); ? ? ? ? ? ? ? ? ? ? ? context.fillStyle = gradientBar; ? ? ? ? ? ? ? ? ? ? context.fillRect(0, 0, show.width, show.width); ? ? ? ? ? ? ? ? ? ? ? //白色透明黑色,明暗度實(shí)現(xiàn) ? ? ? ? ? ? ? ? ? ? var lightToDark = context.createLinearGradient(0, 0, 0, show.width); ? ? ? ? ? ? ? ? ? ? lightToDark.addColorStop(0, "#fff"); ? ? ? ? ? ? ? ? ? ? lightToDark.addColorStop(1 / 2, 'rgba(255,255,255,0)'); ? ? ? ? ? ? ? ? ? ? lightToDark.addColorStop(1, '#000'); ? ? ? ? ? ? ? ? ? ? ? context.fillStyle = lightToDark; ? ? ? ? ? ? ? ? ? ? context.fillRect(0, 0, show.width, show.width); ? ? ? ? ? ? ? ? ? ? ? show.addEventListener('click', function (e) { ? ? ? ? ? ? ? ? ? ? ? ? var ePos = { ? ? ? ? ? ? ? ? ? ? ? ? ? ? x: e.layerX || e.offsetX, ? ? ? ? ? ? ? ? ? ? ? ? ? ? y: e.layerY || e.offsetY ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? //前兩個(gè)參數(shù)為鼠標(biāo)的位置,后娘個(gè)參數(shù)為canvas的寬高 ? ? ? ? ? ? ? ? ? ? ? ? var imgData = context.getImageData(ePos.x, ePos.y, show.width, show.height).data; ? ? ? ? ? ? ? ? ? ? ? ? //可以通過下面的方法獲得當(dāng)前的rgb值 ? ? ? ? ? ? ? ? ? ? ? ? var red = imgData[0]; ? ? ? ? ? ? ? ? ? ? ? ? var green = imgData[1]; ? ? ? ? ? ? ? ? ? ? ? ? var blue = imgData[2]; ? ? ? ? ? ? ? ? ? ? ? ? var rgbStr = "rgb(" + red + "," + green + ',' + blue + ")"; ? ? ? ? ? ? ? ? ? ? ? ? console.log(rgbStr); ? ? ? ? ? ? ? ? ? ? ? ? var cover = document.getElementById("cover"); ? ? ? ? ? ? ? ? ? ? ? ? cover.style.backgroundColor = rgbStr; ? ? ? ? ? ? ? ? ? ? ? ? // var cur = document.getElementById("cur"); ? ? ? ? ? ? ? ? ? ? ? ? var outDiv = document.getElementById('outDiv'); ? ? ? ? ? ? ? ? ? ? ? ? console.log('outDiv',outDiv.offsetTop+','+outDiv.offsetHeight); ? ? ? ? ? ? ? ? ? ? ? ? var pos = { ? ? ? ? ? ? ? ? ? ? ? ? ? ? x: e.clientX, ? ? ? ? ? ? ? ? ? ? ? ? ? ? y: e.clientY-outDiv.offsetTop//當(dāng)該組件整體為相對位置時(shí),y軸的坐標(biāo)是當(dāng)前點(diǎn)的位置-最外層距離頂點(diǎn)的高度 ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? cur.style.left = pos.x + 'px'; ? ? ? ? ? ? ? ? ? ? ? ? cur.style.top = pos.y + 'px'; ? ? ? ? ? ? ? ? ? ? ? ? console.log('onmousemove',cur.style.left); ? ? ? ? ? ? ? ? ? ? }); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? }, ? ? ? ? ? ? getParamColor(color) { ? ? ? ? ? ? ? ? let param = color; ? ? ? ? ? ? ? ? console.log('getParamColor',param.length) ? ? ? ? ? ? ? ? param = param.substring(4,param.length-1); ? ? ? ? ? ? ? ? console.log('getParamColor',param) ? ? ? ? ? ? ? ? this.paramColor = param.split(','); ? ? ? ? ? ? ? ? this.getDotList(); ? ? ? ? ? ? ? ? var cover = document.getElementById("cover"); ? ? ? ? ? ? ? ? cover.style.backgroundColor = color; ? ? ? ? ? ? } ? ? ? ? } ? ? } </script> ? <style scoped> ? ? .box { ? ? ? ? position: relative; ? ? ? ? background-color: pink; ? ? ? ? /*margin: 30px;*/ ? ? ? ? border-radius: 15px; ? ? } ? ? /* 選擇顏色的小方格 */ ? ? #cur { ? ? ? ? width: 13px; ? ? ? ? height: 13px; ? ? ? ? outline: 2px solid #ffffff; ? ? ? ? margin-left: -1px; ? ? ? ? margin-top: -1px; ? ? ? ? position: absolute; ? ? ? ? border-radius: 13px; ? ? } ? ? ? #cover{ ? ? ? ? position: absolute; ? ? ? ? left: 100px; ? ? ? ? top: 10px; ? ? ? ? width: 50px; ? ? ? ? height: 50px; ? ? ? ? background-color: antiquewhite; ? ? ? ? /* cover作為遮罩擋住了canvas,使用這個(gè)可以穿透遮罩,點(diǎn)擊到下面的元素 */ ? ? ? ? pointer-events: none; ? ? } </style>
調(diào)用:
<template> ? ? <div style="background-color: black"> ? ? ? ? <div style="display: flex; height: 44px;align-items: center"> ? ? ? ? ? ? <div style="width: 100px;color: white">彩光</div> ? ? ? ? ? ? <div style="width: 100px;color: white">白光</div> ? ? ? ? </div> ? ? ? ? <div style="display: flex; height: 44px;align-items: center;"> ? ? ? ? ? ? <div class="btn_style-common" style="background-color: rgb(41,53,255)" @click="selectColor('rgb(41,53,255)')"></div> ? ? ? ? ? ? <div class="btn_style-common" style=" background-color: rgb(255,202,83)" @click="selectColor('rgb(255,202,83)')"></div> ? ? ? ? </div> ? ? ? ? <CanvasColor2 ref="canvasColor" :data="color" :canvas-width="340" :canvas-height="170"></CanvasColor2> ? ? </div> </template> ? <script> ? ? import CanvasColor2 from "./CanvasColor2"; ? ? import '../../util/utils.js' ? ? export default { ? ? ? ? name: "yxfColor", ? ? ? ? components:{ ? ? ? ? ? ? CanvasColor2 ? ? ? ? }, ? ? ? ? data() { ? ? ? ? ? ? return { ? ? ? ? ? ? ? ? color:'rgb(100,255,83)' ? ? ? ? ? ? } ? ? ? ? }, ? ? ? ? mounted() { ? ? ? ? ? ? this.$refs.canvasColor.getParamColor(this.color) ? ? ? ? }, ? ? ? ? methods:{ ? ? ? ? ? ? selectColor(color) { ? ? ? ? ? ? ? ? if (color.indexOf('rgb') != 0) { ? ? ? ? ? ? ? ? ? ? this.color = color.colorRgb(); ? ? ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? ? ? this.color = color; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? this.$refs.canvasColor.getParamColor(this.color) ? ? ? ? ? ? }, ? ? ? ? } ? ? } </script> ? <style scoped> .btn_style-common { ? ? height: 20px;width: 20px; border-radius: 20px;margin-left: 20px; } </style>
顏色從十六進(jìn)制轉(zhuǎn)換成RGB格式:utils.js
String.prototype.colorRgb = function () { ? ? // 16進(jìn)制顏色值的正則 ? ? var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/; ? ? // 把顏色值變成小寫 ? ? var color = this.toLowerCase(); ? ? if (reg.test(color)) { ? ? ? ? // 如果只有三位的值,需變成六位,如:#fff => #ffffff ? ? ? ? if (color.length === 4) { ? ? ? ? ? ? var colorNew = "#"; ? ? ? ? ? ? for (var i = 1; i < 4; i += 1) { ? ? ? ? ? ? ? ? colorNew += color.slice(i, i + 1).concat(color.slice(i, i + 1)); ? ? ? ? ? ? } ? ? ? ? ? ? color = colorNew; ? ? ? ? } ? ? ? ? // 處理六位的顏色值,轉(zhuǎn)為RGB ? ? ? ? var colorChange = []; ? ? ? ? for (var j = 1; j < 7; j += 2) { ? ? ? ? ? ? colorChange.push(parseInt("0x" + color.slice(j, j + 2))); ? ? ? ? } ? ? ? ? return "RGB(" + colorChange.join(",") + ")"; ? ? } else { ? ? ? ? return color; ? ? } };
注意:
組件中最外層的div的位置設(shè)為相對位置,頁面中的坐標(biāo)設(shè)置都是相對于最外層div的,所以在設(shè)置點(diǎn)擊位置的時(shí)候要減去最外層div的距離頂部的高度。即
var pos = { x: e.clientX, y: e.clientY-outDiv.offsetTop//當(dāng)該組件整體為相對位置時(shí),y軸的坐標(biāo)是當(dāng)前點(diǎn)的位置-最外層距離頂點(diǎn)的高度 }
到此這篇關(guān)于VUE 自定義取色器組件的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)VUE 取色器 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue 2.5 Level E 發(fā)布了: 新功能特性一覽
很高興Vue 2.5 Level E 發(fā)布了。在這篇文章中,我們將重點(diǎn)介紹一些更重要的的變化:更好的 TypeScript 集成,更好的錯(cuò)誤處理,更好地支持單文件組件中的函數(shù)式組件以及與環(huán)境無關(guān)的服務(wù)端渲染2017-10-10vue element-ul實(shí)現(xiàn)展開和收起功能的實(shí)例代碼
這篇文章主要介紹了vue element-ul實(shí)現(xiàn)展開和收起功能的實(shí)例代碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11使用form-create動(dòng)態(tài)生成vue自定義組件和嵌套表單組件
這篇文章主要介紹了使用form-create動(dòng)態(tài)生成vue自定義組件和嵌套表單組件,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-01-01vue如何根據(jù)不同的環(huán)境使用不同的接口地址
這篇文章主要介紹了vue如何根據(jù)不同的環(huán)境使用不同的接口地址問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04vue3中使用router路由實(shí)現(xiàn)跳轉(zhuǎn)傳參的方法
這篇文章主要介紹了vue3中使用router路由實(shí)現(xiàn)跳轉(zhuǎn)傳參的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03vue與django(drf)實(shí)現(xiàn)文件上傳下載功能全過程
最近簡單的學(xué)習(xí)了django和drf上傳文件(主要是圖片),做一個(gè)記錄,下面這篇文章主要給大家介紹了關(guān)于vue與django(drf)實(shí)現(xiàn)文件上傳下載功能的相關(guān)資料,需要的朋友可以參考下2023-02-02