Konva.Shape: как работать с разными стилями штрихов в scenefunc - PullRequest
0 голосов
/ 14 апреля 2020

Моя цель - получить Shape в Konva с эллиптическим вырезом (в примере я только что использовал прямоугольник, но он может быть несколько более неправильной формы; поэтому я использую Konva.Shape и его sceneFun c ). В данном реальном сценарии у меня есть координаты многоугольника в массиве, и последняя запись - это вырез (который всегда является эллипсом). Результат сэмпла - HTML выглядит следующим образом JSFiddle

Изображение: Результат Konva vs. Canvas (или выполните фрагмент кода на полной странице , чтобы увидеть результат)

Как вы видите, Konva.Shape имеет линии внутри выреза. В нативном холсте я могу избавиться от них с помощью strikeStyle = transparent. В Scenfun Konva.Shape c это не применяется. Есть ли способ избавиться от линий внутри выреза? Здесь HTML / JavaScript:

<html>
  <head>
    <script src="https://unpkg.com/konva@4.2.2/konva.min.js"></script>
    <meta charset="utf-8" />
    <title>Radius-Line in ellipse</title>
    <style>
      body {
        margin: 0;
        padding: 0;
        overflow: hidden;
        background-color: #f0f0f0;
      }
    </style>
  </head>
  <body>
    <div id="KonvaContainer"></div>
	<canvas id="CanvasContainer" height="250" width="250"></canvas>
    <script>
      var width = window.innerWidth;
      var height = window.innerHeight;
		//Konva-way:
      var stage = new Konva.Stage({
        container: 'KonvaContainer',
        width: 250,
        height: 250
      });
	var layer = new Konva.Layer();
      stage.add(layer);
	var backgroundgroup = new Konva.Group();
	layer.add(backgroundgroup);
	var foregroundgroup = new Konva.Group();
	layer.add(foregroundgroup);
	
	var rect = new Konva.Rect({
        y: 0,
        width: width ,
        height: height / 2,
        fill: 'yellow',
        stroke: 'black',
        strokeWidth: 1
    });
	backgroundgroup.add(rect);
	
	var text = new Konva.Text(
	{
		x:10,
		y:20,
		text: 'Konva'
	});
	backgroundgroup.add(text);
	
	var Coords = [{x:50, y: 50, type:'start'} , {x:250, y: 50, type:'line'} , {x:250, y: 250, type:'line'} , {x:50 , y: 250, type:'line'} , {x:130, y:150, type:'cutout', radiusX: 30, radiusY: 20, rotation: 0}];
	//myText = new Konva.
	myPanel = new Konva.Shape({
        sceneFunc: function (context, shape) {
        var closeNeeded = true;
        //var context = c.context;
        context.beginPath();
        for (cindex = 0; cindex < Coords.length; cindex++) {
            switch (Coords[cindex].type) {
                case 'start':
                    context.moveTo(Coords[cindex].x , Coords[cindex].y);
                    break;
                case 'line':
                    context.lineTo(Coords[cindex].x, Coords[cindex].y);
                    break;
                case 'cutout':
                    context.closePath();
                    context.lineWidth = 0;
					context.strokeStyle = 'transparent';
                    //context.beginPath();
                    context.moveTo(Coords[cindex].x, Coords[cindex].y );
					context.stroke();
                    context.ellipse(Coords[cindex].x , Coords[cindex].y , Coords[cindex].radiusX , Coords[cindex].radiusY, Coords[cindex].rotation, 0, 2 * Math.PI, true);//true is needed for making the cutout!!
					context.arc(Coords[cindex].x + 70 , Coords[cindex].y, 30 , 0 , 2 * Math.PI, true);
                    context.stroke();
                    //closeNeeded = true;
                    break;
                default:
                    console.log('default');
                    context.lineTo(Coords[cindex].x , Coords[cindex].y);
                    break;
            }
        }
        context.closePath();
        context.fillStrokeShape(shape);
    },
	fill: 'red',
	stroke: 'black',
	strokeWidth: 1,
	name: 'MyPanel',
	id: 'P1',
	opacity: 1,
	listening: true,
	visible: true
	});
	foregroundgroup.add(myPanel);
	layer.draw();
	
	//Canvas-native:
	const canvas = document.getElementById('CanvasContainer');
	//canvas.width = width/2;
	//canvas.height = height;
	const ctx = canvas.getContext('2d');
	ctx.fillStyle='yellow';
	ctx.strokeStyle = 'black';
	ctx.lineWidth= 1;
	ctx.beginPath();
	ctx.rect(0 , 0 , width/2 , height);
	ctx.closePath();
	ctx.stroke();
	ctx.fill();
	
	ctx.strokeText('Canvas native' , 10 , 20);
	
	ctx.fillStyle = 'red';
	ctx.lineWidth = 1;
	ctx.beginPath();
	for (cindex = 0; cindex < Coords.length; cindex++) {
	switch (Coords[cindex].type) {
                case 'start':
                    ctx.moveTo(Coords[cindex].x , Coords[cindex].y);
                    break;
                case 'line':
                    ctx.lineTo(Coords[cindex].x, Coords[cindex].y);
                    break;
                case 'cutout':
                    ctx.closePath();
					ctx.lineWidth= 0;
					ctx.strokeStyle = 'transparent';
                    //ctx.beginPath();
                    ctx.moveTo(Coords[cindex].x, Coords[cindex].y );
					ctx.stroke();
					//ctx.lineWidth= 0;
                    ctx.ellipse(Coords[cindex].x , Coords[cindex].y , Coords[cindex].radiusX , Coords[cindex].radiusY, Coords[cindex].rotation, 0, 2 * Math.PI , true);
					ctx.arc(Coords[cindex].x + 70 , Coords[cindex].y, 30 , 0 , 2 * Math.PI, true);
                    ctx.stroke();
                    //closeNeeded = true;
                    break;
                default:
                    console.log('default');
                    context.lineTo(Coords[cindex].x , Coords[cindex].y);
                    break;
            }
        }

	ctx.closePath();
	ctx.fill();
	ctx.stroke();
	</script>
</body>
</html>	
...