Are there any ways to place shape in anchors of Transformer in Konvajs? - konvajs

Is it possible to fill anchors in Konva.Transformer with shape? I mean, would I have to add another layer in order to make custom anchors or can I do something right in Transformer component?
return (
<>
<Rect
x={100}
y={100}
fill="red"
width={200}
height={100}
ref={rectRef}
/>
<Transformer
ref={transformerRef}
rotateEnabled
rotateAnchorOffset={48}
keepRatio={false}
anchorFill={'yellow'}
borderDash={[5,10]}
padding={10}
/>

At the current moment konva#7.2.2 doesn't have support for such functions.
As a workaround you can:
create an external canvas with the size of custom shape
Manually draw into that canvas
Manually style required anchors with that canvas to use it as patternImage.
const trRef = React.useRef();
const anchorShapeCanvas = React.useMemo(() => {
const canvas = document.createElement("canvas");
canvas.width = 12;
canvas.height = 12;
const ctx = canvas.getContext("2d");
ctx.strokeStyle = "black";
ctx.beginPath();
ctx.lineTo(0, 0);
ctx.lineTo(12, 0);
ctx.lineTo(12, 4);
ctx.lineTo(4, 4);
ctx.lineTo(4, 12);
ctx.lineTo(0, 12);
ctx.closePath();
ctx.stroke();
ctx.stroke = "2px";
return canvas;
}, []);
React.useEffect(() => {
if (isSelected) {
// we need to attach transformer manually
trRef.current.nodes([shapeRef.current]);
trRef.current.find(".top-left").fillPriority("pattern");
trRef.current.find(".top-left").fillPatternImage(anchorShapeCanvas);
trRef.current.find(".top-left").strokeEnabled(false);
trRef.current.getLayer().batchDraw();
}
}, [isSelected]);
https://codesandbox.io/s/react-konva-fill-pattern-for-transformer-anchor-45zc5?file=/src/index.js:236-1151

Related

How i can extract svg element with text pdf js

I need extarct svg element with text from pdf. But if i did like this:
PDF:
Pdf link https://dropfiles.org/2dTlpxTN
const PDF_PATH = "https://dropfiles.org/2dTlpxTN";
const PAGE_NUMBER = 1;
const PAGE_SCALE = 1.5;
const SVG_NS = "http://www.w3.org/2000/svg";
pdfjsLib.GlobalWorkerOptions.workerSrc =
"../../node_modules/pdfjs-dist/build/pdf.worker.js";
function buildSVG(viewport, textContent) {
// Building SVG with size of the viewport (for simplicity)
const svg = document.createElementNS(SVG_NS, "svg:svg");
svg.setAttribute("width", viewport.width + "px");
svg.setAttribute("height", viewport.height + "px");
// items are transformed to have 1px font size
svg.setAttribute("font-size", 1);
// processing all items
textContent.items.forEach(function (textItem) {
// we have to take in account viewport transform, which includes scale,
// rotation and Y-axis flip, and not forgetting to flip text.
const tx = pdfjsLib.Util.transform(
pdfjsLib.Util.transform(viewport.transform, textItem.transform),
[1, 0, 0, -1, 0, 0]
);
const style = textContent.styles[textItem.fontName];
// adding text element
const text = document.createElementNS(SVG_NS, "svg:text");
text.setAttribute("transform", "matrix(" + tx.join(" ") + ")");
text.setAttribute("font-family", style.fontFamily);
text.textContent = textItem.str;
svg.append(text);
});
return svg;
}
async function pageLoaded() {
// Loading document and page text content
const loadingTask = pdfjsLib.getDocument({ url: PDF_PATH });
const pdfDocument = await loadingTask.promise;
const page = await pdfDocument.getPage(PAGE_NUMBER);
const viewport = page.getViewport({ scale: PAGE_SCALE });
const textContent = await page.getTextContent();
// building SVG and adding that to the DOM
const svg = buildSVG(viewport, textContent);
document.getElementById("pageContainer").append(svg);
// Release page resources.
page.cleanup();
}
document.addEventListener("DOMContentLoaded", function () {
if (typeof pdfjsLib === "undefined") {
// eslint-disable-next-line no-alert
alert("Please build the pdfjs-dist library using\n `gulp dist-install`");
return;
}
pageLoaded();
});
I extracted text with out Font and i extract all text. I need extract text as image.
If i do this:
pdfDoc_.getPage(pageNumber).then(function (page) {
var canvasEl = document.createElement('canvas');
var context = canvasEl.getContext('2d');
var viewport = page.getViewport({scale: imagesSetting_reader.scaleText});
canvasEl.height = viewport.height;
canvasEl.width = viewport.width;
var back;
var renderContext = {
canvasContext: context,
background:back,
viewport: viewport
};
page.render(renderContext).promise.then(function () {
resolve(canvasEl.toDataURL("image/png"));
})
});
It extracted text and background image.
if i do like this :
page.getOperatorList().then(opList => {
var svgGfx = new pdfjsLib.SVGGraphics(page.commonObjs, page.objs);
return svgGfx.getSVG(opList, viewport);
}).then(svg => {
console.log(svg)
return svg;
});
And extracted text from svg, i got error :
error on line 1 at column 101: Namespace prefix svg on svg is not defined
How i can extract only svg text with font and convert it to image ?
Like this:

Image canvas toDataURL function is not wokring on ios

I have a drawImage function in my application which loads the image from a blob and then from that image object calls the toDataURL function for the canvas to draw image. The problem is that this code works on android and browser but not working on iphone or ipad.
I have tried passing the image type to the toDataURL function and tried setting the default width and height of the canvas to prevent width getting 0 for the canvas but nothing seems to work on iphone or ipad. It only shows a blank screen inplace of the image.
the code works fine on mac/safari as well but not in iphone/ipad on any browser.
here is my drawImage function
_drawImage(img) {
// console.log("drawimage");
this.setState({ isGenerating: true });
if (img) {
fetch(img)
.then((r) => r.blob())
.then((blob) => {
loadImage(
blob,
(img) => {
if (img.type === "error") {
this.setState({ error: true });
// console.log(img, "Error loading image ");
} else {
const image = new window.Image();
const height = this.props.height;
const width = this.props.width;
image.src = img.toDataURL('image/jpeg');
console.log(image.src, height, width)
image.onload = () => {
let offsetX,
offsetY,
renderableWidth = image.width,
renderableHeight = image.height;
var imageDimensionRatio = image.width / image.height;
var canvasDimensionRatio = width / height;
// console.log(
// "ratios of image and canvas =",
// imageDimensionRatio,
// canvasDimensionRatio
// );
if (imageDimensionRatio < canvasDimensionRatio) {
renderableHeight = height;
renderableWidth =
image.width * (renderableHeight / image.height);
offsetX = (width - renderableWidth) / 2;
offsetY = 0;
} else if (imageDimensionRatio > canvasDimensionRatio) {
renderableWidth = width;
renderableHeight =
image.height * (renderableWidth / image.width);
offsetX = 0;
offsetY = (height - renderableHeight) / 2;
} else {
renderableHeight = height;
renderableWidth = width;
offsetX = 0;
offsetY = 0;
}
console.log(renderableHeight, renderableWidth, image)
this.setState(
{
image: image,
renderableHeight,
renderableWidth,
imgHeight: image.height,
imgWidth: image.width,
offsetX,
offsetY,
height,
width,
},
() => {
this.setState({ isGenerating: false });
}
);
};
}
},
{
orientation: true,
canvas: true,
}
);
});
}
}
EDIT
I've solved the issue by passing maxWidth to loadImage params along with orientation and canvas, which limits the width to not to exceed in ios devices and thus onload function works properly.
basically I've added the below code.
maxWidth: 10000

three.js, dat.GUI slider controlled by code, morph targets do not move

I work on a human face that the mouth should move about external coordinates (OpenCV and dlibs). In a first step I try to control the dat.GUI by code, which already works. But now I have the problem that the morph targets do not move when I control by code. The sliders move, but the face doesn't. When I use the mouse, they work perfectly. I ask for help with this problem.
<script>
// Laden der 3DScene
var scene = new THREE.Scene();
// Laden der Kamear Perspektive
var camera = new THREE.PerspectiveCamera(15, window.innerWidth/window.innerHeight, 1, 10000);
camera.position.z = 17;
camera.position.y = 3;
// Laden des Renderers
var renderer = new THREE.WebGLRenderer({ alpha: false });
renderer.setClearColor( 0x000000 );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// Laden des Orbitcontrollers
var controls = new THREE.OrbitControls( camera, renderer.domElement );
// Laden der Lichter (Beleuchtung)
var ambientLight = new THREE.AmbientLight(0x111111);
scene.add(ambientLight);
var light = new THREE.PointLight( 0xFFFFDD );
light.position.set( -15, 10, 15 );
scene.add(light);
// Laden des Json Modells
var loader = new THREE.JSONLoader();
loader.load( "./three/models/JSON/test/mkh_shapes.json", function (geometry) {
var material = new THREE.MeshLambertMaterial({morphTargets: true});
var mesh = new THREE.Mesh(geometry, material);
mesh.scale.set(1.2,1.2,1.2); //Modellgrösse die angezeigt wird
mesh.position.x = 0; //Position (x = nach rechts+ links-)
mesh.position.y = -19; //Position (y = nach oben +, unten-)
mesh.position.z = 0; //Position (z = nach vorne +, hinten-)
scene.add(mesh);
//dat.Gui
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
var shape = {
mouth_open: 0.0, //Anfangsposition 0.0
};
var gui = new dat.GUI();
var folder = gui.addFolder( 'Morph Targets' );
folder.add( shape, 'mouth_open', 0, 1 ).step( 0.01 ).name('mouth_open').listen().onChange ( function( a ) { mesh.morphTargetInfluences[ 40 ] = a;} );
folder.open();
var updateGui = function() {
for (var i in folder.__controllers) {
folder.__controllers[i].updateDisplay();
}
}
var time = Date.now() * 0.003;
shape.mouth_open = 0.50 //* Math.sin( 0.5 * time ) + 0.3;
//scene.add(shape);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
});
function animate() {
render();
requestAnimationFrame( animate );
}
function render() {
renderer.clear();
renderer.render( scene, camera );
}
animate();
</script>
I have made my own version with extra features like :
Gui auto resize based on content div.
Improved slidecontroller as unique controller (slide or number insert);
Multi language automatic support
Auto check for conflicts in options, then ask for confirm or cancel.
Auto Show/hide other controllers when option selected deselected (example show color list only if "custom color is selected")
ecc.. ecc..
here is the Video
Now is more confortable and easy to use.

How to rerender PDF.js page with different scale?

I'm trying just to run the same procedure, but with different scale. But it gives me broken pictures. So what is the correct way to update scale?
function draw(num, scale) {
pdfDoc.getPage(num).then(function(page) {
var viewport = page.getViewport(scale);
var canvas = document.getElementById('the-canvas');
var context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
var renderContext = {
canvasContext: context,
viewport: viewport
};
page.render(renderContext);
}
}
draw(1, 1);
draw(1, 2);

Three.js iPad performance

before I totally give up on this idea I wanted to check with the three.js community to make sure that I'm not doing something wrong?
Essentially I have taken Mr doobs canvas geometry cube example http://mrdoob.github.io/three.js/examples/canvas_geometry_cube.html and applied an image to the cube faces. When testing on the iPad I have frame a frame speed of 1fps (as opposed to 60fps with the original example). The image also looks really broken up on rotation.
Are there any tricks on getting this to work well on the iPad? I'm aware that WebGL isn't supported but I thought the canvas renderer would perform better than it is?
Code below
Many thanks
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
var info = document.createElement( 'div' );
info.style.position = 'absolute';
info.style.top = '10px';
info.style.width = '100%';
info.style.textAlign = 'center';
info.innerHTML = 'Drag to spin the cube';
container.appendChild( info );
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.y = 150;
camera.position.z = 500;
scene = new THREE.Scene();
// Cube
var loader = new THREE.TextureLoader();
loader.load( 'test-texture.png', function ( texture ) {
var materials = [];
var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: 0.5 } );
material.transparent = true;
for ( var i = 0; i < 6; i ++ ) {
materials.push( material );
}
// then the cube definitions
cube = new THREE.Mesh( new THREE.CubeGeometry( 200, 200, 200,4,4,4), new THREE.MeshFaceMaterial(materials));
cube.position.y = 150;
scene.add( cube );
animate();
});
// Plane
var geometry = new THREE.PlaneGeometry( 200, 200 );
geometry.applyMatrix( new THREE.Matrix4().makeRotationX( - Math.PI / 2 ) );
var material = new THREE.MeshBasicMaterial( { color: 0xe0e0e0, overdraw: 0.5 } );
plane = new THREE.Mesh( geometry, material );
scene.add( plane );
renderer = new THREE.CanvasRenderer();
renderer.setClearColor( 0xf0f0f0 );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
container.appendChild( stats.domElement );
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
document.addEventListener( 'touchstart', onDocumentTouchStart, false );
document.addEventListener( 'touchmove', onDocumentTouchMove, false );
//
window.addEventListener( 'resize', onWindowResize, false );
}
I would suggest to wait for iOS8 which should bring WebGL support.

Resources