UNPKG

@shopify/react-native-skia

Version:

High-performance React Native Graphics using Skia

355 lines (333 loc) 9.46 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.drawVertices = exports.drawTextPath = exports.drawTextBlob = exports.drawText = exports.drawSkottie = exports.drawRect = exports.drawRRect = exports.drawPoints = exports.drawPicture = exports.drawPath = exports.drawPatch = exports.drawParagraph = exports.drawOval = exports.drawLine = exports.drawImageSVG = exports.drawImage = exports.drawGlyphs = exports.drawDiffRect = exports.drawCircle = exports.drawAtlas = void 0; var _nodes = require("../../../dom/nodes"); var _processors = require("../../../renderer/processors"); var _types = require("../../../skia/types"); const drawLine = (ctx, props) => { "worklet"; const { p1, p2 } = props; ctx.canvas.drawLine(p1.x, p1.y, p2.x, p2.y, ctx.paint); }; exports.drawLine = drawLine; const drawOval = (ctx, props) => { "worklet"; const rect = (0, _nodes.processRect)(ctx.Skia, props); ctx.canvas.drawOval(rect, ctx.paint); }; exports.drawOval = drawOval; const drawImage = (ctx, props) => { "worklet"; const { image, sampling } = props; if (image) { var _props$fit; const fit = (_props$fit = props.fit) !== null && _props$fit !== void 0 ? _props$fit : "contain"; const rect = (0, _nodes.processRect)(ctx.Skia, props); const { src, dst } = (0, _nodes.fitRects)(fit, { x: 0, y: 0, width: image.width(), height: image.height() }, rect); if (sampling && (0, _types.isCubicSampling)(sampling)) { ctx.canvas.drawImageRectCubic(image, src, dst, sampling.B, sampling.C, ctx.paint); } else { var _sampling$filter, _sampling$mipmap; ctx.canvas.drawImageRectOptions(image, src, dst, (_sampling$filter = sampling === null || sampling === void 0 ? void 0 : sampling.filter) !== null && _sampling$filter !== void 0 ? _sampling$filter : _types.FilterMode.Linear, (_sampling$mipmap = sampling === null || sampling === void 0 ? void 0 : sampling.mipmap) !== null && _sampling$mipmap !== void 0 ? _sampling$mipmap : _types.MipmapMode.None, ctx.paint); } } }; exports.drawImage = drawImage; const drawPoints = (ctx, props) => { "worklet"; const { points, mode } = props; ctx.canvas.drawPoints(_types.PointMode[(0, _nodes.enumKey)(mode)], points, ctx.paint); }; exports.drawPoints = drawPoints; const drawVertices = (ctx, props) => { "worklet"; const { mode, textures, colors, indices, blendMode } = props; const vertexMode = mode ? _types.VertexMode[(0, _nodes.enumKey)(mode)] : _types.VertexMode.Triangles; const vertices = ctx.Skia.MakeVertices(vertexMode, props.vertices, textures, colors ? colors.map(c => (0, _nodes.processColor)(ctx.Skia, c)) : undefined, indices); const defaultBlendMode = colors ? _types.BlendMode.DstOver : _types.BlendMode.SrcOver; const blend = blendMode ? _types.BlendMode[(0, _nodes.enumKey)(blendMode)] : defaultBlendMode; ctx.canvas.drawVertices(vertices, blend, ctx.paint); }; exports.drawVertices = drawVertices; const drawDiffRect = (ctx, props) => { "worklet"; const { outer, inner } = props; ctx.canvas.drawDRRect(outer, inner, ctx.paint); }; exports.drawDiffRect = drawDiffRect; const drawTextPath = (ctx, props) => { "worklet"; const path = (0, _nodes.processPath)(ctx.Skia, props.path); const { font, initialOffset } = props; if (font) { let { text } = props; const ids = font.getGlyphIDs(text); const widths = font.getGlyphWidths(ids); const rsx = []; const meas = ctx.Skia.ContourMeasureIter(path, false, 1); let cont = meas.next(); let dist = initialOffset; for (let i = 0; i < text.length && cont; i++) { const width = widths[i]; dist += width / 2; if (dist > cont.length()) { // jump to next contour cont = meas.next(); if (!cont) { // We have come to the end of the path - terminate the string // right here. text = text.substring(0, i); break; } dist = width / 2; } // Gives us the (x, y) coordinates as well as the cos/sin of the tangent // line at that position. const [p, t] = cont.getPosTan(dist); const adjustedX = p.x - width / 2 * t.x; const adjustedY = p.y - width / 2 * t.y; rsx.push(ctx.Skia.RSXform(t.x, t.y, adjustedX, adjustedY)); dist += width / 2; } const derived = ctx.Skia.TextBlob.MakeFromRSXform(text, rsx, font); ctx.canvas.drawTextBlob(derived, 0, 0, ctx.paint); } }; exports.drawTextPath = drawTextPath; const drawText = (ctx, props) => { "worklet"; const { text, x, y, font } = props; if (font != null) { ctx.canvas.drawText(text, x, y, ctx.paint, font); } }; exports.drawText = drawText; const drawPatch = (ctx, props) => { "worklet"; const { texture, blendMode, patch } = props; const defaultBlendMode = props.colors ? _types.BlendMode.DstOver : _types.BlendMode.SrcOver; const mode = blendMode ? _types.BlendMode[(0, _nodes.enumKey)(blendMode)] : defaultBlendMode; // Patch requires a path with the following constraints: // M tl // C c1 c2 br // C c1 c2 bl // C c1 c2 tl (the redundant point in the last command is removed) const points = [patch[0].pos, patch[0].c2, patch[1].c1, patch[1].pos, patch[1].c2, patch[2].c1, patch[2].pos, patch[2].c2, patch[3].c1, patch[3].pos, patch[3].c2, patch[0].c1]; const colors = props.colors ? props.colors.map(c => (0, _nodes.processColor)(ctx.Skia, c)) : undefined; ctx.canvas.drawPatch(points, colors, texture, mode, ctx.paint); }; exports.drawPatch = drawPatch; const drawPath = (ctx, props) => { "worklet"; const { start: trimStart, end: trimEnd, fillType, stroke, ...pathProps } = props; const start = (0, _processors.saturate)(trimStart); const end = (0, _processors.saturate)(trimEnd); const hasStartOffset = start !== 0; const hasEndOffset = end !== 1; const hasStrokeOptions = stroke !== undefined; const hasFillType = !!fillType; const willMutatePath = hasStartOffset || hasEndOffset || hasStrokeOptions || hasFillType; const pristinePath = (0, _nodes.processPath)(ctx.Skia, pathProps.path); const path = willMutatePath ? pristinePath.copy() : pristinePath; if (hasFillType) { path.setFillType(_types.FillType[(0, _nodes.enumKey)(fillType)]); } if (hasStrokeOptions) { path.stroke(stroke); } if (hasStartOffset || hasEndOffset) { path.trim(start, end, false); } ctx.canvas.drawPath(path, ctx.paint); }; exports.drawPath = drawPath; const drawRect = (ctx, props) => { "worklet"; const derived = (0, _nodes.processRect)(ctx.Skia, props); ctx.canvas.drawRect(derived, ctx.paint); }; exports.drawRect = drawRect; const drawRRect = (ctx, props) => { "worklet"; const derived = (0, _nodes.processRRect)(ctx.Skia, props); ctx.canvas.drawRRect(derived, ctx.paint); }; exports.drawRRect = drawRRect; const drawTextBlob = (ctx, props) => { "worklet"; const { blob, x, y } = props; ctx.canvas.drawTextBlob(blob, x, y, ctx.paint); }; exports.drawTextBlob = drawTextBlob; const drawGlyphs = (ctx, props) => { "worklet"; const derived = props.glyphs.reduce((acc, glyph) => { const { id, pos } = glyph; acc.glyphs.push(id); acc.positions.push(pos); return acc; }, { glyphs: [], positions: [] }); const { glyphs, positions } = derived; const { x, y, font } = props; if (font) { ctx.canvas.drawGlyphs(glyphs, positions, x, y, font, ctx.paint); } }; exports.drawGlyphs = drawGlyphs; const drawImageSVG = (ctx, props) => { "worklet"; const { canvas } = ctx; const { svg } = props; const { x, y, width, height } = props.rect ? props.rect : { x: props.x, y: props.y, width: props.width, height: props.height }; if (svg === null) { return; } canvas.save(); if (x && y) { canvas.translate(x, y); } canvas.drawSvg(svg, width, height); canvas.restore(); }; exports.drawImageSVG = drawImageSVG; const drawParagraph = (ctx, props) => { "worklet"; const { paragraph, x, y, width } = props; if (paragraph) { paragraph.layout(width); paragraph.paint(ctx.canvas, x, y); } }; exports.drawParagraph = drawParagraph; const drawPicture = (ctx, props) => { "worklet"; const { picture } = props; ctx.canvas.drawPicture(picture); }; exports.drawPicture = drawPicture; const drawAtlas = (ctx, props) => { "worklet"; const { image, sprites, transforms, colors, blendMode, sampling } = props; const blend = blendMode ? _types.BlendMode[(0, _nodes.enumKey)(blendMode)] : undefined; if (image) { ctx.canvas.drawAtlas(image, sprites, transforms, ctx.paint, blend, colors, sampling); } }; exports.drawAtlas = drawAtlas; const drawCircle = (ctx, props) => { "worklet"; const { c } = (0, _nodes.processCircle)(props); const { r } = props; ctx.canvas.drawCircle(c.x, c.y, r, ctx.paint); }; exports.drawCircle = drawCircle; const drawSkottie = (ctx, props) => { "worklet"; const { animation, frame } = props; if (animation) { props.animation.seekFrame(frame); props.animation.render(ctx.canvas); } }; exports.drawSkottie = drawSkottie; //# sourceMappingURL=Drawing.js.map