View Code? Open in Web Editor
NEW
It's a scoobie oobie doobie, scoobie doobie webcam effector. https://youtu.be/Hy8kmNEo1i8?t=170
Home Page: https://okathira.github.io/scoobie-doobie-effector/
HTML 10.04%
TypeScript 89.96%
scoobie-doobie-effector's Introduction
scoobie-doobie-effector's People
Contributors
Stargazers
Watchers
scoobie-doobie-effector's Issues
作成したクリッピングボックスを上下左右反転できるようにしたい
|
onMouseDown={() => { |
|
setMouseDownPos( |
|
getRelativePointerPosition(inputAreaRef) ?? { x: 0, y: 0 } |
|
); |
|
setDragging(true); |
|
}} |
|
onMouseUp={() => { |
|
addBoxProps(); |
|
setDragging(false); |
|
}} |
範囲外でクリックし始めて範囲内でクリックし終えたときと、
範囲外でクリックし終えて範囲内でクリックし始めたときの
挙動を直す。
|
export const makeGrayscale = (image: ImageData) => { |
|
const l = image.data.length / 4; // RGBA |
|
for (let i = 0; i < l; i++) { |
|
const grayscale = |
|
image.data[i * 4 + 0] * 0.299 + |
|
image.data[i * 4 + 1] * 0.587 + |
|
image.data[i * 4 + 2] * 0.114; |
|
|
|
const s = (grayscale * grayscale) / 255 / 255; |
|
|
|
image.data[i * 4 + 0] = (s + 0.008) * 255; |
|
image.data[i * 4 + 1] = (s + 0.014) * 255 + 1.9; |
|
image.data[i * 4 + 2] = (s + 0.004) * 255; |
|
} |
|
}; |
ピクセルごと毎回計算しているため遅い
grayscale を 256 段階と考えれば、そこから求められる RGB 値の組み合わせも 256 個しかないためテーブル化やメモ化でどうにかできそう?
baseCanvasの更新方法を適切なものにする。
作成したクリッピングボックスのクリップ範囲はそのまま,ボックスをリサイズできるようにしたい
|
boxesProps: BoxProps[]; // TODO: コンテキストにするとレンダリングされないのを治す |
|
const OutputArea: React.FC<{ |
|
layoutSize: RectSize; |
|
baseCanvas: CanvasImageSource; |
|
}> = ({ layoutSize, baseCanvas }) => { |
|
// TODO: 子に渡しているだけのため消したい |
|
const boxesProps = useBoxesProps(); |
|
|
|
return ( |
|
<Stage |
|
className="output-area" |
|
width={layoutSize.width} |
|
height={layoutSize.height} |
|
> |
|
<Layer> |
|
<Image image={baseCanvas} /> |
|
<ClippingBoxes currentFrame={baseCanvas} boxesProps={boxesProps} /> |
|
</Layer> |
|
</Stage> |
|
); |
|
}; |
Context が常に初期値になってた
Context
は <canvas>
を通らない
facebook/react#13336
facebook/react#13332 (comment)
Context
は <Layer>
以下のような dom に属さないコンポーネントまでたどり着かない
ブリッジさせるしかないらしい
konvajs/react-konva#188 (comment)
facebook/react#17275 (comment)
|
<SelectionRect |
|
beginPos={mouseDownPos} |
|
endPos={getRelativePointerPosition(inputAreaRef) || { x: 0, y: 0 }} |
|
// FIXME: endPosの更新タイミングで描画されず、baseCanvasの更新により描画されている。 |
|
/> |
<SelectionRect>
の描画更新タイミングを、ドラッグ中のマウスポインターに動きがあったときとしたい。
クリッピングボックスを生成する際にドラッグしている範囲をわかりやすくしたい
|
onTransformEnd={() => { |
|
// FIXME: 変形中は表示倍率を変更しているため枠線にも影響が出るのに対し、 |
|
// 変形後は枠線の幅が戻るため、結果を確認しながら操作ができなくなっている。 |
|
|
|
// transformerはnodeのscaleを変更し、widthとheightはそのまま。 |
|
// しかし、データの管理を容易にするため、変形終了時にスケールをリセットする。 |
|
const node = shapeRef.current!; |
|
const scaleX = node.scaleX(); |
|
const scaleY = node.scaleY(); |
|
|
|
// もとに戻す |
|
node.scaleX(1); |
|
node.scaleY(1); |
|
|
|
onChange({ |
|
...boxProps, |
|
x: node.x(), |
|
y: node.y(), |
|
// 最小値を指定する |
|
width: Math.max(minimumBoxSize, node.width() * scaleX), |
|
height: Math.max(minimumBoxSize, node.height() * scaleY), |
|
}); |
|
}} |
クリッピングボックスの作成される位置を,ドラッグした位置と相対的に同じになるようにする.
|
// グレイスケールならCSSでもできる。その場合はcanvasごとにフィルターがかかるため構造を変える必要がありそう。 |
|
export const makeGrayscale = (image: ImageData) => { |
|
const l = image.data.length / 4; |
|
for (let i = 0; i < l; i++) { |
|
const grayscale = |
|
image.data[i * 4 + 0] * 0.299 + |
|
image.data[i * 4 + 1] * 0.587 + |
|
image.data[i * 4 + 2] * 0.114; |
|
|
|
image.data[i * 4 + 0] = grayscale; |
|
image.data[i * 4 + 1] = grayscale; |
|
image.data[i * 4 + 2] = grayscale; |
|
} |
|
}; |
|
const image = ctx.getImageData(0, 0, canvasSize.width, canvasSize.height); |
|
makeGrayscale(image); |
|
ctx.putImageData(image, 0, 0); |
グレイスケールだけなら CSS の filter で高速に処理できる。
CSS は、 <canvas>
となる <Konva.Stage>
ごとにしかかけられないため、構造を考える必要がありそう。
カメラ映像のリフレッシュレートを state で保持する