实现一个颜色选择器
颜色选取器要怎么做?最粗暴的就是3重循环覆盖所有色值。试试?
双重循环 + 滑块
<template>
<view class="content">
<view>色块:</view>
<view :style="`width: 100px;height:100px;background-color: ${rgb};`"></view>
<view>色值:</view>
<view>{{rgb}}</view>
<view class="picker">
<view v-for="(x, r) in 256" :key="r">
<view v-for="(y, g) in 256" :key="g"
:style="`width: 1px; height: 1px; background-color: rgb(${r}, ${g}, ${b})`" @click="getColor(r, g)">
</view>
</view>
<view class="spin" :style="`left: ${r-10}px;top:${g-10}px;background-color: rgb(${r}, ${g}, ${b})`"></view>
</view>
<slider style="width: 90%" value="0" @change="sliderChange" min="0" max="255" show-value />
</view>
</template>
<script>
export default {
data() {
return {
r: 0,
g: 0,
b: 0,
rgb: ''
}
},
methods: {
sliderChange(e) {
this.b = e.target.value;
this.rgb = `rgb(${this.r}, ${this.g}, ${this.b})`
this.$forceUpdate()
},
getColor(r, g) {
this.r = r;
this.g = g;
this.rgb = `rgb(${r}, ${g}, ${this.b})`;
}
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.picker {
position: relative;
width: 256px;
height: 256px;
display: flex;
flex-wrap: wrap;
}
.spin {
width: 20px;
height: 20px;
border-radius: 10px;
position: absolute;
border: 2px solid #fff;
box-sizing: border-box;
}
</style>
效果如下:
貌似是完成了,但是!细心的同学一定发现了猫腻,双重循环下,页面渲染div就是256 * 256 = 65536 个div
这样页面必然卡成狗。那怎么办呢,欸,我们可以用css3的渐变色,将一行256个div变成一个div。这样页面元素就大大减少了,说干就干!
渐变 + 一重循环
<template>
<view class="content">
<view>色块:</view>
<view :style="`width: 100px;height:100px;background-color: ${rgb};`"></view>
<view>色值:</view>
<view>{{rgb}}</view>
<view class="picker" id="picker">
<view v-for="(x, g) in 256" :key="g"
@click="getColor"
:style="`width: 256px;height: 1px;background: linear-gradient(to right, rgb(0,${g},${b}) , rgb(255,${g},${b} ));`">
</view>
<view class="spin" :style="`left: ${r-10}px;top:${g-10}px;background-color: rgb(${r}, ${g}, ${b})`"></view>
</view>
<slider style="width: 90%" value="0" @change="sliderChange" min="0" max="255" show-value />
</view>
</template>
<script>
export default {
data() {
return {
r: 0,
g: 0,
b: 0,
rgb: ''
}
},
methods: {
sliderChange(e) {
this.b = e.target.value;
this.rgb = `rgb(${this.r}, ${this.g}, ${this.b})`
this.$forceUpdate()
},
getColor(e) {
this.g = e.target.offsetTop;
this.r = e.target.x - document.getElementById('picker').offsetLeft
this.rgb = `rgb(${this.r}, ${this.g}, ${this.b})`;
}
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.picker {
position: relative;
width: 256px;
height: 256px;
display: flex;
flex-wrap: wrap;
}
.spin {
width: 20px;
height: 20px;
border-radius: 10px;
position: absolute;
border: 2px solid #fff;
box-sizing: border-box;
}
</style>
由于是渐变的,所以需要通过鼠标点击的位置来确定点的是什么色值。这样改进之后,页面顺畅了100倍。
业界做法
业界的color-picker是怎么实现的,我还没去研究过,应该比上述的方法要优雅得多,有兴趣的同学可以去学习学习,然后评论区教我啊,哈哈哈,今天就到这里了,晚安!
转载自:https://juejin.cn/post/7102422599988150279