Skip to content

Commit

Permalink
基本完成所有功能,可以成功取色了
Browse files Browse the repository at this point in the history
  • Loading branch information
guowenfh committed Nov 10, 2018
1 parent 16b0ca6 commit 5522552
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 74 deletions.
8 changes: 7 additions & 1 deletion babel.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
module.exports = {
presets: ['@vue/app']
presets: ['@vue/app'],
plugins: [
[
'import',
{ libraryName: 'ant-design-vue', libraryDirectory: 'es', style: 'css' }
]
]
}
8 changes: 3 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"lint": "vue-cli-service lint"
},
"dependencies": {
"ant-design-vue": "^1.1.7",
"vue": "^2.5.17",
"vue-color": "^2.7.0",
"vue-router": "^3.0.1",
Expand All @@ -20,6 +21,7 @@
"@vue/cli-service": "^3.1.1",
"@vue/eslint-config-prettier": "^4.0.0",
"babel-eslint": "^10.0.1",
"babel-plugin-import": "^1.11.0",
"eslint": "^5.9.0",
"eslint-plugin-vue": "^5.0.0-0",
"husky": "^1.1.3",
Expand All @@ -34,11 +36,7 @@
}
},
"lint-staged": {
"*.js": [
"vue-cli-service lint --fix",
"git add"
],
"*.vue": [
"src/**/**.{js,vue}": [
"vue-cli-service lint --fix",
"git add"
]
Expand Down
224 changes: 157 additions & 67 deletions src/content_scripts/App.vue
Original file line number Diff line number Diff line change
@@ -1,38 +1,72 @@
<template>
<div :style="wrapStyle" id="color-picker-wrap" ref="pickWrap">
<table :style="rgbaArea">
<tr
v-for="(item, index) in matrix"
:key="'label' + index"
style="display:flex;"
>
<td
v-for="xyItem in item"
:key="xyItem.x + '-' + xyItem.y"
v-bind:style="{
backgroundColor: xyItem.backgroundColor,
height: '8px',
width: '8px',
boxShadow: `0 0px 0px 1px ${xyItem.isActive ? 'red' : '#ddd'}`,
zIndex: `${xyItem.isActive ? 1 : 0}`
}"
/>
</tr>
</table>
<div :style="position" v-if="isInit">
<table :style="rgbaArea">
<tr
v-for="(item, index) in matrix"
:key="'label' + index"
style="display:flex;"
>
<td
v-for="xyItem in item"
:key="xyItem.x + '-' + xyItem.y"
v-bind:style="{
backgroundColor: xyItem.backgroundColor,
height: '8px',
width: '8px',
boxShadow: `0 0px 0px 1px ${xyItem.isActive ? 'red' : '#ddd'}`,
zIndex: `${xyItem.isActive ? 1 : 0}`
}"
/>
</tr>
</table>

<input
type="text"
:value="activeHax"
id="color-picker-input"
:style="{ cursor: 'auto' }"
/>
<span
v-if="showChoseBtn"
:style="{
height: '20px',
width: '20px',
position: 'absolute',
top: 0,
right: '7px',
cursor: 'pointer',
background: `url(${closePng}) center center`,
'background-size': '100% 100%'
}"
@click="close"
></span>
</div>
</div>
</template>

<script>
import { loadImage, chunks } from '../common'
import crosshairPng from './crosshair.png'
import closePng from './close2x.png'
function pixelToRgba(data = []) {
const rgba = `rgba(${data[0]}, ${data[1]}, ${data[2]}, ${data[3] / 255})`
return rgba
const r = data[0]
const g = data[1]
const b = data[2]
const rgba = `rgba(${r}, ${g}, ${b}, ${data[3] / 255})`
return {
rgba,
r,
g,
b
}
}
function rgbToHex(r, g, b) {
return ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)
}
export default {
data() {
return {
matrix: [],
wrapStyle: {
display: 'none',
position: 'fixed',
Expand All @@ -45,88 +79,144 @@ export default {
height: 0
},
cursor: `url(${crosshairPng}) 12 12, crosshair;`,
position: {
top: '-1px',
left: '-1px',
position: 'absolute',
zIndex: 1111
},
rgbaArea: {
pointerEvents: 'none',
borderRadius: '50%',
overflow: 'hidden',
borderCollapse: 'collapse',
boxShadow: '0 0px 0px 1px #4c4c4c',
pointerEvents: 'none',
top: '-1px',
position: 'absolute',
left: '-1px',
zIndex: '1111'
boxShadow: '0 0px 0px 1px #4c4c4c'
},
mousePos: { x: -1, y: -1 },
closePng: closePng,
matrix: [], // 显示颜色值的正方形
showChoseBtn: false,
activeHax: 'ffffff',
ctx: null,
$canvas: null
$canvas: null,
isInit: false,
$pickImage: null
}
},
computed: {},
methods: {
rednerCanvas($canvas, styles = {}) {
Object.keys(styles).forEach(key => {
$canvas.setAttribute(key, styles[key])
})
this.$refs.pickWrap.appendChild($canvas)
rednerCanvas() {
this.$canvas = document.createElement('canvas')
this.ctx = this.$canvas.getContext('2d')
this.$canvas.setAttribute('id', 'color-picker-canvas')
this.$canvas.width = this.imgStyles.width
this.$canvas.height = this.imgStyles.height
this.$canvas.style.display = 'none'
// this.$refs.pickWrap.appendChild(this.$canvas)
},
mousemove(ev) {
const clientX = ev.clientX
const clientY = ev.clientY
this.rgbaArea.top = `${clientY + 10}px`
this.rgbaArea.left = `${clientX + 10}px`
const originX = clientX - 5
const originY = clientY - 5
const imageData = this.ctx.getImageData(originX, originY, 11, 11)
// 参考 https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas
// 每四个点表示一个 rgba 的值
const pixel = chunks(imageData.data, 4)
const rgbarr = chunks(pixel.map(item => pixelToRgba(item)), 11)
this.matrix = rgbarr.map((arr, yIndex) => {
return arr.map((rgba, xIndex) => {
const x = originX + xIndex
const y = originY + yIndex
return {
x,
y,
isActive: clientX === x && clientY === y,
backgroundColor: rgba
}
requestAnimationFrame(() => {
const clientX = ev.clientX
const clientY = ev.clientY
this.position.top = `${clientY + 10}px`
this.position.left = `${clientX + 10}px`
this.position.pointerEvents = 'none'
const originX = clientX - 5
const originY = clientY - 5
const imageData = this.ctx.getImageData(originX, originY, 11, 11)
// 参考 https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas
// 每四个点表示一个 rgba 的值
const pixel = chunks(imageData.data, 4)
const rgbarr = chunks(pixel.map(item => pixelToRgba(item)), 11)
this.matrix = rgbarr.map((arr, yIndex) => {
return arr.map((rgba, xIndex) => {
const x = originX + xIndex
const y = originY + yIndex
const isActive = clientX === x && clientY === y
if (isActive) {
this.activeHax = rgbToHex(rgba.r, rgba.g, rgba.b)
}
return {
x,
y,
isActive: isActive,
backgroundColor: rgba.rgba
}
})
})
})
},
click() {
this.$canvas.removeEventListener('mousemove', this.mousemove)
click(ev) {
if (!this.showChoseBtn) {
this.showChoseBtn = true
this.position.pointerEvents = 'initial'
this.$pickImage.removeEventListener('mousemove', this.mousemove)
const $input = document.getElementById('color-picker-input')
if ($input) {
$input.focus()
}
return
}
this.$pickImage.addEventListener('mousemove', this.mousemove)
this.$pickImage.addEventListener('click', this.click)
this.mousemove(ev)
this.showChoseBtn = false
},
close() {
if (this.$pickImage) {
this.$pickImage.removeEventListener('mousemove', this.mousemove)
this.$pickImage.removeEventListener('click', this.click)
this.$pickImage.parentNode.removeChild(this.$pickImage)
}
document.removeEventListener('keyup', this.keyup)
this.$canvas = null
this.ctx = null
this.showChoseBtn = false
this.isInit = false
},
keyup(ev) {
// ESC 键
console.log('----', ev.keyCode === 27)
if (ev.keyCode === 27) {
this.close()
}
}
},
destroyed() {
this.close()
},
mounted() {
document.addEventListener('keyup', this.keyup)
// 接收来自后台的消息
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.cmd == 'colorPicker') {
if (this.isInit) return
loadImage(request.data.src, img => {
this.$canvas = document.createElement('canvas')
this.$canvas.setAttribute('id', 'color-picker-canvas')
this.imgStyles = {
height: Math.floor(img.height / window.devicePixelRatio),
width: Math.floor(img.width / window.devicePixelRatio)
}
this.rednerCanvas(this.$canvas, this.imgStyles)
this.$canvas.style = `cursor:${this.cursor}`
img.id = 'color-picker-image'
img.style = `margin: 0px;padding: 0px;overflow: hidden;max-width: none !important;max-height: none !important;visibility: visible;width: ${
this.imgStyles.width
}px;height: auto;cursor:${this.cursor}`
this.$refs.pickWrap.appendChild(img)
this.$pickImage = img
this.rednerCanvas()
this.wrapStyle.height = `${this.imgStyles.height}px`
this.wrapStyle.width = `${this.imgStyles.width}px`
this.wrapStyle.display = 'block'
this.ctx = this.$canvas.getContext('2d')
this.ctx.drawImage(
img,
0,
0,
this.imgStyles.width,
this.imgStyles.height
)
this.$canvas.addEventListener('mousemove', this.mousemove)
this.$canvas.addEventListener('click', this.click)
this.$pickImage.addEventListener('mousemove', this.mousemove)
this.$pickImage.addEventListener('click', this.click)
this.isInit = true
})
}
sendResponse('我收到你的消息了:' + JSON.stringify(request))
Expand Down
Binary file added src/content_scripts/close.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/content_scripts/close2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion src/content_scripts/content-script.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ console.log('Hello from the content-script')

import Vue from 'vue'
import App from './App'

// 注意,必须设置了run_at=document_start 此段代码才会生效
console.time('-----')
document.addEventListener('DOMContentLoaded', function() {
Expand Down
Binary file added src/content_scripts/crosshair2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 5522552

Please sign in to comment.