I have some script on JS, it change width and height of canvas element:
function RefreshSizes (canvas) {
var temp_width = 320;
var temp_height = 240;
document.getElementById(canvas).setAttribute('width', temp_width);
document.getElementById(canvas).setAttribute('height', temp_height);
}
this functions calling right after canvas initializing.
It works fine on Chrome.
But in FireFox 49 I see that:
What could it be?
UPD#1 Tested code of BukkitmanPlays MCPE
UPD#2
Full CSS for canvas:
element {
width: 320px;
height: 240px;
}
.canvas {
border: 3px solid #E0E0E0;
z-index: 0;
position: relative;
}
html {
font: 10px/10px arial;
}
some code on one browser isn't the same on another browser, so in this case, what I would do:
function RefreshSizes (canv) {
var temp_width = 320;
var temp_height = 240;
var canvas = canv;
canvas.width = temp_width;
canvas.height = temp_height;
}
I'm sure this will work
Related
I want to create a media control bar for a video player with the controls blurring the background. Currently I can get the glassy look but I can't get blurring to work.
I tried following this guide: https://medium.com/#AmJustSam/how-to-do-css-only-frosted-glass-effect-e2666bafab91 but it seems like it only works on static images.
Here's an example of what I want:
I also saw the webkit backdrop-filter which looks perfect but it's only stable on safari so I can't use that. Any advice for frosted glass on dynamic videos?
I was able to accomplish this by copying the bottom part of the video to a canvas every frame and blurring the canvas via CSS. It seems to work well in Chrome, but flashes sometimes in Firefox. Doing the blur programmatically in the canvas with something like Superfast Blur might be more performant, but that's an experiment for another day. Tomorrow, probably.
function initControls (player, blurRadius, controlHeight, videoWidth, videoHeight) {
// crop player to video size
let video = player.querySelector('video');
videoWidth = videoWidth || video.clientWidth;
videoHeight = videoHeight || video.clientHeight;
player.style.width = videoWidth + 'px';
player.style.height = videoHeight + 'px';
// crop control bar to video size
let controlBar = player.querySelector('.control-bar');
controlBar.style.width = videoWidth + 'px';
controlBar.style.height = controlHeight + 'px';
// canvas needs to be slightly taller than what gets displayed
// to blur cleanly
let canvas = player.querySelector('canvas');
canvas.width = videoWidth;
canvas.height = 2 * blurRadius + controlHeight;
canvas.style.filter = `blur(${blurRadius}px)`;
canvas.style.top = -2 * blurRadius + 'px';
// copy video to canvas
let ctx = canvas.getContext('2d');
let videoCropY = videoHeight - canvas.height;
function updateCanvas () {
ctx.drawImage(
video,
0, videoCropY, canvas.width, canvas.height,
0, 0, canvas.width, canvas.height
);
}
// update the canvas only when necessary
let hovering = false;
function renderLoop () {
updateCanvas();
if (hovering && !video.paused) {
window.requestAnimationFrame(renderLoop);
}
}
// no point in rendering to a canvas you can't see
player.addEventListener('mouseenter', () => {
hovering = true;
renderLoop();
});
player.addEventListener('mouseleave', () => { hovering = false; });
video.addEventListener('play', renderLoop);
}
document.addEventListener('DOMContentLoaded', event => {
// do the magic
initControls(document.querySelector('.player'), 4, 50, 320, 240);
// basic play button functionality
document.querySelector('.play-button').addEventListener('click', event => {
let v = event.target.closest('.player').querySelector('video');
if (v.ended) v.currentTime = 0;
if (v.paused) {
v.play();
} else {
v.pause();
}
});
});
/* styling required for blurred control background */
.player {
position: relative;
}
.player > video {
margin: 0;
display: block;
}
.control-bar > canvas {
margin: 0;
display: block;
left: 0;
position: absolute;
}
.control-bar {
margin: 0;
overflow: hidden;
position: absolute;
bottom: 0;
/* height of control bar is specified in javascript, sorry about that */
}
/* simple control-hiding mechanism; other methods also work */
/* javascript relies on mouseover and mouseout to decide whether to update canvas */
.player > .control-bar {
display: none;
}
.player:hover > .control-bar {
display: block;
}
/* styling actual controls; adjust to taste */
.play-button {
height: 30px;
line-height: 30px;
width: 100px;
color: white;
border: 1px solid white;
position: absolute;
top: 10px;
left: 50%;
margin-left: -50px;
text-align: center;
}
<div class="player">
<video src="https://archive.org/download/MedicalA1950/MedicalA1950_512kb.mp4"></video>
<div class="control-bar">
<canvas></canvas>
<div class="play-button">PLAY/PAUSE</div>
</div>
</div>
I'm trying to create a one-pager at the moment with a canvas where you can click to add/place images at random. I've gotten most of what I want to work, but being extremely new to jquery and canvas, I still can't figure out how to set a max-size for my images. As far as I've understood, it can be quite hard to make images on a canvas work perfectly when you haven't set the canvas size manually in css, but I have a resizing canvas, so I'm not really sure how I get around that.
I want the images that I place to have a max-height/max-width of 80% of the viewport. I tried setting a max size in css, but it didn't do anything.
Here's a jsfiddle
$(document).ready(function () {
var images = [];
$("#siteload").fadeIn(1500);
$('.put').each(function() {
images.push($(this).attr('src'));
});
(function() {
var
htmlCanvas = document.getElementById('c'),
context = htmlCanvas.getContext('2d');
initialize();
img = new Image();
count = 0;
htmlCanvas.onclick= function(evt) {
img.src = images[count];
var x = evt.offsetX - img.width/2,
y = evt.offsetY - img.height/2;
context.drawImage(img, x, y);
count++;
if (count == images.length) {
count = 0;
}
}
function initialize() {
window.addEventListener('resize', resizeCanvas, false);
resizeCanvas();
}
function resizeCanvas() {
htmlCanvas.width = window.innerWidth;
htmlCanvas.height = window.innerHeight;
}
})();
});
$(".hvr_cnt").mouseenter(function () {
title = $("<div class='hvr_ttl'>" + $(this).children()[0].title + "</div>");
$(this).children()[0].title = "";
$(this).append(title);
});
$(document).mousemove(function(e){
$('.hvr_ttl').css({
top: e.pageY - $(".hvr_ttl").height()/2,
left: e.pageX - $(".hvr_ttl").width()/2
});
});
$(".hvr_cnt").mouseleave(function (e) {
$(this).children()[0].title = $($(this).children()[1]).html();
$(this).children()[1].remove();
});
body {
margin: 0;
padding: 0;
background: rgb(240, 240, 240);
width: 100%;
height: 100%;
border: 0;
color: rgb(40, 40, 40);
overflow: hidden;
display: block;
}
.slides {
display: none
}
#c {
display: block;
position: absolute;
left: 0px;
top: 0px;
}
.hvr_ttl {
display: block;
position: absolute;
pointer-events: none;
cursor: none;
}
.hvr_cnt {
cursor: none;
padding: none;
margin: none;
}
<body ontouchstart="">
<div class="hvr_cnt">
<canvas id="c" title="click"></canvas>
</div>
<ul class="slides">
<li><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/85/Smiley.svg/2000px-Smiley.svg.png" class="put" /></li>
<li><img src="https://emojipedia-us.s3.amazonaws.com/thumbs/160/google/56/thumbs-up-sign_1f44d.png" class="put" /></li>
</ul>
</body>
Any help would be appreciated :)
Try this :
htmlCanvas.onclick= function(evt) {
img.src = images[count];
img.width = 80/100* htmlCanvas.width;
img.height = 80/100* htmlCanvas.height;
var x = evt.offsetX - img.width/2,
y = evt.offsetY - img.height/2;
// context.drawImage(img, x, y);
context.drawImage(img, x, y, img.width, img.height);
count++;
if (count == images.length) {
count = 0;
}
}
context.drawImage(img, 0, 0,img.width,img.height,0,0,htmlCanvas.width,htmlCanvas.height);
you also can use background-size:cover;
The max-height/width doesn't work because everything within the canvas is independent from your css.
If you want to set the image to 80% use htmlCanvas.width and htmlCanvas.height to calculate the new size and use context.drawImage(img, x, y, w, h) to set the image size when drawing.
Maybe this post could be helpful.
This is the layout and design of my page.
HTML Code:
<div id="myid_browse_modal_image" >
<image id="img_browse" src=""></image>
</div>
<div id="div_myphoto">
<img id="img_myphoto" src="" alt="ID Photo"/>
</div>
CSS Code:
#myid_browse_modal_image
{
height: 370px;
line-height: 370px;
text-align:center;
border: 1px;
border-style: solid;
border-color: gray;
}
#myid_browse_modal_image > img
{
max-width: 100%;
height: 100%;
}
#div_myphoto > img
{
width: 150px;
height: 150px;
max-width:150px;
max-height: 150px;
border: 2px;
border-style: solid;
border-color: black;
}
My problem goes like this. I am implementing a functionality where I can browse an image and be able to crop it. It looks like the image below:
When I click the "Set as an ID Photo", it calls function that do the cropping functionality:
function myid_browse_crop()
{
var img_browse = document.getElementById('img_browse');
var $img_browse = $(img_browse);
var img_myphoto= document.getElementById('img_myphoto');
var $img_myphoto = $(img_myphoto);
//Create a temporary canvas
var canvas= document.createElement("canvas");
canvas.id = "temp_canvas";
canvas.width = img_browse.width;
canvas.height = img_browse.height;
// get the canvas context;
var ctx = canvas.getContext('2d');
ctx.drawImage(img_browse, 0, 0);
//Get the position of my resizable div relative to the image
var relativeX = $(".browse-selection").offset().left - $("#img_browse").offset().left;
var relativeY = $(".browse-selection").offset().top - $("#img_browse").offset().top;
var relativeW = $(".browse-selection").width();
var relativeH = $(".browse-selection").height();
var imageData = ctx.getImageData(relativeX,relativeY, relativeW, relativeH);
// create destination canvas
var canvas1 = document.createElement("canvas");
canvas1.width = relativeW;
canvas1.height = relativeH;
var ctx1 = canvas1.getContext("2d");
ctx1.rect(0, 0, relativeW, relativeH);
ctx1.putImageData(imageData, 0, 0);
img_myphoto.src = canvas1.toDataURL();
}
The result cropped image is below, which is not right.
It might be because of the dimensions of the image. The image is smaller in reality(202 x 250 pixels), but it gets distorted when browse and selected because of the css below, making it (299 x 370 pixels):
#myid_browse_modal_image > img
{
max-width: 100%;
height: 100%;
}
How will I fix it? To get just the correct selected region. Anyways ".browse -selection" is a div with a dashed lines in the Image 1. It is generated by a jquery plug-in that's why it is not included in my Original HTML Code.
Change
#myid_browse_modal_image > img
{
max-width: 100%;
height: 100%;
}
To this:
#myid_browse_modal_image > img
{
max-width: 100%;
height: auto;
max-height: 370px !important;
}
This issue is cause by having an image file dimensions on disk, different from what is being rendered in the browser.
In this case,I edited my code:
function myid_browse_crop()
{
var img_browse = document.getElementById('img_browse');
var $img_browse = $(img_browse);
var img_myphoto= document.getElementById('img_myphoto');
var $img_myphoto = $(img_myphoto);
//Create a temporary canvas
var canvas= document.createElement("canvas");
canvas.id = "temp_canvas";
canvas.width = img_browse_width ;
canvas.height = img_browse_height;
// get the canvas context;
var ctx = canvas.getContext('2d');
ctx.drawImage(img_browse, 0, 0);
//Get the position of my resizable div relative to the image
var relativeX = $(".browse-selection").offset().left - $("#img_browse").offset().left;
var relativeY = $(".browse-selection").offset().top - $("#img_browse").offset().top;
var relativeW = $(".browse-selection").width();
var relativeH = $(".browse-selection").height();
var xrelativeX = relativeX * (img_browse_width /img_browse.width);
var xrelativeY = relativeY * (img_browse_height/img_browse.height);
var xrelativeW = (img_browse_width /img_browse.width)*relativeW;
var xrelativeH = (img_browse_height/img_browse.height)*relativeH;
var imageData = ctx.getImageData(xrelativeX,xrelativeY, xrelativeW,xrelativeH );
// create destination canvas
var canvas1 = document.createElement("canvas");
canvas1.width = xrelativeW ;
canvas1.height = xrelativeH;
var ctx1 = canvas1.getContext("2d");
ctx1.rect(0, 0, xrelativeW, xrelativeH);
ctx1.putImageData(imageData, 0, 0);
img_myphoto.src = canvas1.toDataURL();
}
img_browse_height and img_browse_width are the actual file size of the image on disk. I had acquired this variables from reading an image file through an input file:
function readURL(input, imageframe) {
if (input.files && input.files[0]) {
var reader = new FileReader();
var image = new Image();
reader.onload = function (e) {
image.src = e.target.result;
image.onload = function() {
//Actual File Size in Disk of "#img_browse"
img_browse_width = this.width;
img_browse_height = this.height;
}
$('#img_browse')
.attr('src', e.target.result);
};
reader.readAsDataURL(input.files[0]);
}
}
I've got a canvas on my page and want to toggle it filling the page and backwards. My page is usually "higher" then a screens height so there is a scrollbar on my page. This scroll-bar does't hide when I'm setting the size of my canvas like that in my css:
canvas {
display: inline;
outline: 0;
margin: 50;
border: 1px solid #E0E0E0;
}
canvas.fullscreen {
display: block;
position: absolute;
top: 0;
left: 0;
border: none;
margin: 0;
}
My javascript looks like this:
//toggle the fullscreen mode
function fullscreen() {
if (!fullWindowState) {
fullWindowState = true;
//canvas goes full Window
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
canvas.className = "fullscreen"
} else {
fullWindowState = false;
//canvas goes normal
canvas.width = 820;
canvas.height = 600;
canvas.className = "";
}
}
The full code is on github too and the page is on gh-pages
http://patsimm.github.io/mandelight/
I really don't know what to do to remove the scrollbar when the canvas is in "fullscreen" mode. Every help is apreciated!
Thanks!
patsimm
This has something to do width <canvas> tag.
<canvas> will cause scrollbar if not set to display:block.
detail: http://colla.me/bug/show/canvas_cannot_have_exact_size_to_fullscreen
Try setting overflow to hidden when you're in fullWindowState;
//toggle the fullscreen mode
function fullscreen() {
if (!fullWindowState) {
fullWindowState = true;
//canvas goes full Window
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
canvas.className = "fullscreen"
document.body.scrollTop = 0; // <-- pull the page back up to the top
document.body.style.overflow = 'hidden'; // <-- relevant addition
} else {
fullWindowState = false;
//canvas goes normal
canvas.width = 820;
canvas.height = 600;
canvas.className = "";
document.body.style.overflow = 'visible'; // <-- toggle back to normal mode
}
}
Use the following CSS style for <html> and <body> tags,
<style>
html,
body {
margin: 0;
height: 100%;
overflow: hidden;
}
</style>
and the following javascript code to set width and height of the <canvas id="canvas"><canvas> element,
<script>
var canvas = document.getElementById('canvas');
canvas.width = document.body.clientWidth;
canvas.height = document.body.clientHeight;
</script>
If you go into full screen mode and use the developer tools to set visibility: hidden on the canvas, you can see that the page content behind the canvas is is too large, causing the scrollbars to appear. I was able to get rid of the scrollbars by setting display: none on the page footer. You could toggle the display property of the footer or other content while in full screen mode since it will be covered up by the canvas anyway.
I'm using the PDF.js library to render a pdf into the canvas. That pdf has hyperlinks in there, The PDF.js library is drawing the pdf into the canvas but the hyperlinks don't work.
Any Idea if it possible that hyperlinks work into the canvas?
Thanks
Here is a fiddle that shows you how to enable annotations (including hyperlinks) in PDF files.
The original PDF file used in the fiddle is here.
I used viewer code (web/page_view.js,web/viewer.css) as refrence to write this fiddle.
HTML:
<!doctype html>
<html lang="en">
<head>
<link href="style.css" rel="stylesheet" media="screen" />
<script src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script src="http://seikichi.github.io/tmp/PDFJS.0.8.715/pdf.min.js" type="text/javascript"></script>
<script src="http://seikichi.github.io/tmp/PDFJS.0.8.715/ui_utils.js"></script>
<script src="./main.js" type="text/javascript"></script>
</head>
<body>
<div id="pdfContainer" class="pdf-content">
<canvas id="the-canvas"></canvas>
<div class="annotationLayer"></div>
</div>
</body>
</html>
CSS:
body {
font-family: arial, verdana, sans-serif;
}
.pdf-content {
border: 1px solid #000000;
}
.annotationLayer > a {
display: block;
position: absolute;
}
.annotationLayer > a:hover {
opacity: 0.2;
background: #ff0;
box-shadow: 0px 2px 10px #ff0;
}
.annotText > div {
z-index: 200;
position: absolute;
padding: 0.6em;
max-width: 20em;
background-color: #FFFF99;
box-shadow: 0px 2px 10px #333;
border-radius: 7px;
}
.annotText > img {
position: absolute;
opacity: 0.6;
}
.annotText > img:hover {
opacity: 1;
}
.annotText > div > h1 {
font-size: 1.2em;
border-bottom: 1px solid #000000;
margin: 0px;
}
JavaScript:
PDFJS.workerSrc = 'http://seikichi.github.io/tmp/PDFJS.0.8.715/pdf.min.worker.js';
$(function () {
var pdfData = loadPDFData();
PDFJS.getDocument(pdfData).then(function (pdf) {
return pdf.getPage(1);
}).then(function (page) {
var scale = 1;
var viewport = page.getViewport(scale);
var $canvas = $('#the-canvas');
var canvas = $canvas.get(0);
var context = canvas.getContext("2d");
canvas.height = viewport.height;
canvas.width = viewport.width;
var $pdfContainer = $("#pdfContainer");
$pdfContainer.css("height", canvas.height + "px")
.css("width", canvas.width + "px");
var renderContext = {
canvasContext: context,
viewport: viewport
};
page.render(renderContext);
setupAnnotations(page, viewport, canvas, $('.annotationLayer'));
});
function setupAnnotations(page, viewport, canvas, $annotationLayerDiv) {
var canvasOffset = $(canvas).offset();
var promise = page.getAnnotations().then(function (annotationsData) {
viewport = viewport.clone({
dontFlip: true
});
for (var i = 0; i < annotationsData.length; i++) {
var data = annotationsData[i];
var annotation = PDFJS.Annotation.fromData(data);
if (!annotation || !annotation.hasHtml()) {
continue;
}
var element = annotation.getHtmlElement(page.commonObjs);
data = annotation.getData();
var rect = data.rect;
var view = page.view;
rect = PDFJS.Util.normalizeRect([
rect[0],
view[3] - rect[1] + view[1],
rect[2],
view[3] - rect[3] + view[1]]);
element.style.left = (canvasOffset.left + rect[0]) + 'px';
element.style.top = (canvasOffset.top + rect[1]) + 'px';
element.style.position = 'absolute';
var transform = viewport.transform;
var transformStr = 'matrix(' + transform.join(',') + ')';
CustomStyle.setProp('transform', element, transformStr);
var transformOriginStr = -rect[0] + 'px ' + -rect[1] + 'px';
CustomStyle.setProp('transformOrigin', element, transformOriginStr);
if (data.subtype === 'Link' && !data.url) {
// In this example, I do not handle the `Link` annotations without url.
// If you want to handle those annotations, see `web/page_view.js`.
continue;
}
$annotationLayerDiv.append(element);
}
});
return promise;
}
});
function loadPDFData() {
/*jshint multistr: true */
var base64pdfData = '...'; //should contain base64 representing the PDF
function base64ToUint8Array(base64) {
var raw = atob(base64);
var uint8Array = new Uint8Array(new ArrayBuffer(raw.length));
for (var i = 0, len = raw.length; i < len; ++i) {
uint8Array[i] = raw.charCodeAt(i);
}
return uint8Array;
}
return base64ToUint8Array(base64pdfData);
}
Enable Text Selection in PDF.JS
Step 1: Adding a Element to Hold the Text Layer
<div id="text-layer"></div>
This div will be in addition to the element where the PDF is rendered, so the HTML will look like :
<canvas id="pdf-canvas"></canvas>
<div id="text-layer"></div>
Step 2 : Adding CSS for Text Layer
Add the following to your CSS file :
#text-layer {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
overflow: hidden;
opacity: 0.2;
line-height: 1.0;
}
#text-layer > div {
color: transparent;
position: absolute;
white-space: pre;
cursor: text;
transform-origin: 0% 0%;
}
Step 3: Getting the PDF Text
After the PDF has been rendered in the canvas, you need to get the text contents of the PDF, and place that text in the text layer.
// page is the page context of the PDF page
// viewport is the viewport required in renderContext
// For more see https://usefulangle.com/post/20/pdfjs-tutorial-1-preview-pdf-during-upload-wih-next-prev-buttons
page.render(renderContext).then(function() {
// Returns a promise, on resolving it will return text contents of the page
return page.getTextContent();
}).then(function(textContent) {
// PDF canvas
var pdf_canvas = $("#pdf-canvas");
// Canvas offset
var canvas_offset = pdf_canvas.offset();
// Canvas height
var canvas_height = pdf_canvas.get(0).height;
// Canvas width
var canvas_width = pdf_canvas.get(0).width;
// Assign CSS to the text-layer element
$("#text-layer").css({ left: canvas_offset.left + 'px', top: canvas_offset.top + 'px', height: canvas_height + 'px', width: canvas_width + 'px' });
// Pass the data to the method for rendering of text over the pdf canvas.
PDFJS.renderTextLayer({
textContent: textContent,
container: $("#text-layer").get(0),
viewport: viewport,
textDivs: []
});
});
source: https://usefulangle.com/post/90/javascript-pdfjs-enable-text-layer
setupAnnotations = (page, viewport, canvas, annotationLayerDiv) => {
let pdfjsLib = window['pdfjs-dist/build/pdf'];
let pdfjsViewer = window['pdfjs-dist/web/pdf_viewer'];
//BELOW--------- Create Link Service using pdf viewer
let pdfLinkService = new pdfjsViewer.PDFLinkService();
page.getAnnotations().then(function (annotationsData) {
viewport = viewport.clone({
dontFlip: true
});
let pdf_canvas = canvas;
// Render the annotation layer
annotationLayerDiv.style.left = pdf_canvas.offsetLeft + 'px';
annotationLayerDiv.style.top = pdf_canvas.offsetTop + 'px';
annotationLayerDiv.style.height = viewport.height + 'px';
annotationLayerDiv.style.width = viewport.width + 'px';
pdfjsLib.AnnotationLayer.render({
viewport: viewport,
div: annotationLayerDiv,
annotations: annotationsData,
page: page,
linkService: pdfLinkService,
enableScripting: true,
renderInteractiveForms: true
});
}
IMP ---- Do not forget to add this CSS
.annotation-layer{
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
overflow: hidden;
opacity: 1;
}
.annotation-layer section{
position: absolute;
cursor: pointer;
}
.annotation-layer section a{
display: block;
width: 100%;
height: 10px;
}
In above example, Link service instance is created using class in pdf viewer, which is being passed as parameter to annotation layer render method.
Please refer source code of PDF.js refer to /web/pdf_viewer.js - class PDFLinkService for more information.
PDF.js version - v2.9.359