将 Caman JS 预设过滤器应用于 Konva React
Apply Caman JS preset filters to Konva React
通过为图层组件创建一个 ref,我可以访问 canvas 元素,然后我可以将其传递给 caman 函数以将预设滤镜应用于 canvas 中的图像。然而,这按预期工作,当将舞台保存为图像时,过滤器未应用。如何将 Konva 舞台导出为应用了卡曼滤镜的图像。
组件Editor.js
import React, {useRef} from 'react';
import {Stage, Layer, Image} from 'react-konva';
import EditorControls from './EditorControls';
const caman = window.Caman;
const Editor = ({image}) => {
const stageRef = useRef();
const mainLayer = useRef();
const filterSelect = filter => {
const canvas = mainLayer.current.canvas._canvas;
caman(canvas, image, function() {
this.revert();
if (!filter) {return;}
this[filter]().render();
});
}
return (
<div className='Editor'>
<Stage
width={500}
height={500}
ref={stageRef}
>
<Layer ref={mainLayer}>
<Image
x={0}
y={0}
width={500}
height={500}
image={image}
/>
</Layer>
</Stage>
<EditorControls
onFilterSelect={filterSelect}
/>
<button
onClick={() => {
const link = document.createElement('a');
link.download = 'test.png';
link.href = stageRef.current.getStage().toDataURL({pixelRatio: 3});
link.click();
link.remove();
}}
>
SAVE
</button>
</div>
);
}
export default Editor;
组件EditorControls.js
import React from 'react';
const filters = ['vintage', 'lomo', 'clarity', 'sinCity', 'sunrise', 'crossProcess', 'orangePeel', 'love', 'grungy', 'jarques', 'pinhole', 'oldBoot', 'glowingSun', 'hazyDays', 'herMajesty', 'nostalgia', 'hemingway', 'concentrate'];
const EditorControls = ({onFilterSelect}) => {
return (
<div className='EditorControls'>
<div className='EditorControls__filters'>
<button onClick={() => onFilterSelect('')}>
<p>noFilter</p>
</button>
{filters.map((filter, index) => (
<button key={filters[index]} onClick={() => onFilterSelect(filter)}>
<p>{filters[index]}</p>
</button>
))}
</div>
</div>
);
}
export default EditorControls;
根据 https://konvajs.org/docs/sandbox/Native_Context_Access.html,不建议手动更改 canvas 内容(在您的情况下通过 Caman 操作)。
如果你想申请卡曼,你可以:
- 缓存节点并编写您自己的自定义过滤器https://konvajs.org/docs/filters/Custom_Filter.html。要使其与 Caman 一起使用,您可以将 Konva 过滤器中使用的 imageData 转换为 canvas,然后应用 Caman 过滤器,然后转换回 imageData
- 或者,如果您只想应用过滤器一次(在导出时),您可以先使用 node.toCanvas() method 将节点转换为
<canvas>
元素。然后在 Caman 中使用结果 canvas。
通过为图层组件创建一个 ref,我可以访问 canvas 元素,然后我可以将其传递给 caman 函数以将预设滤镜应用于 canvas 中的图像。然而,这按预期工作,当将舞台保存为图像时,过滤器未应用。如何将 Konva 舞台导出为应用了卡曼滤镜的图像。
组件Editor.js
import React, {useRef} from 'react';
import {Stage, Layer, Image} from 'react-konva';
import EditorControls from './EditorControls';
const caman = window.Caman;
const Editor = ({image}) => {
const stageRef = useRef();
const mainLayer = useRef();
const filterSelect = filter => {
const canvas = mainLayer.current.canvas._canvas;
caman(canvas, image, function() {
this.revert();
if (!filter) {return;}
this[filter]().render();
});
}
return (
<div className='Editor'>
<Stage
width={500}
height={500}
ref={stageRef}
>
<Layer ref={mainLayer}>
<Image
x={0}
y={0}
width={500}
height={500}
image={image}
/>
</Layer>
</Stage>
<EditorControls
onFilterSelect={filterSelect}
/>
<button
onClick={() => {
const link = document.createElement('a');
link.download = 'test.png';
link.href = stageRef.current.getStage().toDataURL({pixelRatio: 3});
link.click();
link.remove();
}}
>
SAVE
</button>
</div>
);
}
export default Editor;
组件EditorControls.js
import React from 'react';
const filters = ['vintage', 'lomo', 'clarity', 'sinCity', 'sunrise', 'crossProcess', 'orangePeel', 'love', 'grungy', 'jarques', 'pinhole', 'oldBoot', 'glowingSun', 'hazyDays', 'herMajesty', 'nostalgia', 'hemingway', 'concentrate'];
const EditorControls = ({onFilterSelect}) => {
return (
<div className='EditorControls'>
<div className='EditorControls__filters'>
<button onClick={() => onFilterSelect('')}>
<p>noFilter</p>
</button>
{filters.map((filter, index) => (
<button key={filters[index]} onClick={() => onFilterSelect(filter)}>
<p>{filters[index]}</p>
</button>
))}
</div>
</div>
);
}
export default EditorControls;
根据 https://konvajs.org/docs/sandbox/Native_Context_Access.html,不建议手动更改 canvas 内容(在您的情况下通过 Caman 操作)。
如果你想申请卡曼,你可以:
- 缓存节点并编写您自己的自定义过滤器https://konvajs.org/docs/filters/Custom_Filter.html。要使其与 Caman 一起使用,您可以将 Konva 过滤器中使用的 imageData 转换为 canvas,然后应用 Caman 过滤器,然后转换回 imageData
- 或者,如果您只想应用过滤器一次(在导出时),您可以先使用 node.toCanvas() method 将节点转换为
<canvas>
元素。然后在 Caman 中使用结果 canvas。