mirror of
https://github.com/m1k1o/neko.git
synced 2024-07-24 14:40:50 +12:00
add click on color.
This commit is contained in:
parent
9b579a8cbd
commit
3eeb589f3f
219
src/page/components/color.vue
Normal file
219
src/page/components/color.vue
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
<template>
|
||||||
|
<div class="color">
|
||||||
|
<canvas ref="canvas"></canvas>
|
||||||
|
<div class="color-box" ref="color"></div>
|
||||||
|
<div v-if="x && y">Point: ({{ x }}, {{ y }})</div>
|
||||||
|
<div v-else>No point set</div>
|
||||||
|
<button @click="setPoint">Set</button>
|
||||||
|
<button @click="clearPoint">Clear</button>
|
||||||
|
<br />
|
||||||
|
<button v-if="!clickOnChange" @click="clickOnChange = true">Click on color change</button>
|
||||||
|
<button v-if="clickOnChange" @click="clickOnChange = false">Don't click</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/page/assets/styles/main.scss';
|
||||||
|
|
||||||
|
canvas {
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.color {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.color-box {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
height: 10px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { Vue, Component, Ref, Watch } from 'vue-property-decorator'
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
name: 'neko-color',
|
||||||
|
})
|
||||||
|
export default class extends Vue {
|
||||||
|
@Ref('canvas') readonly _canvas!: HTMLCanvasElement
|
||||||
|
@Ref('color') readonly _color!: HTMLDivElement
|
||||||
|
|
||||||
|
ctx!: CanvasRenderingContext2D | null
|
||||||
|
video!: HTMLVideoElement | null
|
||||||
|
interval!: number
|
||||||
|
picker!: HTMLDivElement | null
|
||||||
|
bullet!: HTMLDivElement | null
|
||||||
|
color!: string
|
||||||
|
|
||||||
|
x = 0
|
||||||
|
y = 0
|
||||||
|
clickOnChange = false
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.video = document.querySelector('video')
|
||||||
|
this.ctx = this._canvas.getContext('2d')
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeDestroy() {
|
||||||
|
if (this.interval) {
|
||||||
|
window.clearInterval(this.interval)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.clearPoint()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Watch('clickOnChange')
|
||||||
|
clickOnChangeChanged() {
|
||||||
|
if (this.clickOnChange) {
|
||||||
|
// register interval timer
|
||||||
|
this.interval = window.setInterval(this.intervalTimer, 0)
|
||||||
|
} else {
|
||||||
|
// unregister interval timer
|
||||||
|
window.clearInterval(this.interval)
|
||||||
|
this.color = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
intervalTimer() {
|
||||||
|
if (!this.video || !this.ctx) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this._canvas.width = this.video.videoWidth
|
||||||
|
this._canvas.height = this.video.videoHeight
|
||||||
|
this.ctx.clearRect(0, 0, this.video.videoWidth, this.video.videoHeight)
|
||||||
|
this.ctx.drawImage(this.video, 0, 0, this.video.videoWidth, this.video.videoHeight)
|
||||||
|
|
||||||
|
// get color from pixel at x,y
|
||||||
|
var pixel = this.ctx.getImageData(this.x, this.y, 1, 1)
|
||||||
|
var data = pixel.data
|
||||||
|
var rgba = 'rgba(' + data[0] + ', ' + data[1] + ', ' + data[2] + ', ' + data[3] / 255 + ')'
|
||||||
|
|
||||||
|
// if color is different, update it
|
||||||
|
if (this.color != rgba) {
|
||||||
|
if (this.clickOnChange && this.color) {
|
||||||
|
this.$emit('colorChange', { x: this.x, y: this.y })
|
||||||
|
this.clickOnChange = false
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('color change', rgba, this.color)
|
||||||
|
this._color.style.backgroundColor = rgba
|
||||||
|
this.color = rgba
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getCoords(elem: HTMLElement) {
|
||||||
|
// crossbrowser version
|
||||||
|
let box = elem.getBoundingClientRect()
|
||||||
|
|
||||||
|
let body = document.body
|
||||||
|
let docEl = document.documentElement
|
||||||
|
|
||||||
|
let scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop
|
||||||
|
let scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft
|
||||||
|
|
||||||
|
let clientTop = docEl.clientTop || body.clientTop || 0
|
||||||
|
let clientLeft = docEl.clientLeft || body.clientLeft || 0
|
||||||
|
|
||||||
|
let top = box.top + scrollTop - clientTop
|
||||||
|
let left = box.left + scrollLeft - clientLeft
|
||||||
|
|
||||||
|
return { top: Math.round(top), left: Math.round(left) }
|
||||||
|
}
|
||||||
|
|
||||||
|
setPoint() {
|
||||||
|
// create new element and add to body
|
||||||
|
var picker = document.createElement('div')
|
||||||
|
|
||||||
|
// coordinates of video element
|
||||||
|
var video = this.getCoords(this.video!)
|
||||||
|
|
||||||
|
// match that dimensions and offset matches video
|
||||||
|
picker.style.width = this.video!.offsetWidth + 'px'
|
||||||
|
picker.style.height = this.video!.offsetHeight + 'px'
|
||||||
|
picker.style.left = video.left + 'px'
|
||||||
|
picker.style.top = video.top + 'px'
|
||||||
|
picker.style.position = 'absolute'
|
||||||
|
picker.style.backgroundColor = 'rgba(0, 0, 0, 0.5)'
|
||||||
|
picker.style.cursor = 'crosshair'
|
||||||
|
|
||||||
|
// put it on top of video
|
||||||
|
picker.style.zIndex = '100'
|
||||||
|
|
||||||
|
document.body.appendChild(picker)
|
||||||
|
|
||||||
|
// add click event listener to new element
|
||||||
|
picker.addEventListener('click', this.clickPicker)
|
||||||
|
this.picker = picker
|
||||||
|
}
|
||||||
|
|
||||||
|
clearPoint() {
|
||||||
|
this.x = 0
|
||||||
|
this.y = 0
|
||||||
|
this.color = ''
|
||||||
|
this._color.style.backgroundColor = 'transparent'
|
||||||
|
|
||||||
|
if (this.bullet) {
|
||||||
|
this.bullet.remove()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.picker) {
|
||||||
|
this.picker.remove()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clickPicker(e: any) {
|
||||||
|
// get mouse position
|
||||||
|
var x = e.pageX
|
||||||
|
var y = e.pageY
|
||||||
|
|
||||||
|
// get picker position
|
||||||
|
var picker = this.getCoords(this.picker!)
|
||||||
|
|
||||||
|
// calculate new x,y position
|
||||||
|
var newX = x - picker.left
|
||||||
|
var newY = y - picker.top
|
||||||
|
|
||||||
|
// make it relative to video size
|
||||||
|
newX = Math.round((newX / this.video!.offsetWidth) * this.video!.videoWidth)
|
||||||
|
newY = Math.round((newY / this.video!.offsetHeight) * this.video!.videoHeight)
|
||||||
|
|
||||||
|
console.log(newX, newY)
|
||||||
|
|
||||||
|
// set new x,y position
|
||||||
|
this.x = newX
|
||||||
|
this.y = newY
|
||||||
|
|
||||||
|
// remove picker element
|
||||||
|
this.picker!.remove()
|
||||||
|
|
||||||
|
// add bullet element to the position
|
||||||
|
if (this.bullet) {
|
||||||
|
this.bullet.remove()
|
||||||
|
}
|
||||||
|
var bullet = document.createElement('div')
|
||||||
|
bullet.style.left = x + 'px'
|
||||||
|
bullet.style.top = y + 'px'
|
||||||
|
// width and height of bullet
|
||||||
|
bullet.style.width = '10px'
|
||||||
|
bullet.style.height = '10px'
|
||||||
|
// background color of bullet
|
||||||
|
bullet.style.backgroundColor = 'red'
|
||||||
|
// border radius of bullet
|
||||||
|
bullet.style.borderRadius = '50%'
|
||||||
|
// transform bullet to center
|
||||||
|
bullet.style.transform = 'translate(-50%, -50%)'
|
||||||
|
bullet.style.position = 'absolute'
|
||||||
|
bullet.style.zIndex = '100'
|
||||||
|
document.body.appendChild(bullet)
|
||||||
|
this.bullet = bullet
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -457,6 +457,12 @@
|
|||||||
<button @click="screenChangingToggle">screen cfg changing</button>
|
<button @click="screenChangingToggle">screen cfg changing</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>click on color</th>
|
||||||
|
<td>
|
||||||
|
<NekoColor @colorChange="neko.control.buttonPress(1, $event)" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -494,9 +500,13 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Vue, Component, Prop, Watch } from 'vue-property-decorator'
|
import { Vue, Component, Prop, Watch } from 'vue-property-decorator'
|
||||||
import Neko from '~/component/main.vue'
|
import Neko from '~/component/main.vue'
|
||||||
|
import NekoColor from './color.vue'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
name: 'neko-events',
|
name: 'neko-events',
|
||||||
|
components: {
|
||||||
|
NekoColor,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
export default class extends Vue {
|
export default class extends Vue {
|
||||||
@Prop() readonly neko!: Neko
|
@Prop() readonly neko!: Neko
|
||||||
|
Loading…
Reference in New Issue
Block a user