WebGL Texture image Flip - webgl

How to flip the image in webGL?
The original image is:
I do not have idea at this moment

Here's a few ideas:
Change the UV coordinates on your triangle
Flip the UV coordinates in your shader
Change pixel unpacking in webgl
Apply the desired image operations with a 2D canvas and upload that

My example which shows how to load a texture:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Load Texture</title>
</head>
<body>
<canvas id="renderCanvas" width="250" height="250"></canvas>
<script id="vertexShader" type="x-shader/x-vertex">
attribute vec2 aPosition;
attribute vec2 aTexCoord;
uniform mat4 uMvpMatrix;
varying vec2 vTexCoord;
void main() {
gl_Position = uMvpMatrix * vec4(aPosition, 0.0, 1.0);
vTexCoord = aTexCoord;
}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
precision mediump float;
uniform sampler2D uSampler;
varying vec2 vTexCoord;
void main() {
gl_FragColor = texture2D(uSampler, vTexCoord);
}
</script>
<script type="importmap">
{
"imports": {
"gl-matrix": "https://cdn.skypack.dev/gl-matrix#3.4.3"
}
}
</script>
<script type="module">
import { mat4 } from "gl-matrix";
const gl = document.getElementById("renderCanvas")
.getContext("webgl", { alpha: false, premultipliedAlpha: false });
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
function loadTexture(url) {
return new Promise(resolve => {
const image = new Image();
image.onload = () => {
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
resolve(texture);
};
image.crossOrigin = "anonymous";
image.src = url;
});
}
async function main() {
const vertShaderSrc = document.getElementById("vertexShader").firstChild.textContent;
const vShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vShader, vertShaderSrc);
gl.compileShader(vShader);
const fragShaderSrc = document.getElementById("fragmentShader").firstChild.textContent;
const fShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fShader, fragShaderSrc);
gl.compileShader(fShader);
const program = gl.createProgram();
gl.attachShader(program, vShader);
gl.attachShader(program, fShader);
gl.linkProgram(program);
gl.useProgram(program);
const vertPositions = [
-0.5, -0.5,
0.5, -0.5,
-0.5, 0.5,
0.5, 0.5
];
const vertPosBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertPosBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertPositions), gl.STATIC_DRAW);
const aPositionLocation = gl.getAttribLocation(program, "aPosition");
gl.vertexAttribPointer(aPositionLocation, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(aPositionLocation);
const texCoords = [
0, 0,
1, 0,
0, 1,
1,1
];
const texCoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(texCoords), gl.STATIC_DRAW);
const aTexCoordLocation = gl.getAttribLocation(program, "aTexCoord");
gl.vertexAttribPointer(aTexCoordLocation, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(aTexCoordLocation);
const texture = await loadTexture("https://dl.dropboxusercontent.com/s/nxvziah1a7n9txd/256px-WebGL_Logo.svg.png");
const projMatrix = mat4.create();
mat4.ortho(projMatrix, -50, 50, -50, 50, 50, -50);
const viewMatrix = mat4.create();
mat4.lookAt(viewMatrix, [0, 0, 50], [0, 0, 0], [0, 1, 0]);
const projViewMatrix = mat4.create();
mat4.mul(projViewMatrix, projMatrix, viewMatrix);
const modelMatrix = mat4.create();
mat4.scale(modelMatrix, modelMatrix, [100, 50, 1]);
const mvpMatrix = mat4.create();
mat4.mul(mvpMatrix, projViewMatrix, modelMatrix);
const uMvpMatrixLocation = gl.getUniformLocation(program, "uMvpMatrix");
gl.clearColor(0.2, 0.2, 0.2, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.uniformMatrix4fv(uMvpMatrixLocation, false, mvpMatrix);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
}
main();
</script>
</body>
</html>

Related

How to make shape only show in react and partially hide on stage

I created a responsive rect as an artboard in the stage, and when I add shapes and move them, I want the shapes to only show on the rect, just like opening a window on the stage, only show the shapes inside the window
You should use clipping for that. Tutorial: https://konvajs.org/docs/clipping/Clipping_Regions.html
import React from "react";
import { createRoot } from "react-dom/client";
import { Stage, Layer, Star } from "react-konva";
function generateShapes() {
return [...Array(50)].map((_, i) => ({
id: i.toString(),
x: Math.random() * window.innerWidth,
y: Math.random() * window.innerHeight,
rotation: Math.random() * 180,
isDragging: false
}));
}
const INITIAL_STATE = generateShapes();
const STAR_PROPS = {
numPoints: 5,
innerRadius: 20,
outerRadius: 40,
fill: "#89b717",
opacity: 0.8,
shadowColorL: "black",
shadowBlur: 10,
shadowOpacity: 0.6,
shadowOffsetX: 5,
shadowOffsetY: 5,
scaleX: 1,
scaleY: 1,
draggable: true
};
const App = () => {
const [stars] = React.useState(INITIAL_STATE);
return (
<Stage width={window.innerWidth} height={window.innerHeight}>
<Layer
clipX={50}
clipY={50}
clipWidth={window.innerWidth - 100}
clipHeight={window.innerWidth - 100}
>
{stars.map((star) => (
<Star
{...STAR_PROPS}
key={star.id}
id={star.id}
x={star.x}
y={star.y}
rotation={star.rotation}
/>
))}
</Layer>
</Stage>
);
};
const container = document.getElementById("root");
const root = createRoot(container);
root.render(<App />);
https://codesandbox.io/s/react-konva-clipping-sg2fpd

ThreeJS / GLTFLoader responded with 404 about my gltf object

I started an ASPNET MVC project and I tried to load a gltf object
GLTFLoader.js -> https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/GLTFLoader.js
But my object isn't found... chrome console :
Project files:
I added something in web config:
<script src="~/Scripts/three.js"></script>
<script src="~/Scripts/OrbitControls.js"></script>
<script src="~/Scripts/GLTFLoader.js"></script>
<script>
var app = new Vue({
el: '#app',
data: {
test: 'xd'
}
});
</script>
<script>
var scene, renderer, camera;
var cube;
var controls;
function initialize() {
scene = new THREE.Scene();
scene.background = new THREE.Color(0xdddddd);
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000);
camera.lookAt(new THREE.Vector3(0, 0, 0));
camera.rotation.y = 45 / 180 * Math.PI;
camera.position.set(800, 100, 1000);
ambientLight = new THREE.AmbientLight(0x404040, 100);
scene.add(ambientLight)
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
$('#object').append(renderer.domElement);
let loader = new THREE.GLTFLoader();
loader.load('Cars/tutorial/scene.gltf', function (gltf) {
car = gltf.scene.children[0];
car.scale.set(0.5, 0.5, 0.5)
scene.add(gltf.scene);
renderer.render(scene, camera);
})
}
initialize();
</script>
Thanks!

html2canvas and jspdf genereted blank pdf

Hi i created invoice page and added to them jsPDF and html2canvas, but my solution generated blank pdf. How can I repair this? where is a bug ?
In my project used jspdf and html2canvas, can you help me with this?
Script:
$(document).ready(function() {
function generatePDF() {
window.scrollTo(0, 0);
var pdf = new jsPDF('p', 'pt', [1380, 2030]);
html2canvas($(".page-section")[0], {
onrendered: function(canvas) {
document.body.appendChild(canvas);
var ctx = canvas.getContext('2d');
var imgData = canvas.toDataURL("image/png", 1.0);
var width = canvas.width;
var height = canvas.clientHeight;
pdf.addImage(imgData, 'PNG', 20, 20, (width - 10), (height));
}
});
setTimeout(function() {
pdf.save('sample.pdf');
var blob = pdf.output("blob");
var blobURL = URL.createObjectURL(blob);
var iframe = document.getElementById('sample-pdf');
iframe.src = blobURL;
var downloadLink = document.getElementById('pdf-download-link');
downloadLink.href = blobURL;
}, 0);
};
generatePDF();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script type="text/javascript" src="https://instamarketing.pl/cennik/js/jspdf.min.js"></script>
<script type="text/javascript" src="https://instamarketing.pl/cennik/js/html2canvas.js"></script>
<div class="page-section">
test
</div>

Simple WebGL program, draw points when mouse down, fail to work. help please

Here is the source code, pretty simple, but do not work.
// this is the html file
<html>
<head>
<title>Test</title>
<style>
body { background: pink }
canvas { background: orange }
</style>
<script src="utils.js"></script>
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec4 aVertexPosition;
void main() {
gl_PointSize = 10.0;
gl_Position = aVertexPosition;
}
</script>
<script id="shader-fs" type="x-shader/x-fragment">
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
</script>
<script>
var canvas, gl, shaderProgram;
window.onload = function() {
initCanvasAndGL("canvas", canvas, gl);console.log(gl);
initProgram(gl, shaderProgram);
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
var aVertexPosition = gl.getAttribLocation(shaderProgram, "aVertexPosition");
canvas.onmousedown = function(e) {
onCanvasMouseDown(e, aVertexPosition, canvas, gl);
}
}
function onCanvasMouseDown(e, aVertexPosition, canvas, gl) {
var x = e.pageX;
var y = e.pageY;
x = (x - canvas.width / 2) / (canvas.width / 2);
y = (canvas.height / 2 - y) / (canvas.height / 2);
gl.vertexAttrib2f(aVertexPosition, x, y);
gl.drawArray(gl.POINTS, 0, 1);
}
</script>
</head>
<body>
<canvas id="canvas" width="400" height="400">
Canvas Not Supported! :(
</canvas>
</body>
</html>
and this is the utils.js file
function initCanvasAndGL(canvasID, canvas, gl) {
canvas = document.getElementById(canvasID);
var names = [
"webgl", "experimental-webgl",
"webkit-3d", "moz-webgl"
];
for(var i = 0; i < names.length; ++i) {
try {
gl = canvas.getContext(names[i]);console.log("i: " + i + "gl: " + gl);
} catch(e) {}
if(gl) {
break;
}
}
if(!gl) {
alert("WebGL is not available! :(");
}
}
function getShader(gl, id) {
var shaderScript = document.getElementById(id);
if(!shaderScript) {
return null;
}
var str = "";
var k = shaderScript.firstChild;
while(k) {
if(k.nodeType == 3) {
str += k.textContent;
}
k = k.nextSibling;
}
var shader;
if(shaderScript.type == "x-shader/x-vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
} else if(shaderScript.type == "x-shader/x-fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else {
return null;
}
gl.shaderSource(shader, str);
gl.complieShader(shader);
if(!gl.getShaderParameter(shader, gl.COMPLIE_STATUS)) {
alert(gl.getShaderInfoLog(shader));
return null;
}
return shader;
}
function initProgram(gl, shaderProgram) {
var vertexShader = getShader(gl, "shader-vs");
var fragmentShader = getShader(gl, "shader-fs");
shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
if(!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert("Could not initialise shaders! :(");
}
gl.useProgram(shaderProgram);
}
the console traces Uncaught TypeError: Cannot read property 'VERTEX_SHADER' of undefined.So I add two console.log() in window.onload() function and initCanvasAndGL() function.And the result is:
i: 0gl: null utils.js:10
i: 1gl: [object WebGLRenderingContext] utils.js:10
undefined
I really don't know why! who can help me? thanks.
The code had multiple minor issues.
Please find a fixed version here:
webgl_mousedown.html
utils.js

Limit canvas pinch zoom out on iPad Safari

I have this fiddle
JS Fiddle
I want to limit the pinch zoom out of a canvas on iPad Safari. When i pinch out the canvas shrinks and becomes small. Is there any way i can limit the zoom out level on this particular device? I am using KineticJS.
Here's my code below of the fiddle
div id="container"></div>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.5.5.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
init();
});
function init() {
var lastDist = 0;
var startScale = 1;
function getDistance(p1, p2) {
return Math.sqrt(Math.pow((p2.x - p1.x), 2) + Math.pow((p2.y - p1.y), 2));
}
var image = new Image();
image.onload = function() {
kimage = new Kinetic.Image({
image: image,
x : 0,
y : 0
});
var stage = new Kinetic.Stage({
container: 'container',
width: 500,
height: 500
});
var layer = new Kinetic.Layer();
var group = new Kinetic.Group({
draggable: true,
dragBoundFunc: function(pos) {
var newX = 0;
if (pos.x < 0) {
newX = pos.x < stage.getWidth() - kimage.getWidth()
? stage.getWidth() - kimage.getWidth() : pos.x;
}
var newY = 0;
if (pos.y < 0) {
newY = pos.y < stage.getHeight() - kimage.getHeight()
? stage.getHeight() - kimage.getHeight() : pos.y;
}
return {
x: newX,
y: newY
};
}
});
stage.getContent().addEventListener('click', function(evt) {
var touch1 = evt.touches[0];
var touch2 = evt.touches[1];
if(touch1 && touch2) {
var dist = getDistance({
x: touch1.clientX,
y: touch1.clientY
}, {
x: touch2.clientX,
y: touch2.clientY
});
if(!lastDist) {
lastDist = dist;
}
var scale = stage.getScale().x * dist / lastDist;
stage.setScale(scale);
stage.draw();
lastDist = dist;
}
}, false);
stage.getContent().addEventListener('touchend', function() {
lastDist = 0;
}, false);
group.add(kimage);
layer.add(group);
stage.add(layer);
layer.draw();
}
image.src = 'http://www.ourclientwebsites.com/html5/images/1.jpg';
}
</script>
Add a viewport meta tag:<meta name="viewport" content="width=device-width, user-scalable=no">. This will prevent the page from zooming, while still allowing your app to grab the Javascript event.

Resources