UNPKG

konva

Version:

HTML5 2d canvas library for interactive graphics, design editors, whiteboards, and diagrams.

86 lines (85 loc) • 3.6 kB
import { Util } from "./Util.js"; import { Container } from "./Container.js"; import { _registerNode } from "./Global.js"; import { Factory } from "./Factory.js"; import { getBooleanValidator } from "./Validators.js"; /** * Group constructor. Groups are used to contain shapes or other groups. * @constructor * @memberof Konva * @augments Konva.Container * @param {Object} config * @param {Boolean} [config.isolated=false] composite children as one live image * @@nodeParams * @@containerParams * @example * var group = new Konva.Group(); */ export class Group extends Container { _validateAdd(child) { const type = child.getType(); if (type !== 'Group' && type !== 'Shape') { Util.throw('You may only add groups and shapes to groups.'); } } _drawChildNodes(drawMethod, canvas, top) { // cache() already provides an isolated surface and owns its snapshot. if (drawMethod !== 'drawScene' || !this.isolated() || top === this) { return super._drawChildNodes(drawMethod, canvas, top); } if (!canvas.width || !canvas.height) { return; } const context = canvas.getContext(); const surface = canvas._prepareIsolationCanvas(this.getClientRect({ _forDrawing: true, relativeTo: top })); const surfaceContext = surface.getContext(); surfaceContext._opacityRoot = this; context.save(); try { super._drawChildNodes(drawMethod, surface, top); context._applyOpacity(this); context._drawDeviceBuffer(surface); } catch (error) { // A throwing sceneFunc can leave unbalanced saves or a clip on the // scratch context. Discard it rather than contaminate the next draw. canvas._releaseIsolationCanvas(); throw error; } finally { context.restore(); surfaceContext._opacityRoot = undefined; } } } /** * Get or set group isolation. Default is false. * An isolated group draws its children into a transparent canvas on each scene draw. * The group opacity and globalCompositeOperation apply once to the completed image. * Child blend modes and erasing affect only the content inside that canvas. * * Explicit cache() calls keep their snapshot behavior. clearCache() resumes live drawing. * Hit testing keeps its normal behavior, including hits on erased content. * For video or canvas sources, schedule draws when the source changes. * * Buffers use conservative content bounds at the destination pixel ratio. * Moving the buffer origin changes native edge coverage. A few edge pixels * can differ substantially; isolation does not promise pixel-identical antialiasing. * Like cache(), isolation requires custom drawing (sceneFunc, charRenderFunc) to provide accurate * bounds, including any pixels it paints outside its size: selfRectFunc or a * getSelfRect() override. * Text is bounded by its lines plus one font size, so a glyph with many stacked * marks can be clipped. node-canvas shadows can change with bitmap origin. * Siblings reuse a buffer; unused or oversized buffers are freed after each layer draw. * @name Konva.Group#isolated * @method * @param {Boolean} isolated * @returns {Boolean} * @example * const group = new Konva.Group({ isolated: true, opacity: 0.5 }); * group.add(shape1, shape2); * group.isolated(false); */ Factory.addGetterSetter(Group, 'isolated', false, getBooleanValidator()); Group.prototype.nodeType = 'Group'; _registerNode(Group);