How to fit image in canvas using cropperJS - javascript

I am new using cropperjs library. But I'm struggling on how can I configure it.
What I have
https://jsfiddle.net/kaeqxfjL/
What I need
I want to integrate a full image crop where you just need to drag the photo inside the canvas instead of having a square to crop the photo. I also need to make the width of the photo fit to the width of the canvas so you cannot drag it left/right; you could only drag it up/down.
var canvas = $("#canvas"),
context = canvas.get(0).getContext("2d"),
$result = $('#result');
$('#fileInput').on( 'change', function(){
if (this.files && this.files[0]) {
if ( this.files[0].type.match(/^image\//) ) {
var reader = new FileReader();
reader.onload = function(evt) {
var img = new Image();
img.onload = function() {
context.canvas.height = img.height;
context.canvas.width = img.width;
context.drawImage(img, 0, 0);
var cropper = canvas.cropper({
aspectRatio: 16 / 9,
dragMode: 'move'
});
$('#btnCrop').click(function() {
// Get a string base 64 data url
var croppedImageDataURL = canvas.cropper('getCroppedCanvas').toDataURL("image/png");
$result.append( $('<img>').attr('src', croppedImageDataURL) );
});
$('#btnRestore').click(function() {
canvas.cropper('reset');
$result.empty();
});
};
img.src = evt.target.result;
};
reader.readAsDataURL(this.files[0]);
}
else {
alert("Invalid file type! Please select an image file.");
}
}
else {
alert('No file(s) selected.');
}
});
/* Limit image width to avoid overflow the container */
img {
max-width: 100%; /* This rule is very important, please do not ignore this! */
}
#canvas {
height: 290px;
width: 650px;
background-color: #ffffff;
cursor: default;
border: 1px solid black;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/cropper/2.3.3/cropper.css" rel="stylesheet"/>
<p>
<!-- Below are a series of inputs which allow file selection and interaction with the cropper api -->
<input type="file" id="fileInput" accept="image/*" />
<input type="button" id="btnCrop" value="Crop" />
<input type="button" id="btnRestore" value="Restore" />
</p>
<div>
<canvas id="canvas">
Your browser does not support the HTML5 canvas element.
</canvas>
</div>
<div id="result"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/cropper/2.3.3/cropper.js"></script>

Set image width using class:
.img-container img {
width: 100%;
}
And set viewMode and aspectRatio as below.
var cropper = canvas.cropper({
aspectRatio: 16 / 9,
dragMode: 'move',
viewMode: 3,
aspectRatio: 1
});
var canvas = $("#canvas"),
context = canvas.get(0).getContext("2d"),
$result = $('#result');
$('#fileInput').on('change', function() {
if (this.files && this.files[0]) {
if (this.files[0].type.match(/^image\//)) {
var reader = new FileReader();
reader.onload = function(evt) {
var img = new Image();
img.onload = function() {
context.canvas.height = img.height;
context.canvas.width = img.width;
context.drawImage(img, 0, 0);
var cropper = canvas.cropper({
aspectRatio: 16 / 9,
dragMode: 'move',
viewMode: 3,
aspectRatio: 1
});
$('#btnCrop').click(function() {
// Get a string base 64 data url
var croppedImageDataURL = canvas.cropper('getCroppedCanvas').toDataURL("image/png");
$result.append($('<img>').attr('src', croppedImageDataURL));
});
$('#btnRestore').click(function() {
canvas.cropper('reset');
$result.empty();
});
};
img.src = evt.target.result;
};
reader.readAsDataURL(this.files[0]);
} else {
alert("Invalid file type! Please select an image file.");
}
} else {
alert('No file(s) selected.');
}
});
/* Limit image width to avoid overflow the container */
img {
max-width: 100%;
/* This rule is very important, please do not ignore this! */
}
#canvas {
height: 290px;
width: 650px;
background-color: #ffffff;
cursor: default;
border: 1px solid black;
}
.img-container img {
width: 100%;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/cropper/2.3.3/cropper.css" rel="stylesheet" />
<p>
<!-- Below are a series of inputs which allow file selection and interaction with the cropper api -->
<input type="file" id="fileInput" accept="image/*" />
<input type="button" id="btnCrop" value="Crop" />
<input type="button" id="btnRestore" value="Restore" />
</p>
<div>
<canvas id="canvas" class="img-container">
Your browser does not support the HTML5 canvas element.
</canvas>
</div>
<div id="result"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/cropper/2.3.3/cropper.js"></script>

Related

jquery preview image not working

So I'm trying to implement a preview button so that when my users clicks on the upload button image they could have a preview but the thing is that it is not working, I wonder why ?? A brief description : I have a js function that creates new elements and append it to a p tag date. It is in this function that is going to create the preview image code
// code for creating new elements
function createElements(){
const userQuestions = document.querySelector('#userQuestions');
userQuestions.insertAdjacentHTML(
'beforeend', '<div class="uploader" onclick="$(\'#filePhoto\').click()"><p id="bg-text">No image</p></div><input type="file" name="userprofile_picture" id="filePhoto" style="display:block;width:185px;" /></center><div class="grid-container">'
);
}
///Code to preview image
function handleImage(e) {
var imageLoader = document.getElementById('filePhoto');
imageLoader.addEventListener('change', handleImage, false);
var reader = new FileReader();
reader.onload = function (event) {
$('.uploader').html( '<img width="300px" height="350px" src="'+event.target.result+'"/>' );
}
reader.readAsDataURL(e.target.files[0]);
}
.uploader {width:50%;height:35%;background:#f3f3f3;border:2px dashed #0091ea;}
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<div id="userQuestions"></div>
<button type="button" onclick="createElements()">add elements</button>
</body>
</html>
If you run the snippet above you can see that the button is woeking but the preview is not showing. Could someone help me?
HTML:
<div class="row">
<div class="col-xs-4">
<div class="form-group">
<label>Company Logo</label>
<input type="file" class="form-control" value="" name="companyLogo" id="companyLogo" accept="image/*" />
</div>
</div>
<div id="displayImage">
<img id="imgData" src="#" alt="your image" height="150px" width="150px" />
</div>
</div>
JavaScript:
$("#companyLogo").change(function(e) {
if(e.target.value === "") {
$("#displayImage").hide();
} else {
$("#displayImage").show();
}
readURL(this);
});
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
$("#imgData").attr("src", e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
Short n simple
No need to create an element on click.
Just add an image tag and set a default image like no image selected or something like that.
The following code will help you
<input type="file" name="myCutomfile" id="myCutomfile"/>
<img id="customTargetImg" src="default.jpg" width="400" height="250">
$("#myCutomfile").change(function() {
if (this.files && this.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#customTargetImg').attr('src', e.target.result);
}
reader.readAsDataURL(this.files[0]);
}
});
Take advantage of jQuery -- particularly using
event handlers
delegated event handlers for dynamically-created elements
tree traversal methods.
$(function() {
var userQuestions = $('#userQuestions');
// create onclick event handler for your button
$('#addElements').click(function() {
// IDs must be unique - since you can have an arbitrary number of filePhoto, use a class instead
userQuestions.append(
'<div class="uploader"><p id="bg-text">No image</p></div><input type="file" name="userprofile_picture" class="filePhoto" /><div class="grid-container"></div>'
);
});
// create delegated onclick event handler for your .uploader
userQuestions.on('click', '.uploader', function() {
// you only want to target the file input immediately after it
$(this).next('[type=file]').click();
});
// create delegated onchange event handler for your .filePhoto
userQuestions.on('change', '.filePhoto', function() {
// find related uploader
var uploader = $(this).prev('.uploader');
// check file was given
if (this.files && this.files.length) {
var reader = new FileReader();
reader.onload = function(event) {
uploader.html('<img width="300px" height="350px" src="' + event.target.result + '"/>');
}
reader.readAsDataURL(this.files[0]);
}
});
});
.uploader {
width: 50%;
height: 35%;
background: #f3f3f3;
border: 2px dashed #0091ea;
}
.filePhoto {
display: block;
width: 185px;
}
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<div id="userQuestions"></div>
<!-- added ID attribute -->
<button type="button" id="addElements">add elements</button>
</body>
</html>
Edit
This answer is a non-jQuery solution based off your comment.
// code for creating new elements
function createElements() {
// no need to document.querySelector if the selector is an ID
const userQuestions = document.getElementById('userQuestions');
// you want to use onclick/onchange attributes here as they are dynamically created
userQuestions.insertAdjacentHTML(
'beforeend', '<div class="uploader" onclick="selectFile(this)"><p id="bg-text">No image</p></div><input type="file" name="userprofile_picture" onchange="handleImage(this)" />'
);
}
// trigger click on file input that follows the uploader
function selectFile(uploader) {
uploader.nextSibling.click();
}
///Code to preview image
function handleImage(input) {
if (input.files.length) {
var reader = new FileReader();
reader.onload = function(e) {
input.previousSibling.innerHTML =
'<img width="300px" height="350px" src="' + e.target.result + '"/>';
}
reader.readAsDataURL(input.files[0]);
}
}
.uploader {
width: 50%;
height: 35%;
background: #f3f3f3;
border: 2px dashed #0091ea;
}
.filePhoto {
display: block;
width: 185px;
}
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<div id="userQuestions"></div>
<button type="button" onclick="createElements()">add elements</button>
</body>
</html>

Saving/Loading JSON on Page

I'd like to make a saver/loader for a single canvas, like on the Fabric.js example website (see JSON tab). I'm able to get, and load to a canvas, my JSON (kudos Durga) with this:
var canvas = new fabric.Canvas('canvas', {
backgroundColor: 'white',
centeredScaling: true,
isDrawingMode: true
});
var canvas1 = new fabric.Canvas('canvas1');
function loadOnCanvas(){
var json = canvas.toJSON();
console.log(json)
canvas1.loadFromJSON(json,canvas1.renderAll.bind(canvas1));
}
body {
}
canvas {
border-radius: 2px;
margin: 5px;
border:1px solid #000000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.22/fabric.min.js"></script>
<button onclick='loadOnCanvas()'>Load</button>
<canvas id="canvas" height="400" width="400"></canvas><br>
<canvas id="canvas1" height="400" width="400"></canvas>
How would I go about getting the JSON on the page so that I can save/load it like in the example?
For anyone coming across this post, I eventually got a solution (here's the JSFiddle) together:
$(function() {
var canvas = new fabric.Canvas('c', {
/* isDrawingMode: true */
});
$('#text').on('click', addtext);
function addtext() {
var text = new fabric.IText('Some Text!', {
left: 10,
top: 10
});
canvas.add(text);
}
// From Computer
document.getElementById('imgLoader').onchange = function handleImage(e) {
var reader = new FileReader();
reader.onload = function(event) {
console.log('fdsf');
var imgObj = new Image();
imgObj.src = event.target.result;
imgObj.onload = function() {
// start fabricJS stuff
var image = new fabric.Image(imgObj);
image.set({
left: 0,
top: 0,
angle: 20,
padding: 10,
cornersize: 10
});
//image.scale(getRandomNum(0.1, 0.25)).setCoords();
image.scale(0.2);
canvas.add(image);
// end fabricJS stuff
}
}
reader.readAsDataURL(e.target.files[0]);
}
//
var myImg = 'https://i.imgur.com/q2oGjQ9.jpg';
$('#addImage').on('click', addImg);
function addImg() {
fabric.Image.fromURL(myImg, function(oImg) {
oImg.scale(0.2);
canvas.add(oImg);
});
}
$("#canvas2json").click(function() {
var json = canvas.toJSON();
$("#myTextArea").text(JSON.stringify(json));
});
$("#loadJson2Canvas").click(function() {
canvas.loadFromJSON(
$("#myTextArea").val(),
canvas.renderAll.bind(canvas));
});
});
#myTextArea {
width: 200px;
height: 200px;
}
canvas {
border: 1px solid black
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.22/fabric.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<button id="text">Add Text</button>
<input type="button" id="addImage" value="Add Web IMG">
<input type="file" id="imgLoader">
<br/><br/>
<canvas id='c' width=500 height=500></canvas>
<br/>
<button id='canvas2json'>canvas2json</button>
<button id='loadJson2Canvas'>loadJson2Canvas</button>
<br/><br/>
<textarea id='myTextArea' onfocus="this.select();" onmouseup="return false;"></textarea>

Jquery Crop: cropper image not changing

I have the following code:
<link rel="stylesheet" href="style.css">
<script src="/static/js/jquery/2.1.4/jquery.min.js"></script>
<script src="http://fengyuanchen.github.io/cropper/js/cropper.min.js"></script>
<form action="" method="post" enctype="multipart/form-data">
<img id="crop" style="width:400px;height:200px;" />
<div id="img2" style="position: relative; overflow: hidden; border: 1px solid #000; background: #fff; width: 100px; height: 100px;"></div>
X: <input type="text" id="crop_x" name="crop_x" /><br />
Y: <input type="text" id="crop_y" name="crop_y" /><br />
Width: <input type="text" id="crop_width" name="crop_width" /><br />
Height: <input type="text" id="crop_height" name="crop_height" /><br />
<input type="file" id="file" name="file" />
<input type="submit" id="submit" name="submit" value="Submit" />
</form>
<script>
var url = null;
$('#file').on('change',function(){
var file = this.files[0];
if(url != null){
URL.revokeObjectURL(url);
}
url = URL.createObjectURL(file);
startCropper();
});
function startCropper(){
$('#crop').removeAttr('src');
$('#crop').attr('src',url);
$('#crop').cropper({
viewMode : 0,
cropBoxResizable : false,
minCropBoxWidth : 100,
minCropBoxHeight : 100,
dragMode : 'none',
preview : $('#img2'),
aspectRatio: 1,
crop : function(e){
$('#crop_x').val(e.x);
$('#crop_y').val(e.y);
}
});
};
</script>
The problem is that when I select a new file, the new image is not showed (the old image is still displayed in the cropper).
As you can see, I check the old url and revoke this. When I don't use $("#crop").cropper({...}) in the startCropper() function, it works.
GitHub: https://github.com/fengyuanchen/cropper/tree/v2.3.0
How can I force the cropper to load the new image?
You need to call
$('#crop').cropper('destroy');
before crop initialization
This code will solve the problem of Image not changing in Cropper.
HTML
<input id="userImage" type="file" name="userImage" accept="image/*">
<div>
<canvas id="canvas" style="display: none;">
Your browser does not support the HTML5 canvas element.
</canvas>
</div>
<div id="imagePreview" style="position: relative; overflow: hidden; border: 1px solid #000; background: #fff; width: 100px; height: 100px;"></div>
CSS
img {max-width: 100%;} /* This rule is very important, please do not ignore this! */
#canvas {
height: auto;
width: 250px; /*Change this value according to your need*/
background-color: #ffffff;
cursor: default;
border: 1px solid #000;
}
JS
var canvas = $("#canvas");
context = canvas.get(0).getContext("2d");
$('#userImage').on( 'change', function(){
if (this.files && this.files[0]) {
if ( this.files[0].type.match(/^image\//) ) {
var reader = new FileReader();
reader.onload = function(evt) {
var img = new Image();
img.onload = function() {
context.canvas.height = img.height;
context.canvas.width = img.width;
context.drawImage(img, 0, 0);
// Destroy the old cropper instance
canvas.cropper('destroy');
// Replace url
canvas.attr('src', this.result);
var cropper = canvas.cropper({
//these options can be changed or modified according to need
viewMode: 0,
cropBoxResizable: false,
minCropBoxWidth: 100,
minCropBoxHeight: 100,
dragMode: 'none',
preview: $('#imagePreview'),
aspectRatio: 1,
crop : function(e){
$('#crop_x').val(e.x);
$('#crop_y').val(e.y);
}
});
};
img.src = evt.target.result;
};
reader.readAsDataURL(this.files[0]);
} else {
alert("Invalid file type! Please select an image file.");
}
} else {
alert('No file(s) selected.');
}
});
For more details and better understanding Visit
Cropper Official Documentation
For cropper JS 1.3.3 it is cropper.destroy(); instead of canvas.cropper('destroy') after the drawing of the canvas.
`

Show a part of canvas image in an <img> tag

I can show the full content of canvas in an <img> tag using canvas.toDataURL() method.
I can get a part of image from canvas using getImageData() method and draw it in another canvas using putImageData() method.
The problem is, I want to show the part of image getting by getImageData() in an <img> tag as canvas.toDataURL() but I failed.
What I've tried so far is:
var canvas = $('canvas')[0];
var ctx = canvas.getContext("2d");
$('#baseImg').load(function() {
ctx.drawImage(this, 0, 0);
});
$('#full').click(function () {
$('div').html('');
var image = new Image();
image.onload = function() {
$('div').html(this);
};
image.src = canvas.toDataURL();
});
// here i failed
$('#partail').click(function () {
$('div').html('');
var image = new Image();
image.onload = function () {
$('div').html(this);
};
image.src = ctx.getImageData(10, 10, 50, 50);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3>Canvas</h3>
<canvas id="canvas" width="100" height="100" style="border: 1px solid #000000;"></canvas>
<br/><br/>
<img id="baseImg" style="display: none;" src="data:image/png;base64,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" />
<input id="full" type="button" value="Show Full Image" />
<input id="partail" type="button" value="Show Partial Image" />
<h3>Image from canvas</h3>
<div style="border: 1px solid #000000; height: 100px; width: 100px;"></div>
You can use context.drawImage to draw a partial clipped rectangular part of your full image.
The clipping version of drawImage looks like this:
context.drawImage(imageObject,
XClipFromSource, YClipFromSource, widthToClipFromSource, heightToClipFromSource,
canvasX, canvasY, canvasWidth, canvasHeight
);
Here's example code and a demo:
<<===>>
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var status=1;
var img=document.getElementById('baseImg');
$('#toggle').on('click',function(){
status*=-1;
draw();
});
draw();
//
function draw(){
if(status==1){
canvas.width=img.width;
canvas.height=img.height;
ctx.drawImage(img,0,0);
}else{
canvas.width=50;
canvas.height=50;
ctx.drawImage(img,10,10,50,50,0,0,50,50);
}
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<button id=toggle>Toggle img display</button>
<br>
<canvas id="canvas" width=300 height=300></canvas>
<img id="baseImg" style="display: none;" src="data:image/png;base64,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" />
I have solved my problem with the suggestions of everyone. I've used a temporary canvas to hold the part of main canvas and then get the partial image from it.
And my solution is:
var canvas = $('canvas')[0];
var ctx = canvas.getContext("2d");
$('#baseImg').load(function() {
ctx.drawImage(this, 0, 0);
});
$('#full').click(function() {
$('div').html('');
var image = new Image();
image.onload = function() {
$('div').html(this);
};
image.src = canvas.toDataURL();
});
$('#partail').click(function() {
$('div').html('');
var height = 50, width = 50;
var copyCanvas = $('<canvas id="canvas" width="' + width + '" height="' + height + '"></canvas>')[0];
var copyCtx = copyCanvas.getContext("2d");
copyCtx.putImageData(ctx.getImageData(10, 10, width, height), 0, 0);
var image = new Image();
image.onload = function() {
$('div').html(this);
};
image.src = copyCanvas.toDataURL();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3>Canvas</h3>
<canvas id="canvas" width="100" height="100" style="border: 1px solid #000000;"></canvas>
<br /><br />
<img id="baseImg" style="display: none;" src="data:image/png;base64,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" />
<input id="full" type="button" value="Show Full Image" />
<input id="partail" type="button" value="Show Partial Image" />
<h3>Image from canvas</h3>
<div style="border: 1px solid #000000; height: 100px; width: 100px;"></div>

How to make html div with text over image downloadable/savable for users?

I have a div that takes a user image and places user text over it. My goal is for the users to, after seeing the preview and customizing the image/text to their like, be able to download or save the image with the click of a button. Is this possible? Here's my code: (I'm new to html/css so please forgive ugly formatting/methods)
HTML:
<script `src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>`
<p>DOM-rendered</p>
<p> </p>
<div id="imagewrap" class="wrap" style="border-style: solid;">
<img src="../images/environment.gif" id="img_prev" width="640" height="640" />
<h3 class="desc">Something Inspirational</h3>
</div>
<div id="canvasWrapper" class="outer">
<p>Canvas-rendered (try right-click, save image as!)</p>
<p>Or, <a id="downloadLink" download="cat.png">Click Here to Download!</a>
</div>
CSS:
.desc {
text-align: center;
}
.outer, .wrap, .html2canvas, .image_text {
display: inline-block;
vertical-align: top;
}
.wrap {
text-align: center;
}
#imagewrap {
background-color: white;
}
JavaScript:
window.onload = function() {
html2canvas(document.getElementById("imagewrap"), {
onrendered: function(canvas) {
canvas.className = "html2canvas";
document.getElementById("canvasWrapper").appendChild(canvas);
var image = canvas.toDataURL("image/png");
document.getElementById("downloadLink").href = image;
},
useCORS: true
});
}
function changePicture(image) {
var at = $(image).attr('at');
var newpath = '../images/' + at;
$("#img_prev").attr('src', newpath);
}
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#img_prev')
.attr('src', e.target.result)
.width(640)
.height(640);
};
reader.readAsDataURL(input.files[0]);
}
};
$(document).on("click", '.font-names li a', function() {
$("#imagewrap h3").css("font-family", $(this).parent().css("font-family"));
$("#new_tile_font_style").val($(this).parent().css("font-family"));
});
$(document).on("click", '.font-sizes li a', function() {
$("#imagewrap h3").css("font-size", $(this).parent().css("font-size"));
$("#new_tile_font_size").val($(this).parent().css("font-size") + "px");
});
$(document).on("click", '.font-colors li a', function() {
$("#imagewrap h3").css("color", $(this).parent().css("color"));
$("#new_tile_font_color").val($(this).parent().css("color"));
});
$("#new_tile_quote").on('keyup', function() {
var enteredText = $("#new_tile_quote").val().replace(/\n/g, "<br>");
$("#imagewrap h3").html(enteredText);
});
What you're trying to accomplish is entirely possible using just HTML, JS, and CSS, with no server-side code. Here is a simplified demo that uses the html2canvas library to render your entire DOM element to a canvas, where the user can then download it.
Be sure to click "Full page" on the demo so you can see the whole thing!
window.onload = function() {
html2canvas(document.getElementById("imagewrap"), {
onrendered: function(canvas) {
canvas.className = "html2canvas";
document.getElementById("canvasWrapper").appendChild(canvas);
var image = canvas.toDataURL("image/png");
document.getElementById("downloadLink").href = image;
},
useCORS: true
});
}
.desc {
text-align: center;
}
.outer, .wrap, .html2canvas, .image_text {
display: inline-block;
vertical-align: top;
}
.wrap {
text-align: center;
}
#imagewrap {
background-color: white;
}
#wow {
color: red;
display: block;
transform: translate(0px, -12px) rotate(-10deg);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
<div class="outer">
<p>DOM-rendered</p>
<p> </p>
<div id="imagewrap" class="wrap" style="border-style: solid;">
<img src="https://i.imgur.com/EFM76Qe.jpg?1" id="img_prev" width="170" />
<h3 class="desc">Something <br /><span style="color: blue;">Inspirational</span></h3>
<span id="wow">WOW!</span>
</div>
</div>
<div id="canvasWrapper" class="outer">
<p>Canvas-rendered (try right-click, save image as!)</p>
<p>Or, <a id="downloadLink" download="cat.png">Click Here to Download!</a>
</div>
Here's a quick demo that shows how to use JavaScript to convert your markup into a canvas, then render that into an image and replace it on the page.
document.getElementById('generate').onclick = generateImage;
function generateImage() {
var container = document.getElementById('image_text');
var imgPrev = document.getElementById('img_prev');
var desc = document.getElementById('desc');
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
canvas.setAttribute('width', container.clientWidth);
canvas.setAttribute('height', container.clientHeight);
context.drawImage(imgPrev, 0, 0);
context.font = "bold 20px serif";
context.fillText(desc.innerHTML, 0, container.clientHeight-20);
context.strokeRect(0, 0, canvas.width, canvas.height);
var dataURL = canvas.toDataURL();
var imgFinal = new Image();
imgFinal.src = dataURL;
container.parentNode.insertBefore(imgFinal, container.nextSibling);
container.remove();
document.getElementById('generate').remove();
}
#image_text {
display: inline-block;
border: 1px solid #000;
}
<div id="image_text">
<div class="wrap">
<img src= "https://placekitten.com/g/200/300" id="img_prev" crossorigin="anonymous" />
<h3 id="desc" contenteditable>Something Inspirational</h3>
</div>
</div>
<button id="generate">Generate Image</button>
You can replace the image file with anything you like. I've added a crossorigin property to the img tag, and this is because canvases that use resources from other sites cannot be exported unless a crossorigin attribute is specified (if your scripts and images are on the same domain, this is unnecessary).
I've also made the h3 tag editable. You can click on the text and start typing to change what it says, then click "generate image" and save the rendered output.
This script is just a demonstration. It is not bulletproof, it is only a proof-of-concept that should help you understand the techniques being used and apply those techniques yourself.
The javascript creates a canvas element (detached from the DOM), and sizes it according to the container div in your markup. Then it inserts the image into the canvas (it inserts it at the top-left corner), loads the text from your h3 tag and puts it near the bottom-left of the canvas, and converts that canvas to a data-uri. Then it creates a new img element after the container and deletes the container and button.

Categories