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)用它的頁(yè)面中傳過(guò)去。
組件代碼(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;
? ? ? ? ? ? ? ? // 通過(guò) width 和 height 遍歷 imgData 對(duì)象,每隔 gap 個(gè)點(diǎn)取一次像素,找到紅色的像素,
? ? ? ? ? ? ? ? // 每找到一個(gè)紅色點(diǎn),就創(chuàng)建一個(gè) Dot 對(duì)象,并添加到 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ù)是漸變開(kāi)始的橫縱坐標(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;
? ? ? ? ? ? ? ? ? ? ? ? //可以通過(guò)下面的方法獲得當(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)該組件整體為相對(duì)位置時(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})$/;
? ? // 把顏色值變成小寫(xiě)
? ? 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è)為相對(duì)位置,頁(yè)面中的坐標(biāo)設(shè)置都是相對(duì)于最外層div的,所以在設(shè)置點(diǎn)擊位置的時(shí)候要減去最外層div的距離頂部的高度。即
var pos = {
x: e.clientX,
y: e.clientY-outDiv.offsetTop//當(dāng)該組件整體為相對(duì)位置時(shí),y軸的坐標(biāo)是當(dāng)前點(diǎn)的位置-最外層距離頂點(diǎn)的高度
}
到此這篇關(guān)于VUE 自定義取色器組件的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)VUE 取色器 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于ElementUI實(shí)現(xiàn)v-tooltip指令的示例代碼
文本溢出隱藏并使用tooltip 提示的需求,相信在平時(shí)的開(kāi)發(fā)中會(huì)經(jīng)常遇到,常規(guī)做法一般是使用 elementui 的 el-tooltip 組件,在每次組件更新的時(shí)候去獲取元素的寬度/高度判斷是否被隱藏,本文給大家介紹了基于ElementUI實(shí)現(xiàn)v-tooltip指令,需要的朋友可以參考下2024-09-09
Vuex拿到state中數(shù)據(jù)的3種方式與實(shí)例剖析
store是一個(gè)狀態(tài)管理工具(vueX中只有唯一 一個(gè)store),下面這篇文章主要給大家介紹了關(guān)于Vuex拿到state中數(shù)據(jù)的3種方式與實(shí)例剖析的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09
詳解Vue組件實(shí)現(xiàn)tips的總結(jié)
這篇文章主要介紹了詳解Vue組件實(shí)現(xiàn)tips的總結(jié),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-11
vue element 生成無(wú)線級(jí)左側(cè)菜單的實(shí)現(xiàn)代碼
這篇文章主要介紹了vue element 生成無(wú)線級(jí)左側(cè)菜單的實(shí)現(xiàn)代碼,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-08-08
使用webpack搭建vue項(xiàng)目及注意事項(xiàng)
這篇文章主要介紹了使用webpack搭建vue項(xiàng)目的方法,本文以開(kāi)發(fā)環(huán)境為例,通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-06-06
Vue.set與this.$set的用法與使用場(chǎng)景介紹
Vue.set()和this.$set()這兩個(gè)api的實(shí)現(xiàn)原理基本一模一樣,都是使用了set函數(shù),下面這篇文章主要給大家介紹了關(guān)于Vue.set與this.$set的用法與使用場(chǎng)景,需要的朋友可以參考下2022-03-03

