I am using the Html2canvas in order to take a screenshot of a div and display it in a new window. Here is my javascript function
function capture() {
html2canvas(document.getElementById('screenshot'), {
onrendered: function(canvas) {
var img = canvas.toDataURL("image/png");
window.open(img);
}}
);
}
The problem with this code is that it captures only half of the div as the following image shows:
I changed the ID of the element to be captured to 'table' so that I can screenshot the table only. But it seems like the screenshot takes only half of the targeted div (in terms of height).
Now when I select the whole body:
function capture() {
html2canvas(document.body, {
onrendered: function(canvas) {
var img = canvas.toDataURL();
window.open(img);
}
});
the result is as follows:
I made a function that can adjust the output by 1 to 200% of the window height and width. To get your part working, I did the following:
....
html2canvas(document.body, {
onrendered: function(canvas) {
document.body.appendChild(canvas);
canvas.id = "ctx"
var ctx = document.getElementById('ctx');
var img = ctx.toDataURL("image/png");
window.open(img);
},....
Snippet
function hide(ele) {
var ele = document.querySelector(ele);
ele.style.display = 'none';
setTimeout(function() {
ele.style.display = 'block'
}, 1000);
return false;
}
function screenShot() {
var w = document.getElementById('w');
var h = document.getElementById('h');
var winW = window.outerWidth;
var winH = window.outerHeight;
var width = parseFloat(w.value * winW * .01);
var height = parseFloat(h.value * winH * .01);
html2canvas(document.body, {
onrendered: function(canvas) {
document.body.appendChild(canvas);
canvas.id = "ctx"
var ctx = document.getElementById('ctx');
var img = ctx.toDataURL("image/png");
window.open(img);
},
width: width,
height: height
});
return false;
}
main {
position: relative;
width: 100vw;
height: 100vh;
overflow: auto;
}
#panel {
position: absolute;
top: 0;
right: 0;
width: 200px;
height: 50px;
z-index: 1;
}
fieldset {
border-radius: 10px;
background: hsla(120, 100%, 50%, .5)
}
legend {
font: small-caps 700 20px/1.4'Source Code Pro';
}
section {
height: 33vh;
width: 100vw;
}
#sec1 {
background: red;
border: 1px solid blue;
}
#sec2 {
background: white;
border: 1px solid red;
}
#sec3 {
background: blue;
border: 1px solid white;
}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>34571073</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
</head>
<body>
<header id="panel">
<fieldset>
<legend>HTML2Canvas</legend>
<label for="w">Width.:
<input id="w" type="number" min="1" max="200" />%</label>
<br/>
<label for="h">Height:
<input id="h" type="number" min="1" max="200" />%</label>
<br/>
<input type="button" value="Capture" onclick="hide('#panel'); screenShot();" />
</fieldset>
</header>
<main>
<section id="sec1"></section>
<section id="sec2"></section>
<section id="sec3"></section>
</main>
</body>
</html>
Related
what I want to see the result is 2 set of split view screen (or more), one is vertical, one is horizontal, but in the same javascript file. If it's possible to do in a single JavaScript file will be good
I tried to use this one to make it but it seems like not how to make that.
Here's the code I'm trying to make two div elements and its vertical
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>my app</title>
<style>
.container {
width: 202px;
height: 406px;
border: 1px solid black;
display: flex;
flex-direction: column;
}
.top {
width: 200px;
height: 200px;
border: 1px solid red;
min-height: 100px;
}
.resizer {
width: 202px;
height: 2px;
background-color: green;
}
.resizer:hover {
cursor: ns-resize;
}
.bottom {
width: 200px;
height: 200px;
border: 1px solid blue;
flex: 1 1 0%;
min-height: 100px;
}
</style>
</head>
<body>
<div class="container">
<div class="top" id="top">
something here
</div>
<div class="resizer" id="resizer"></div>
<div class="bottom" id="bottom">
something too
</div>
</div>
<script>
const resizer = document.getElementById('resizer');
const topSection = document.getElementById('top');
const bottomSection = document.getElementById('bottom');
let x = 0;
let y = 0;
let topSectionHeight = 0;
const mouseDownHandler = function (e) {
x = e.clientX;
y = e.clientY;
topSectionHeight = topSection.getBoundingClientRect().height;
document.addEventListener('mousemove', mouseMoveHandler);
document.addEventListener('mouseup', mouseUpHandler);
}
resizer.addEventListener('mousedown', mouseDownHandler);
const mouseMoveHandler = function (e) {
const dx = e.clientX - x;
const dy = e.clientY - y;
const newtopSectionHeight = ((topSectionHeight + dy) * 100) / resizer.parentNode.getBoundingClientRect().height;
topSection.style.height = `${newtopSectionHeight}%`;
resizer.style.cursor = 'ns-resize';
document.body.style.cursor = 'ns-resize';
topSection.style.userSelect = 'none';
topSection.style.pointerEvents = 'none';
bottomSection.style.userSelect = 'none';
bottomSection.style.pointerEvents = 'none';
}
const mouseUpHandler = function () {
resizer.style.removeProperty('cursor');
document.body.style.removeProperty('cursor');
actionBasic.style.removeProperty('user-select');
actionBasic.style.removeProperty('pointer-events');
bottomSection.style.removeProperty('user-select');
bottomSection.style.removeProperty('pointer-events');
document.removeEventListener('mousemove', mouseMoveHandler);
document.removeEventListener('mouseup', mouseUpHandler);
}
</script>
</body>
</html>
thank you for reading so far, please help me if you're able to! If any information is needed, please tell me below and I'll provide it as soon as possible.
I am using Jcrop to crop Images, it is working fine with small size images, but Whenever I try to put large image like 2080x2080 or 1600x1600 it covers all my screen, also It cannot be handle with CSS like width and height control in Image tag
Seeking Solution/Suggestion -
Any method to put this image in container/div and then zoom-in/out with mouse event ?
Any method to handle large size image in a fix container and crop so that image maintain it's quality.
P.s: you can try with large image in below working example and see how it behaves with big Image.
var jcp;
var save = document.getElementById('save');
var imageLoader = document.getElementById('imageLoader');
var img = document.getElementById("target");
imageLoader.onchange = function handleImage(e) { //handling our image picker <input>:
var reader = new FileReader();
reader.onload = function(event) {
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
save.onclick = function() {
if (jcp && jcp.active) {
var i = 0;
for (area of jcp.crops) {
i++;
canvas = document.createElement("canvas");
canvas.setAttribute('width', area.pos.w);
canvas.setAttribute('height', area.pos.h);
ctx = canvas.getContext("2d");
ctx.drawImage(img, area.pos.x, area.pos.y, area.pos.w, area.pos.h, 0, 0, area.pos.w, area.pos.h);
temp = document.createElement('a');
temp.setAttribute('download', 'area' + i + '.jpg');
temp.setAttribute('href', canvas.toDataURL("image/jpg").replace("image/jpg", "image/octet-stream"));
temp.click();
}
}
};
Jcrop.load('target').then(img => {
jcp = Jcrop.attach(img, {
multi: true
});
});
body {
margin: 0px;
padding: 0px;
background-color: #ededed;
}
.cropapp {
position: absolute;
width: 100%;
height: 100%;
left: 5%;
background: lightgray;
}
.cropbox {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
}
div {
position: relative;
overflow: hidden;
}
<head>
<title>Jcrop Example</title>
<link href="https://unpkg.com/jcrop#3.0.1/dist/jcrop.css" rel="stylesheet" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://unpkg.com/jcrop#3.0.1/dist/jcrop.js"></script>
</head>
<body>
<div style="width:400px; margin:10px auto; padding:10px 0; overflow:hidden;"><a style="float:right; display:block; padding:10px 15px; color:#fff; background-color:#237dbd; font-size: 14px; font-weight:bold; border-radius:5px;" id="save">Save</a>
<input type="file" id="imageLoader" name="imageLoader" />
<!-- add this for file picker -->
</div>
<div>
<h1 style="font-family:Helvetica,sans-serif;">
Image Crop <span style="color:lightgray;"></span>
</h1>
<img id="target" style="background-size: cover !important;">
</div>
</body>
You can add any fixed width or height value to your <img id="target"/>. Just calculate and apply the change ratio to areas:
canvas = document.createElement("canvas");
displayWidth=img.width;
displayHeight=img.height;
realWidth = img.naturalWidth;
realHeight = img.naturalHeight;
widthRatio = Math.round(realWidth/displayWidth);
heightRatio = Math.round(realHeight/displayHeight);
width=area.pos.w*widthRatio
height=area.pos.h*heightRatio
canvas.setAttribute('width', width);
canvas.setAttribute('height', height);
ctx = canvas.getContext("2d");
ctx.drawImage(img, area.pos.x*widthRatio, area.pos.y*heightRatio, width, height, 0, 0, width, height);
and <img width="500" id="target"/> (or with css #target{width:500px})
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<title>Online Drawing Program</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="canvas"></div>
<script src="script.js"></script>
</body>
</html>
Javascript:
function drawingProgram(width, height) {
this.width = width;
this.height = height;
this.mousedown = false;
this.makeCanvas = function () {
for (var row = 0; row <= this.height; row++) {
$("#canvas").append("<div class='row' id='row" + row + "'></div>");
for (var col = 0; col <= height; col++) {
$("#row" + row).append("<div class='pixel'></div>");
}
}
}
this.draw = function (el) {
console.log("drawing");
$(el).css({ "background-color": "black" });
}
}
var drawing = new drawingProgram(50, 50);
drawing.makeCanvas();
$("body").on("mousedown", function () { drawing.mousedown = true });
$("body").on("mouseup", function () { drawing.mousedown = false });
$(".pixel").on("mouseover", function () {
if (drawing.mousedown) {
drawing.draw(this);
}
});
CSS:
.row {
display:block;
margin-top:-12px;
}
.pixel {
user-select: none;
flex-wrap:wrap;
display:inline-block;
width:5px;
height:5px;
border:1px solid black;
}
The program in action is here: https://online-drawing-program.powercoder.repl.co/
Problem: the program only makes the pixels at the bottom of my canvas div black. It's only detecting when I'm pressing the bottom pixels. But, I want to detect all my pixel divs.
The pixels are too small, and other CSS problems.
I added a color-picker just for fun.
function drawingProgram(width, height) {
this.width = width;
this.height = height;
this.mousedown = false;
this.color = "black"
this.makeCanvas = function() {
for (var row = 0; row <= this.height; row++) {
$("#canvas").append("<div class='row' id='row" + row + "'></div>");
for (var col = 0; col <= this.width; col++) {
$("#row" + row).append("<div class='pixel'></div>");
}
}
}
this.draw = function(el) {
console.log("drawing");
$(el).css({
"background-color": this.color
});
}
return this
}
var drawing = new drawingProgram(20, 20);
drawing.makeCanvas();
$("body").on("mousedown", function(e) {
drawing.mousedown = true
});
$("body").on("mouseup", function(e) {
drawing.mousedown = false
});
$(".pixel").on("mouseover", function() {
if (drawing.mousedown) {
drawing.draw(this);
}
});
$("#colorpicker div").on("click", function() {
drawing.color = $(this).data("color")
})
#colorpicker {
width: 100px;
height: 20px;
display: flex;
border: 1px solid black;
}
#colorpicker div {
display: block;
width: 20px;
height: 20px;
}
.row {
display: block;
margin: 0;
line-height: 1;
height: 12px;
}
.pixel {
user-select: none;
flex-wrap: wrap;
display: inline-block;
width: 10px;
height: 10px;
border: 1px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="colorpicker">
<div data-color="red" style="background-color: red;"></div>
<div data-color="yellow" style="background-color: yellow;"></div>
<div data-color="green" style="background-color: green;"></div>
<div data-color="black" style="background-color: black;"></div>
<div data-color="white" style="background-color: white;"></div>
</div>
<div id="canvas"></div>
SUGGESTION
If you want a drawing program then you should check out the canvas API - that's exactly for these kinds of things.
More on canvas:
basic: https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API
tutorial: https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial
I have an inner circle which tracks the position of my pointer, Now I want the circle color to change when it hovers on the h2 tag.
can anyone help??
I have tried searching few places but all were on "mouseover".
note: only when the inner-circle hovers on h2 not the mouse pointer, the inner circle's color should change.
<!doctype>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Roll Over Eyes</title>
<style>
body
{
display: flex;
align-items: center;
justify-content: center;
height: 900px;
border: 1px solid black;
}
.main-circle
{
display: flex;
align-items: center;
justify-content: center;
position: relative;
height: 350px;
width: 350px;
border: 1px solid black;
border-radius: 10%;
}
#inner-circle
{
position: absolute;
height: 50px;
width: 50px;
border: 1px solid black;
border-radius: 50%;
background: #af4b23;
}
.message
{
display:none;
width: 75%;
}
</style>
</head>
<body>
<div class="main-circle">
<div id="inner-circle">
</div>
<h2 class="message">Your Outside the box</h2>
<h2 class="message">Your inside the box, now move the mouse to move the circle.</h2>
</div>
<script>
(function()
{
var ele= document.getElementById("inner-circle");
var hea= document.getElementsByClassName("message");
var body=document.body;
var height=body.clientHeight;
var width=body.clientWidth;
var move = function(event)
{
var x= event.clientX;
var y= event.clientY;
ele.style.left = ( x/width )*300;
ele.style.top = ( y/height )*300;
}
var display = function()
{
console.log("done");
hea[0].style.display="inline-block";
hea[1].style.display="none";
}
var hide = function()
{
console.log("done hiden");
hea[0].style.display="none";
hea[1].style.display="inline-block";
}
var effect = function()
{
ele.style.backgroundColor= "rgba(0,0,0,0.5)";
}
var deflt = function()
{
ele.style.backgroundColor= "#af4b23";
}
body.addEventListener("mousemove",function(){ move(event) },false);
body.addEventListener("mouseout",display,false);
body.addEventListener("mouseover",hide,false);
hea[1].addEventListener("mouseover",effect,false);
hea[1].addEventListener("mouseout",deflt,false);
})();
</script>
</body>
</html>
You can try this:
(function()
{
var ele= document.getElementById("inner-circle");
var hea= document.getElementsByClassName("message");
var body=document.body;
var height=body.clientHeight;
var width=body.clientWidth;
var move = function(event)
{
var x= event.clientX;
var y= event.clientY;
ele.style.left = ( x/width )*300;
ele.style.top = ( y/height )*300;
var e_pos = ele.getBoundingClientRect();
var h_pos = hea[1].getBoundingClientRect();
if(e_pos.bottom>=h_pos.top && e_pos.top<=h_pos.bottom && e_pos.right>=h_pos.left && e_pos.left<=h_pos.right){
ele.style.backgroundColor= "rgba(0,0,0,0.5)";
}else{
ele.style.backgroundColor= "#af4b23";
};
}
var display = function()
{
//console.log("done");
hea[0].style.display="inline-block";
hea[1].style.display="none";
}
var hide = function()
{
//console.log("done hiden");
hea[0].style.display="none";
hea[1].style.display="inline-block";
}
body.addEventListener("mousemove",function(){ move(event) },false);
body.addEventListener("mouseout",display,false);
body.addEventListener("mouseover",hide,false);
})();
in this answer i set background-color after setting left and top of ele. also i have removed two last eventListeners.
Look at the result online and change it yorself!
the border is added to detect h2's bounds.
I have a simple drawing spectrum on a website http://alldev.eu/html/mp3/index.phtml, which loads to browser cache a song and plays it after it's fully downloaded.
I've made a pre-loader for my site which displays a message and an image for 7 seconds while the song is being loaded. Unfortunately, it doesn't work in the way I'd like to since 7 seconds might not be enough time to load a song (for instance, a test song with 11 Megabytes)
How can I rebuild my site to pre-load all data? My current script is below:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"></meta>
<title>Shiny Toy Guns - Major Tom</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-2.1.0.min.js"></script>
<script type="text/javascript">
(function($) {
$.fn.extend({
jqbar: function(options) {
var DefaultSpeedOfAnimation = 7000;
var settings = $.extend({
SpeedOfAnimation: DefaultSpeedOfAnimation,
LengthOfBar: 200,
barWidth: 10,
barColor: 'red',
label: ' ',
value: 100
}, options);
return this.each(function() {
var valueLabelHeight = 0;
var ContainerProgress = $(this);
ContainerProgress.addClass('jqbar horizontal').append('<div class="bar-label"></div><div class="bar-level-wrapper"><div class="bar-level"></div></div><div class="bar-percent"></div>');
var progressLabel = ContainerProgress.find('.bar-label').html(settings.label);
var progressBar = ContainerProgress.find('.bar-level').attr('data-value', settings.value);
var progressBarWrapper = ContainerProgress.find('.bar-level-wrapper');
progressBar.css({
height: settings.barWidth,
width: 0,
backgroundColor: settings.barColor
});
var valueLabel = ContainerProgress.find('.bar-percent');
valueLabel.html('0');
animateProgressBar(progressBar);
function animateProgressBar(progressBar) {
var level = parseInt(progressBar.attr('data-value'));
if (level > 100) {
level = 100;
alert('max value cannot exceed 100 percent');
}
var w = settings.LengthOfBar * level / 100;
progressBar.animate({
width: w
}, {
duration: DefaultSpeedOfAnimation,
step: function(currentWidth) {
var percent = parseInt(currentWidth / settings.LengthOfBar * 100);
if (isNaN(percent)) percent = 0;
ContainerProgress.find('.bar-percent').html(percent + '%');
}
});
}
});
}
});
})(jQuery);
</script>
<style>
body {
text-align: center;
background-color: black;
color: white;
}
footer {
float: center;
bottom: 0;
position: absolute;
color: #FFFFFF;
font: bold 1.2em/2.5 arial;
width: 99%;
}
.jqbar {
position: relative;
top: 100px;
}
.jqbar.horizontal div {
display: inline-block;
margin-left: 5px;
font-size: 11px;
font-weight: bold;
}
.jqbar.horizontal .bar-percent {
font-size: 11px;
font-weight: bold;
height: 20px;
margin-bottom: 5px;
}
#progressbar {
width: 400px;
height: 22px;
border: 1px solid #000;
background-color: #292929;
}
#progressbar div {
height: 100%;
color: #FFF;
text-align: center;
line-height: 22px;
width: 0;
background-color: #0099FF;
}
#preloader {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
color: #FFF;
z-index: 99;
height: 100%;
}
#status {
width: 200px;
height: 200px;
position: absolute;
left: 50%;
top: 50%;
background-color: #000;
background-repeat: no-repeat;
background-position: center;
margin: -100px 0 0 -100px;
}
</style>
</head>
<body onload="hide_preloader();">
<div id="preloader">
<div id="status">Wait for MP3 Load...
<br>
<br>
<br>
<img src="http://alldev.eu/html/images/Loader.gif" />
</div>
</div>
<footer>
<center>
<div id="bar-1"></div>
<canvas id="music" width="1024" height="250" style="display: block;"></canvas>
</center>
</footer>
<script type="text/javascript">
jQuery(window).load(function() {
jQuery("#status").delay(5000).fadeOut(2500);
jQuery("#preloader").delay(5000).fadeOut(2500);
jQuery("#bar-1").delay(5000).fadeOut(2500);
});
$(document).ready(function() {
$('#bar-1').jqbar({
SpeedOfAnimation: 7000,
label: 'Loading...',
value: 100,
barColor: '#FFF',
barWidth: 20
});
});
if (!window.AudioContext) {
if (!window.webkitAudioContext) {
alert('AudioContext not found!');
}
window.AudioContext = window.webkitAudioContext;
}
var context = new AudioContext();
var audioBuffer;
var sourceNode;
var analyser;
var javascriptNode;
var ctx = $("#music").get()[0].getContext("2d");
var gradient = ctx.createLinearGradient(0, 0, 0, 325);
gradient.addColorStop(1, '#FFFFFF');
gradient.addColorStop(0.75, '#00FFFF');
gradient.addColorStop(0.25, '#0000FF');
gradient.addColorStop(0, '#000000');
setupAudioNodes();
loadSound("http://alldev.eu/html/mp3/Shiny%20Toy%20Guns%20-%20Major%20Tom%20(Official%20Live).mp3");
function setupAudioNodes() {
javascriptNode = context.createScriptProcessor(2048, 1, 1);
javascriptNode.connect(context.destination);
analyser = context.createAnalyser();
analyser.smoothingTimeConstant = 0.75; //0.5;
analyser.fftSize = 512;
sourceNode = context.createBufferSource();
sourceNode.connect(analyser);
analyser.connect(javascriptNode);
sourceNode.connect(context.destination);
}
$(document).ready(function() {
$.ajax({
url: "soundfile.mp3",
success: function() {
$("#play_button").show();
}
});
});
function loadSound(url) {
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'arraybuffer';
request.onload = function() {
context.decodeAudioData(request.response, function(buffer) {
playSound(buffer);
}, onError);
}
request.send();
}
function playSound(buffer) {
sourceNode.buffer = buffer;
sourceNode.start(0);
}
function onError(e) {
console.log(e);
}
javascriptNode.onaudioprocess = function() {
var array = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(array);
ctx.clearRect(0, 0, 1024, 325);
ctx.fillStyle = gradient;
drawSpectrum(array);
}
function drawSpectrum(array) {
for (var i = 0; i < (array.length); i++) {
var value = array[i];
ctx.fillRect(i * 5, 325 - value, 3, 325);
}
};
</script>
</body>
</html>
you can give preloadJS a try.
http://www.createjs.com/#!/PreloadJS
here's some code from their documentation to get you started:
var queue = new createjs.LoadQueue();
queue.installPlugin(createjs.Sound);
queue.on("complete", handleComplete, this);
queue.loadFile({id:"sound", src:"http://path/to/sound.mp3"});
queue.loadManifest([
{id: "myImage", src:"path/to/myImage.jpg"}
]);
function handleComplete() {
createjs.Sound.play("sound");
var image = queue.getResult("myImage");
document.body.appendChild(image);
}
Check for JWPlayer API, you can have access to a method getBuffer(), which returns the current buffered state for your audio file : http://www.longtailvideo.com/support/jw-player/28851/javascript-api-reference/
But this requires to use JWplayer to play / handle your audio file, as it's not included in the audio object : http://www.w3schools.com/tags/av_prop_buffered.asp
EDIT :
I took some time to make it work, see the fiddle :) : http://jsfiddle.net/uKZ8N/
Basically, I set an interval of 0,5s which check the getBuffer() value.