HTML5 Canvas 禁用完美绘制提示
在某些情况下,在画布上绘图可能会出现意想不到的效果。 例如,让我们绘制一个带有填充、描边和不透明度的形状。 由于描边在填充之上绘制,形状内部会出现一条描边宽度一半的线条,这是较深的颜色 因为这是填充和描边的交集部分。
这可能不是你所期望的。因此,Konva
使用缓冲画布来修正此类行为。
在这种情况下,Konva
会执行以下步骤:
- 在缓冲画布上绘制形状
- 在不应用不透明度的情况下填充和描边
- 在图层画布上应用不透明度
- 最后在图层画布上绘制缓冲画布的结果
但使用缓冲画布可能会降低性能。因此,你可以禁用此类修正:
shape.perfectDrawEnabled(false);
如下图所示的效果差异:
- Vanilla
- React
- Vue
import Konva from 'konva'; const stage = new Konva.Stage({ container: 'container', width: window.innerWidth, height: window.innerHeight, }); const layer = new Konva.Layer(); stage.add(layer); // 使用完美绘制(默认) const perfectCircle = new Konva.Circle({ x: 100, y: 100, radius: 50, fill: 'red', stroke: 'black', strokeWidth: 10, opacity: 0.5, }); // 不使用完美绘制 const nonPerfectCircle = new Konva.Circle({ x: 250, y: 100, radius: 50, fill: 'red', stroke: 'black', strokeWidth: 10, opacity: 0.5, perfectDrawEnabled: false, }); // 添加标签 const perfectLabel = new Konva.Text({ x: 50, y: 170, text: '完美绘制', fontSize: 16, }); const nonPerfectLabel = new Konva.Text({ x: 200, y: 170, text: '禁用完美绘制', fontSize: 16, }); layer.add(perfectCircle); layer.add(nonPerfectCircle); layer.add(perfectLabel); layer.add(nonPerfectLabel);
import { Stage, Layer, Circle, Text } from 'react-konva'; const App = () => { return ( <Stage width={window.innerWidth} height={window.innerHeight}> <Layer> {/* 使用完美绘制(默认) */} <Circle x={100} y={100} radius={50} fill="red" stroke="black" strokeWidth={10} opacity={0.5} /> {/* 不使用完美绘制 */} <Circle x={250} y={100} radius={50} fill="red" stroke="black" strokeWidth={10} opacity={0.5} perfectDrawEnabled={false} /> {/* 标签 */} <Text x={50} y={170} text="完美绘制" fontSize={16} /> <Text x={200} y={170} text="禁用完美绘制" fontSize={16} /> </Layer> </Stage> ); }; export default App;
<template> <v-stage :config="stageSize"> <v-layer> <!-- 使用完美绘制(默认) --> <v-circle :config="perfectCircleConfig" /> <!-- 不使用完美绘制 --> <v-circle :config="nonPerfectCircleConfig" /> <!-- 标签 --> <v-text :config="perfectLabelConfig" /> <v-text :config="nonPerfectLabelConfig" /> </v-layer> </v-stage> </template> <script setup> import { ref } from 'vue'; const stageSize = { width: window.innerWidth, height: window.innerHeight }; const perfectCircleConfig = { x: 100, y: 100, radius: 50, fill: 'red', stroke: 'black', strokeWidth: 10, opacity: 0.5 }; const nonPerfectCircleConfig = { x: 250, y: 100, radius: 50, fill: 'red', stroke: 'black', strokeWidth: 10, opacity: 0.5, perfectDrawEnabled: false }; const perfectLabelConfig = { x: 50, y: 170, text: '完美绘制', fontSize: 16 }; const nonPerfectLabelConfig = { x: 200, y: 170, text: '禁用完美绘制', fontSize: 16 }; </script>