currently I am calling canvas source images from imgur, but I would like to host them within my app, like "images/soundwave.png"... .. given my current code, I cant figure out how to do that.
If it helps at all I am using Middleman
<script>
var imgBg = new Image(),
imgFg = new Image(),
count = 2;
imgBg.onload = imgFg.onload = init;
imgBg.src = "http://i.imgur.com/hRHH9VO.png";
imgFg.src = "http://i.imgur.com/WoJggN0.png";
function init() {
var canvas = document.querySelector("canvas"),
ctx = canvas.getContext("2d"),
audio = document.querySelector("audio");
canvas.width = 500;
canvas.height = 120;
render();
audio.addEventListener("timeupdate", render);
function render() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(imgBg, 0, 0, canvas.width, canvas.height);
// calc progress
var progress = audio.currentTime / audio.duration;
// draw clipped version of top image
if (progress > 0) {
ctx.drawImage(imgFg, 0, 0, imgFg.width * progress, imgFg.height, // source
0, 0, canvas.width * progress, canvas.height); // dst
}
}
}
</script>
any help would be greatly appreciated
In your source directory you can create an images folder and put the images in there.
Then, you can either set the image src to your app URL or a relative URI (e.g. /images/hRHH9VO.png).
Then, if you just need to embed an image in the page you can use the image_tag template helper.
Related
There are numerous examples out there showing how to draw things onto a canvas, however, my problem is slightly different - I want to load a photo into memory, draw a shape onto exact coordinates over the photo, THEN draw/scale the photo onto a canvas. Not sure where to start with this. Are there any relevant libraries out there I can use with ionic that will allow you to do this?
Edit 1 ~ I now have this mostly working:
private properties:
#ViewChild('mainCanvas') canvasEl: ElementRef;
private _CANVAS: any;
private _CONTEXT: any;
ionViewDidEnter():
this._CANVAS = this.canvasEl.nativeElement;
this._CONTEXT = this._CANVAS.getContext('2d');
updateCanvas():
var img = new Image();
const ctx = this._CONTEXT;
const canvas = this._CANVAS;
ctx.clearRect(0, 0, this._CANVAS.width, this._CANVAS.height);
ctx.fillStyle = "#ff0000";
img.onload = (() => {
img.width = img.width;
img.height = img.height;
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
ctx.lineWidth = 8;
ctx.strokeStyle = "#FF0000";
ctx.strokeRect(100, 100, 400, 400);
ctx.scale(0.5, 0.5); // this does nothing
});
img.src = (<any>window).Ionic.WebView.convertFileSrc(path);
This draws the photo then the rectangle onto the canvas, however, the resulting image is too large to fit onto the screen, so I need to scale the canvas after all drawing is complete. I tried this with ctx.scale but the canvas remains the same size regardless of which values I specify.
You cannot draw straight onto a photo, but what you can do is create an offscreen canvas that is the same size as the photo, draw the photo to it, and then draw your shapes on top.
The result can then be drawn to your main canvas e.g.
// Empty image for example purposes
const img = new Image(100, 100);
// Creating a canvas for example purposes
const mainCanvas = document.createElement('canvas');
const mainCtx = mainCanvas.getContext('2d');
// Create an offscreen buffer
const bufferCanvas = document.createElement('canvas');
const bufferCtx = bufferCanvas.getContext('2d');
// Scale the buffer canvas to match our image
bufferCanvas.width = img.width;
bufferCanvas.height = img.height;
if (bufferCtx && mainCtx) {
// Draw image to canvas
bufferCtx.drawImage(img, 0, 0);
// Draw a rectangle in the center
bufferCtx.fillRect(img.width / 2 - 5, img.height / 2 - 5, 10, 10);
// Draw the buffer to the main canvas
mainCtx.drawImage(bufferCanvas, 0, 0);
}
I'm trying to have a page where users can customize a canvas and then email the finished project to themselves. I set the background of the canvas using the following javascript:
function setbackground1() {
document.getElementById('myCanvas').setAttribute("class",
"background1");
}
function setbackground2() {
document.getElementById('myCanvas').setAttribute("class",
"background2");
}
and included a form on the page to populate the rest of the canvas. I have tried various ways of including canvas.toDataURL() in order to save the canvas as an image that can later be emailed to them however the background image is not part of the saved image. (similar problem to Canvas to Save Image and Email but my text saves not my images)
I've been trying variations of this but it's not working for me.
function setbackground11() {
var img = new Image();
img.src = 'background1.jpg';
img.onload = function () {
ctx.fillRect( 0, 0, canvas.width, canvas.height )
}
}
I believe that I somehow have to reference myCanvas id as well
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');`
CSS styles aren't part of the canvas image. For a solid color:
ctx.fillStyle = 'green'
ctx.fillRect( 0, 0, canvas.width, canvas.height )
For an image:
var img = new Image();
img.src = 'background1.jpg';
img.onload = function () {
ctx.drawImage( img, 0, 0, canvas.width, canvas.height )
// do the rest of your drawing over the background
}
The title is poorly worded but there's no way to concisely describe the problem. I'm drawing images to the 2D context of a dynamically created canvas. The data of the context is then saved to an image via toDataURL, which is then draw on every frame. The code below is condensed, I will be drawing multiple images to the context, not just one; which is why I'm saving to an image. I will only draw part of the image at once but the image remains constant so I thought this was the best method, if there are alternatives I will happily accept those as answers.
In short: many images drawn on an image. Part of the image draw each frame.
The code below works:
var picture = new Image();
picture.src = "images/tilesheet.png";
var canvas = document.getElementById("background");
var context = canvas.getContext("2d");
function generate(){
var ctx = document.createElement("canvas").getContext("2d");
ctx.canvas.width = canvas.width;
ctx.canvas.height = canvas.height;
ctx.fillStyle = "red";
ctx.rect (0, 0, 40, 40);
ctx.fill();
ctx.drawImage(picture,0,0);
image = new Image();
image.src = ctx.canvas.toDataURL("image/png");
}
function draw(){
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(image, 0,0,100,100,0,0,100,100);
}
function play(){
generate();
setInterval(function(){draw();}, 0.0333);
}
window.onload = function(){
if(picture.complete)play();
else picture.onload = play;
}
<canvas id="background"></canvas>
However this doesn't:
window.Game = {};
canvas = document.getElementById("background");
var tilesheet = new Image();
tilesheet.src = "images/tilesheet.png";
(function(){
function Map(){
this.width = 2736;
this.height = 2736;
this.image = null;
}
Map.prototype.generate = function(){
var ctx = document.createElement("canvas").getContext("2d");
ctx.canvas.width = this.width;
ctx.canvas.height = this.height;
ctx.fillStyle = "red";
ctx.rect (0, 0, 40, 40);
ctx.fill();
ctx.drawImage(tilesheet,0,0);
this.image = new Image();
this.image.setAttribute('crossOrigin', 'anonymous');
this.image.src = ctx.canvas.toDataURL("image/png");
}
Map.prototype.draw = function(context){
context.drawImage(this.image, 0,0, context.canvas.height, context.canvas.height, 0, 0, context.canvas.height, context.canvas.height);
}
Game.Map = Map;
})();
(function(){
var room = new Game.Map();
room.generate();
var draw = function(){
canvas.getContext("2d").clearRect(0, 0, canvas.width, canvas.height);
room.draw(canvas.getContext("2d"));
}
Game.play = function(){setInterval(function(){draw();}, 0.0333);}
})();
window.onload = function(){
if(tilesheet.complete)Game.play();
else tilesheet.onload = Game.play;
}
<canvas id="background"></canvas>
It seems therefore, that the problem is lying in the fact that I'm using function objects but I'm not sure. What am I doing wrong? There are no errors in the debug console.
Those two have different execution order.
First one:
...
Attach image.onload
Call generate()
...
Second one:
...
Call generate()
Attach image.onload
...
That's why it's not working - generate() expects image to be loaded, however second case order doesn't guarantees it.
Instead of
...
room.generate();
...
Game.play = function(){setInterval(function(){draw();}, 0.0333);}
do this
...
Game.play = function(){
room.generate();
setInterval(function(){draw();}, 0.0333);
}
This question already has an answer here:
Canvas image crossplatform insecure error
(1 answer)
Closed 7 years ago.
When trying to draw an image onto a canvas, and then saving the canvas to an image, I get the following error:
Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported
var picture = new Image();
picture.src = "https://upload.wikimedia.org/wikipedia/commons/thumb/8/85/Smiley.svg/800px-Smiley.svg.png";
var canvas = document.getElementById("background");
var context = canvas.getContext("2d");
function generate(){
var ctx = document.createElement("canvas").getContext("2d");
ctx.canvas.width = canvas.width;
ctx.canvas.height = canvas.height;
ctx.fillStyle = "red";
ctx.rect (0, 0, 40, 40);
ctx.fill();
ctx.drawImage(picture,0,0);
image = new Image();
image.setAttribute('crossOrigin', 'anonymous');
image.src = ctx.canvas.toDataURL("image/png");
}
function draw(){
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(image, 0,0,100,100,0,0,100,100);
}
function play(){
generate();
setInterval(function(){draw();}, 0.0333);
}
window.onload = function(){
if(picture.complete)play();
else picture.onload = play;
}
<canvas id="background" width=500 height=500></canvas>
I know it's to do with drawing the image on the canvas because when that line is removed everything's okay and you can see the red box:
var picture = new Image();
picture.src = "https://upload.wikimedia.org/wikipedia/commons/thumb/8/85/Smiley.svg/800px-Smiley.svg.png";
var canvas = document.getElementById("background");
var context = canvas.getContext("2d");
function generate(){
var ctx = document.createElement("canvas").getContext("2d");
ctx.canvas.width = canvas.width;
ctx.canvas.height = canvas.height;
ctx.fillStyle = "red";
ctx.rect (0, 0, 40, 40);
ctx.fill();
image = new Image();
image.setAttribute('crossOrigin', 'anonymous');
image.src = ctx.canvas.toDataURL("image/png");
}
function draw(){
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(image, 0,0,100,100,0,0,100,100);
}
function play(){
generate();
setInterval(function(){draw();}, 0.0333);
}
window.onload = function(){
if(picture.complete)play();
else picture.onload = play;
}
<canvas id="background" width=500 height=500></canvas>
So it's drawImage that causes this to fail.
I've read other questions and the solutions were "just add image.setAttribute('crossOrigin', 'anonymous');" (which I've done) or to put them in the same directory (I tried this by placing both files on desktop) but neither seemed to solve it for me.
Is there a fix or an alternative method? All I want to do is draw multiple images onto one image. (The red box was just for show.)
I tried this by placing both files on desktop
No. You need a web server and to open your files in http:// (or https://) for them to be considered of the same origin. When you open your files in file://, they're not considered of the same origin, even if you serve them from the same directory.
I am trying to blank canvas when there is image already in it.
I want to remove old image and load new image that I am getting from var getfrontimage.
But It failed me.
$('#fittocanvasfront').click(function () {
var canvas = document.getElementById("canvas-front");
var c = canvas.getContext("2d");
var getfrontimage = $('#image-tocanvaschangefront').attr('src');
var img = new resize(getfrontimage);
function resize(src) {
console.log('blank canvas');
canvas.width = canvas.width;
var image = new Image();
image.src = getfrontimage;
image.width = canvas.width;
image.height = canvas.height;
image.onload = function () {
// clearing canvas
c.clearRect(0, 0, canvas.width, canvas.height);
//loading image
c.drawImage(image, 0, 0);
//creating a hole in canvas
var centerX = canvas.width / 2;
var centerY = canvas.offsetTop;
var radius = 30;
c.beginPath();
c.arc(centerX, centerY, radius, 0, 2 * Math.PI, true);
c.fillStyle = 'black';
c.fill();
}
}
});
Into the script-
I have image in <img> tag-
var getfrontimage = $('#image-tocanvaschangefront').attr('src');
this above image is what i will be using after clearing canvas.
So I tried doing canvas empty as below when image is being loaded-
c.clearRect(0, 0, canvas.width, canvas.height);
But this didn't work, I tried doing canvas empty on click-
$('#fittocanvasfront').click(function () {
var canvas = document.getElementById("canvas-front");
var c = canvas.getContext("2d");
c.clearRect(0, 0, canvas.width, canvas.height);
});
How do I empty this canvas with existing image in it.
What you are saying is not true. You can clear of any image using clearRect. Please see fiddle with your code where image's cleared on click.
$("#canvas-front").click(function(){
c.clearRect(0, 0, canvas.width, canvas.height);
});
Hard to say what you're doing wrong, since you didn't provide the full code, use the code I provided in fiddle and all should be fine.