We have a situation where we have a number of (animated) .gif files. We can change the underlying .gif, but that resets the new one to start. What we would want is to have the playback continue with the new .gif (all our .gif's have the same layout/number of frames/etc.)
The first in this process would probably be something like:
Is it possible to get currently shown frame of a .gif ?
Not gif. But you can do for html. the basic code be found on.
https://odetocode.com/blogs/scott/archive/2013/01/04/capturing-html-5-video-to-an-image.aspx
converting GIF to mp4
https://www.smashingmagazine.com/2018/11/gif-to-video/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<video id="video" controls="controls">
<source src="element_stream.mp4" crossorigin="anonymous" />
</video>
<button id="capture">Capture</button>
<div id="output" crossorigin></div>
</div>
<script>
(function () {
"use strict";
var video, output;
var scale = 0.25;
output = document.querySelector("#output");
video = document.querySelector("#video");
document.querySelector("#capture").addEventListener('click', function () {
var canvas = document.createElement("canvas");
canvas.width = video.videoWidth * scale;
canvas.height = video.videoHeight * scale;
canvas.getContext('2d')
.drawImage(video, 0, 0, canvas.width, canvas.height);
var img = document.createElement("img");
img.src = canvas.toDataURL();
output.prepend(img);
});
}());
</script>
</body>
</html>
Related
It's my first question here. I just learn canvas in JavaScript and I found a problem while adding the speed. I want to stop the rectangle if its x exceeds the width of the canvas. I am just a beginner, so please help me.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#canvas{
border: 1px solid black;
}
</style>
</head>
<body>
<canvas id="canvas" width="400" height="400">Your browser doesn't support canvas</canvas>
<script>
var canvas = document.getElementById('canvas');
var cnxt = canvas.getContext('2d');
x = 0;
y = 50;
var t;
function draw(){
cnxt.clearRect(0,0,400,400);
cnxt.beginPath();
cnxt.rect(x,y,25,25);
cnxt.fillStyle = 'red';
cnxt.fill();
var timePassed = (performance.now()-t)/1000;
var fps = Math.round(1/ timePassed);
let speed = 100;
cnxt.font = '25px Arial';
cnxt.fillStyle = 'black';
cnxt.fillText("FPS: " + fps, 20,30);
t = performance.now();
x += (speed * timePassed);
if (x >= 400 - 25){
speed = 0;
}
window.requestAnimationFrame(draw);
}
draw();
</script>
</body>
</html>
I'm currently trying to get a similar touch/stylus behaviour to Squid (the notetaking app). I have used the PointerEvent API and it all works, except for one annoying issue:
After I put down the stylus or the finger, it draws a stroke for the next ~0.3 seconds, but after that, no more pointermove events are fired as long as the pointer is down.
here's my code:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Draw</title>
<link rel="stylesheet" href="index.css">
</head>
<body>
<canvas id="canvas" width="500px" height="500px" style=" position: absolute;border: 2px solid red;"></canvas>
<script src="index.js"></script>
</body>
</html>
index.js
var canvas = document.querySelector("#canvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "white"
var pos = {}
canvas.addEventListener("pointerdown", function (e) {
pos.x = e.pageX;
pos.y = e.pageY;
});
canvas.addEventListener("pointermove", function (e) {
console.log(e.pressure)
switch (e.pointerType) {
case "pen":
ctx.beginPath();
ctx.moveTo(pos.x, pos.y);
ctx.lineTo(e.pageX, e.pageY);
ctx.stroke();
pos.x = e.pageX;
pos.y = e.pageY;
break;
case "touch":
ctx.fillRect(e.pageX - 10, e.pageY - 10, 20, 20);
break;
}
});
index.css is just a css reset
I'm really confused over this and can't seem to find anyone else who had this problem. Any help would be appreciated!
Just add touch-action: none; to your canvas's style attribute.
After ~0.3 seconds starts touch events as page scrolling.
Sublime text preview in browser doesn't show the javascript that is in html. when I want to check and see it in chrome browser, it shows the html and css but doesn't do anything with js file. The code is very simple and it works (example in JSBin). (Html and js file in the same directory.)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Practice the Basics - Two overlapping squares sample solution</title>
</head>
<body>
<canvas id="myCanvas" width="450" height="300" style="border: 1px solid black"></canvas>
<script src="rajzos.js"></script>
</body>
</html>
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var canvasWidth = canvas.width;
var canvasHeight = canvas.height;
var size = 100;
var positionX = canvasWidth / 2 - size * 0.75;
var positionY = canvasHeight / 2 - size * 0.75;
context.fillStyle = 'rgba(255,0,0,.5)';
context.fillRect(positionX, positionY, size, size);
positionX += size / 2;
positionY += size / 2;
I don't know what should be the expected output but the script tag should be in the head of your html.
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var canvasWidth = canvas.width;
var canvasHeight = canvas.height;
var size = 100;
var positionX = canvasWidth / 2 - size * 0.75;
var positionY = canvasHeight / 2 - size * 0.75;
context.fillStyle = 'rgba(255,0,0,.5)';
context.fillRect(positionX, positionY, size, size);
positionX += size / 2;
positionY += size / 2;
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Practice the Basics - Two overlapping squares sample solution</title>
<script src="rajzos.js"></script>
</head>
<body>
<canvas id="myCanvas" width="450" height="300" style="border: 1px solid black"></canvas>
</body>
</html>
this is my code, i use two canvas to drawimage to avoid flickering, but i cant get the full image when use this way, anyone can help please?
if i only use one canvas the image display fine, it seems the secondarycanvas that created by Javascript got some issue to display the image, but i can't find what's wrong. any help is appreciated!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Decorate</title>
</head>
<body>
<div class="content-box">
<canvas id="canvas" width="360" height="740" style="border:1px solid #d3d3d3"></canvas>
</div>
<script>
var c=document.getElementById("canvas");
var ctx = c.getContext("2d");
var secondaryCanvas=document.createElement("canvas");
var secondaryCtx=secondaryCanvas.getContext("2d");
secondaryCanvas.weight=c.weight;
secondaryCanvas.height=c.height;
var bgimg=new Image();
bgimg.src=imageEncoder[24].background;
bgimg.onload=function() {
secondaryCtx.drawImage(bgimg, 0, 0);
ctx.drawImage(secondaryCanvas,0,0);
}
</script>
</body>
</html>
I change secondaryCanvas.weight=c.weight; to secondaryCanvas.width=c.width; and your code seems to work now.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Decorate</title>
</head>
<body>
<div class="content-box">
<canvas id="canvas" width="360" height="740" style="border:1px solid #d3d3d3"></canvas>
</div>
<script>
var c=document.getElementById("canvas");
var ctx = c.getContext("2d");
var secondaryCanvas=document.createElement("canvas");
var secondaryCtx=secondaryCanvas.getContext("2d");
secondaryCanvas.width=c.width;
secondaryCanvas.height=c.height;
var bgimg=new Image();
bgimg.src= "https://picsum.photos/360/740"
bgimg.onload=function() {
secondaryCtx.drawImage(bgimg, 0, 0);
ctx.drawImage(secondaryCanvas,0,0);
}
</script>
</body>
</html>
I am trying to get the following single HTML5 page with embedded Javascript to draw a fraction of a circle dependent upon the numerator and dominator chosen.
The code was suggested by #Vanojx1 but, my post was closed because it was not 'specific' enough, and, I just want some help understanding what I am doing wrong please:
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="author" content="">
<meta name="description" content="Fraction Learning app for Children">
<script type="text/javascript">
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var pi = Math.PI;
document.getElementById("draw").addEventListener("click", function () {
var num = document.getElementById("num").value;
var den = document.getElementById("den").value;
var rad = 2 / den * num * pi;
var cx = 250;
var cy = 250;
ctx.clearRect(0, 0, 500, 500);
ctx.beginPath();
ctx.moveTo(cx, cy);
ctx.arc(cx, cy, 220, 1.5 * pi, 1.5 * pi + rad);
ctx.lineTo(cx, cy);
ctx.fillStyle = "#FF0000";
ctx.fill();
ctx.closePath();
ctx.stroke();
});
</script>
<title>Fractions Fun</title>
</head>
<body>
<canvas id="myCanvas" width="500" height="500" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<br>
<input type="number" id="num" /> /
<input type="number" id="den" />
<br>
<button id="draw">
DRAW
</button>
</body>
</html>
HTML is rendered in the order that it appears in the DOM (that includes script blocks). Therefore the script block will be run before draw is rendered. As draw does not exist the script fails to add the click handler.
Putting the code in a function and call it using the body's onload event would allow the click handler to be added. See below -
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="author" content="">
<meta name="description" content="Fraction Learning app for Children">
<script type="text/javascript">
function init() {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var pi = Math.PI;
document.getElementById("draw").addEventListener("click", function() {
var num = document.getElementById("num").value;
var den = document.getElementById("den").value;
var rad = 2 / den * num * pi;
var cx = 250;
var cy = 250;
ctx.clearRect(0, 0, 500, 500);
ctx.beginPath();
ctx.moveTo(cx, cy);
ctx.arc(cx, cy, 220, 1.5 * pi, 1.5 * pi + rad);
ctx.lineTo(cx, cy);
ctx.fillStyle = "#FF0000";
ctx.fill();
ctx.closePath();
ctx.stroke();
});
}
</script>
<title>Fractions Fun</title>
</head>
<body onload="init()">
<canvas id="myCanvas" width="500" height="500" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<br>
<input type="number" id="num" />/
<input type="number" id="den" />
<br>
<button id="draw">
DRAW
</button>
</body>
Another method I've seen used is to put the script tag at the end of the document (although I'm not sure if it's considered best practice and I don't use it myself) -
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="author" content="">
<meta name="description" content="Fraction Learning app for Children">
<title>Fractions Fun</title>
</head>
<body>
<canvas id="myCanvas" width="500" height="500" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<br>
<input type="number" id="num" />/
<input type="number" id="den" />
<br>
<button id="draw">
DRAW
</button>
<script type="text/javascript">
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var pi = Math.PI;
document.getElementById("draw").addEventListener("click", function() {
var num = document.getElementById("num").value;
var den = document.getElementById("den").value;
var rad = 2 / den * num * pi;
var cx = 250;
var cy = 250;
ctx.clearRect(0, 0, 500, 500);
ctx.beginPath();
ctx.moveTo(cx, cy);
ctx.arc(cx, cy, 220, 1.5 * pi, 1.5 * pi + rad);
ctx.lineTo(cx, cy);
ctx.fillStyle = "#FF0000";
ctx.fill();
ctx.closePath();
ctx.stroke();
});
</script>
</body>