Pixi.js sprite not loading - javascript

<!DOCTYPE HTML>
<html>
<head>
<title>Test</title>
<style>
body {
margin: 0;
padding: 0;
background-color: #000000;
overflow: hidden;
}
</style>
<script src="http://www.goodboydigital.com/pixijs/examples/1/pixi.js"></script>
</head>
<body>
<script>
// create an new instance of a pixi stage
var stage = new PIXI.Stage(0x66FF99);
// create a renderer instance
var renderer = PIXI.autoDetectRenderer(window.innerWidth, window.innerHeight);
// add the renderer view element to the DOM
document.body.appendChild(renderer.view);
requestAnimFrame( animate );
// create a texture from an image path
var texture = PIXI.Texture.fromImage("https://dl.dropboxusercontent.com/s/en13743nxusaozy/player.PNG?dl=1&token_hash=AAFVxLm8fEjk3xxPad-kAZ98LJqLoZpdFy9fQtGrIfXL-A");
// create a new Sprite using the texture
var player = new PIXI.Sprite(texture);
// center the sprites anchor point
player.anchor.x = 0.5;
player.anchor.y = 0.5;
// move the sprite t the center of the screen
player.position.x = 200;
player.position.y = 150;
stage.addChild(player);
function animate() {
requestAnimFrame( animate );
//rotate player
player.rotation += 0.1;
// render the stage
renderer.render(stage);
}
</script>
</body>
</html>
This is my code (from the pixijs example, Loaiding the bunny), for some reason I can't seem to get the sprite to load... Can someone take a look at the code and help?
When I put in the right link (the stage rendering turns black). When I put in the wrong link to the sprite, then the stage renders fine but there is no sprite.

var texture = PIXI.Texture.fromImage("https://dl.dropboxusercontent.com/s....");
With the above code, a cross domain request is created for the Sprite texture to load. This is usually not allowed (as in Dropbox case).
In order to see the sprite you will have to copy the file to the local web server or allow Cross domain requests on the other server (https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS)
//local image instead of cross domain
var texture = PIXI.Texture.fromImage("img/player.PNG");

Related

Trouble rendering a 2D SVG in Three.js & WebGL

I have a ThreeJS Scene (below, or here on CodePen) with some objects in it - one is a Mesh object of a cat, one is a cube, and now, I'm trying to render a 2D SVG illustration I made. I want to put the SVG illustration in the scene in between the cat image and the cube, displayed the same way the cat image appears (upright, and 2D).
It has taken me days to figure out how to render my own SVG, I find the documentation and examples on ThreeJs.org for SVGRenderer and SVGLoader extremely cumbersome and hard to pick apply to my own image (I'm a novice). The closest I've come to rendering my SVG is using the code from this SO thread that uses a LegacySVG Loader. Problem is, I'm completely lost on how to render this code onto a canvas versus a DOM, and it appears this LegacySVG Loader was a solution to a bug which makes it extremely hard to find resources.
So, essentially, I have rendered an SVG in an individual CodePen using the above resources and now I am lost on how to render it onto the same scene as my cube and cat image. Is it possible to use LegacySVG to render onto a canvas? Or, is there a simpler way to get my SVG onto the same canvas as the other objects?
let renderer;
let camera;
//let controls;
let scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(54, window.innerWidth / window.innerHeight, 0.1, 1000);
renderer = new THREE.WebGLRenderer({
antialias: true,
canvas: document.getElementById("viewport")
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(new THREE.Color(0xfefefe));
// document.body.appendChild(renderer.domElement);
camera.position.x = 1;
camera.position.y = 1;
camera.position.z = 15;
let light = new THREE.AmbientLight(0xFFFFFF);
scene.add(light);
let gridHelper = new THREE.GridHelper(10, 10);
scene.add(gridHelper);
// example code
const geometry1 = new THREE.BoxGeometry(1, 1, 1);
const material1 = new THREE.MeshStandardMaterial({
color: 0xff0000
});
const topBox = new THREE.Mesh(geometry1, material1);
scene.add(topBox);
var loader = new THREE.TextureLoader();
// Load an image file into a custom material
var material = new THREE.MeshLambertMaterial({
map: loader.load('https://images.unsplash.com/photo-1518791841217-8f162f1e1131?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2850&q=80')
});
// create a plane geometry for the image with a width of 10
// and a height that preserves the image's aspect ratio
var geometry = new THREE.PlaneGeometry(2, 1.5);
// combine our image geometry and material into a mesh
var mesh = new THREE.Mesh(geometry, material);
// set the position of the image mesh in the x,y,z dimensions
mesh.position.set(0,0,5);
// add the image to the scene
scene.add(mesh);
let animate = function() {
requestAnimationFrame(animate);
//controls.update();
renderer.render(scene, camera);
};
//////////////////
animate();
function updateCamera(ev) {
camera.position.z = 15 - window.scrollY / 250.0;
}
window.addEventListener("scroll", updateCamera);
body {
overflow-x: hidden;
overflow-y: scroll;
padding: 0;
margin: 0;
}
canvas {
position: fixed;
height: 100vh;
}
#threeD {
position: fixed;
margin: 0;
padding: 0;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
.page-wrapper {
padding: 0px;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 4000vh;
}
#container {
height: 500vh;
position: fixed;
}
<html>
<script src="https://raw.githubusercontent.com/mrdoob/three.js/master/src/loaders/LoadingManager.js"></script>
<script src="https://unpkg.com/three#0.102.1/build/three.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/r68/examples/js/loaders/SVGLoader.js"></script>
<script src="https://raw.githubusercontent.com/mrdoob/three.js/master/examples/js/renderers/SVGRenderer.js"></script>
<link rel="stylesheet" type="text/css" href="index1.css" />
<body>
<canvas id="viewport"></canvas>
<div class="page-wrapper" >
<h1> scroll! </h1>
</div>
</body>
<script src="index1.js"></script>
</html>
There are a few things you need to keep in mind.
SVGRenderer does not render the same things as WebGLRenderer.
a. SVGRenderer takes items inside an <svg> element and applies transformations to its internal <path>, <circle>, <rect>, etc, elements. You can see the svg_sandbox example. All SVG elements are 2D, but can give the impression of being 3D when rotated.
b. WebGLRenderer draws onto a <canvas> element, and can render all kinds of true 3D geometry. If you want to draw an SVG in WebGL, you'll need to first convert the SVG file into a geometry that WebGL can understand by using THREE.SVGLoader. You can see how that's done in the webgl_loader_svg example, (the source code is available by clicking on the <> button on the bottom right).
You cannot have <svg> elements co-existing in the same 3D space as WebGL elements in the <canvas>. If you want to add cubes and planes with cat images to the same space, I recommend you use the WebGLRenderer approach.
I noticed in your code snippet that you're using files from many different sources, and all kinds of Three.js revisions. Some files are r102.1, some are r68, and some are the latest, which is r113. You should stick to one revision to avoid conflicts when trying to get older files to work with newer ones. For example:
https://raw.githubusercontent.com/mrdoob/three.js/r113/build/three.min.js
https://raw.githubusercontent.com/mrdoob/three.js/r113/examples/js/loaders/SVGLoader.js

Pixi.js renderer from p5.js canvas

I've been trying to write a script in Pixi that uses the canvas from a p5.js program as the entire "view" to apply a displacement filter on. I've already achieved this with a single image added as a sprite (see below), but I can't figure out how to interface with the output of p5.js and use it as a view with Pixi's autoDetectRenderer(). I've used p5's .parent() function to attach the canvas to a specific element but that doesn't seem to help. Ideally this would all end up existing in my #main-container div.
The next task would be to make sure this feed is coming in live, so animating elements from the p5.js program are constantly fed into Pixi and filtered.
Any help/pointers would be greatly appreciated!
HTML:
<!DOCTYPE html>
<html>
<head>
<title>pixi.js + p5.js displacement filter</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="https://cdn.rawgit.com/GoodBoyDigital/pixi.js/v1.6.1/bin/pixi.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.15/p5.min.js"></script>
<style>
#main-container {
position: relative;
width: 300px;
height: 300px;
border: 1px solid red;
}
</style>
</head>
<body>
<div id="main-container"></div>
<script type="text/javascript" src="js/program.js"></script>
</body>
</html>
program.js:
// p5.js program
var theCanvas, width, height;
function setup() {
width = document.getElementById('main-container').offsetWidth;
height = document.getElementById('main-container').offsetHeight;
theCanvas = createCanvas(width, height);
rectMode(CENTER);
}
function draw() {
background(0, 0, 255);
translate(width/2, height/2);
rotate(frameCount*0.01);
fill(0, 255, 0);
rect(0, 0, 100, 100);
}
// -_-_-_-_-_-_-_-_-_-_-_-_
// pixi.js
// Renderer
var renderer = PIXI.autoDetectRenderer(width, height);
document.body.appendChild(renderer.view);
// Stage
var stage = new PIXI.Stage(0xd92256);
// Container
var container = new PIXI.DisplayObjectContainer();
stage.addChild(container);
// Background
var bg = PIXI.Sprite.fromImage("https://i.imgur.com/3q3kNGh.png?1");
container.addChild(bg);
// Filter
var displacementTexture = PIXI.Texture.fromImage("http://i.imgur.com/2yYayZk.png");
var displacementFilter = new PIXI.DisplacementFilter(displacementTexture);
// Apply it
container.filters = [displacementFilter];
// Animate
requestAnimFrame(animate);
function animate() {
var offset = 1;
displacementFilter.offset.x += offset;
displacementFilter.offset.y += offset;
renderer.render(stage);
requestAnimFrame(animate);
}
Thank you!
I think the best best thing to do would be to take different approach to the problem, trying to connect P5 and Pixi is a lot work. I have tried using both libraries before and it went off the rails fast. What you are trying to do can be done with P5 or Pixi alone. The P5 only approach is what I know best so I will walk you though it.
The way that Pixi makes it filters is with webGL shaders, they are small programs the run on the GPU to manipulate images. They are written in a C like language called glsl. P5 has support for webGL shaders (filters) and so, we write our own displacement shader. I am not going to get into the glsl part here but I have made a demo with lots of comments here.
The first part of a shader is loading in the glsl code. Always do this in preload. As an alternative you can use with createShader and grave strings.
let displacementShader;
function preload() {
displacementShader = loadShader("displacement.vert", "displacement.frag");
}
Next you create a WEBGL mode canvas, this is not like a normal canvas and is for 3d graphics and shaders. You still need somewhere for your 2d graphics so make a buffer to draw 2d graphics too.
let buffer;
function setup(){
createCanvas(windowWidth, windowHeight, WEBGL);
buffer = createGraphics(windowWidth, windowHeight);
}
Now that everything is set up, all you need to do is run the shader.
function draw(){
buffer.circle(100, 100, 50, 50) // draw stuff to the buffer
shader(displacementShader);
// pass variables into the shader, it will need to buffer to distort it
displacementShader.setUniform("buffer", buffer);
rect(0, 0, width, height); // some geometry for the shader to draw on too
}
If you want to look at some examples of shader other that my demo there is a lovely Github repo for that. In my demo I also

How do I get pixi to expand my canvas and zoom in?

I'm making a game that uses pixi and it renders on a canvas that's 640x480 pixels. As you can imagine, this is very small when viewed on a PC. I'd like to accomplish this:
I want to increase the size of the canvas so it fills up the whole screen
I want to zoom in on the content so that it fills up as much as possible without changing its aspect ratio
I'd like to center the canvas if there's left over space from the previous step
When I google for how to do this in pixi, I can find each of these individually. But I'd like to have the information on how to do this all in one place and on stackoverflow, because you usually want to do all of these things together.
I modified the source code in this example made by the creator: http://www.goodboydigital.com/pixi-js-tutorial-getting-started/ (source download)
Here's what I came up with:
<!DOCTYPE HTML>
<html>
<head>
<title>pixi.js example 1</title>
<style>
body {
margin: 0;
padding: 0;
background-color: #000000;
}
</style>
<script src="pixi.js"></script>
</head>
<body>
<script>
// create an new instance of a pixi stage
var stage = new PIXI.Stage(0x66FF99);
// create a renderer instance
var renderer = PIXI.autoDetectRenderer(400, 300);
renderer.resize(800, 600);
// add the renderer view element to the DOM
document.body.appendChild(renderer.view);
requestAnimFrame( animate );
// create a texture from an image path
var texture = PIXI.Texture.fromImage("bunny.png");
// create a new Sprite using the texture
var bunny = new PIXI.Sprite(texture);
// center the sprites anchor point
bunny.anchor.x = 0.5;
bunny.anchor.y = 0.5;
// move the sprite t the center of the screen
bunny.position.x = 200;
bunny.position.y = 150;
var container = new PIXI.DisplayObjectContainer();
container.scale.x = 2;
container.scale.y = 2;
container.addChild(bunny);
stage.addChild(container);
function animate() {
requestAnimFrame( animate );
// just for fun, lets rotate mr rabbit a little
bunny.rotation += 0.1;
// render the stage
renderer.render(stage);
}
</script>
</body>
</html>
Now the one thing I didn't do is center it. I see two potential ways to do this. I could use CSS to center the canvas (what I'll probably use), or I could do this in code by adding another outer display object to the stage that centers container.

How can i improve the performance of drawing an animation path?

I drew a rectangle with kinetic.js and animating it in a circular path. In each animation frame i reduce it's radius, and i draw animating path of this object by kineticJS Line. But This Kinetics animation loop develops an undesirable pausing "stagger". This stagger is small in Chrome, noticeable in IE and horrible in FireFox. This seems to be due to the Kinetic.Line being unable to smoothly add + draw thousands of changing points of data. How can make this animation flawless, smooth. It would be great help if you give me the link of a jsfiddle. Bunches of thanks in advance.
CODES:
var R= 80;
$(document).ready(function(){
var stage= new Kinetic.Stage({
container: 'container',
width:500,
height:500
});
var layer = new Kinetic.Layer();
var line = new Kinetic.Line({
points:[0,0,0,0],
stroke:'blue',
strokeWidth:2
});
var rect = new Kinetic.Rect({
x:10,
y:10,
width:10,
height: 10,
fill:'black',
stroke:'red'
});
layer.add(rect);
layer.add(line);
stage.add(layer);
var centerX = stage.width()/2;
var points=[];
var anim = new Kinetic.Animation(
function(f){
var cX= stage.width()/2;
var cY= stage.height()/2;
R=R-1/100;
var X = cX + R*Math.cos(f.time/1000);
var Y = cY+ R*Math.sin(f.time/1000);
points.push(X,Y);
line.setPoints(points);
rect.setX(X);
rect.setY(Y);
}
,layer);
anim.start();
});
JSFIDDLE: http://jsfiddle.net/tanvirgeek/n8z8N/7/
Thanks In advance.
As you’ve discovered, updating and drawing a Kinetic.Line containing thousands of line segments causes a noticable lag.
One Kinetic trick that I rarely seen used is useful to create a lag-free animation of thousands of line segments.
First, draw your line segments on an off-screen html5 canvas. When a new line segment is needed, just add that segment to all the pre-existing segments. This is very efficient because only the last line segment needs to be drawn.
You can use a Kinetic.Image to display the offscreen html5 canvas on the screen.
The trick is to set the Kinetic.Image image-source to the html canvas: myKineticImage.setImage(myOffscreenCanvas). This works because “behind the scenes” the Kinetic.Image is using context.drawImage to display its image. Since context.drawImage can also accept another canvas as its image-source, you can efficiently display the current offscreen canvas drawings.
A Demo: http://jsfiddle.net/m1erickson/rYC96/
And example code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Prototype</title>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v5.0.1.min.js"></script>
<style>
body{padding:20px;}
#container{
border:solid 1px #ccc;
margin-top: 10px;
width:350px;
height:350px;
}
</style>
<script>
$(function(){
var stage = new Kinetic.Stage({
container: 'container',
width: 350,
height: 350
});
var layer = new Kinetic.Layer();
stage.add(layer);
// variables used to set the stage and animate
var rectSize=15;
var cx=stage.getWidth()/2;
var cy=stage.getHeight()/2;
var R=100;
var A=0;
var deltaA=Math.PI/180;
var lastX=cx+R*Math.cos(A);
var lastY=cy+R*Math.sin(A);
// the html canvas incrementally draws the line segments
// which are in turn displayed as a Kinetic.Image (called line)
var canvas=document.createElement("canvas");
var ctx=canvas.getContext("2d");
canvas.width=stage.getWidth();
canvas.height=stage.getHeight();
ctx.strokeStyle="blue";
ctx.lineWidth=2;
// this Kinetic.Image exactly displays the current html canvas drawings
// (this trick cures the lags)
var line=new Kinetic.Image({
x:0,
y:0,
width:canvas.width,
height:canvas.height,
image:canvas
});
layer.add(line);
// the rotating Kinetic.Rectangle
var rect = new Kinetic.Rect({
x:lastX,
y:lastY,
width:rectSize,
height:rectSize,
fill:'black',
stroke:'red'
});
layer.add(rect);
// use requestAnimationFrame (RAF) to drive the animation
// RAF efficiently schedules animation frames with display
function animate(){
// stop animating when rect reaches center
if(R<=rectSize/2){return;}
// schedule another animation frame even before this one is done
requestAnimationFrame(animate);
// calc the new XY position
R=R-.01;
A+=deltaA;
var X=cx+R*Math.cos(A);
var Y=cy+R*Math.sin(A);
// animate the rect and line to their next position
// draw just the latest line segment to the canvas
// (all the previous line segments are still there--no need to redraw them)
ctx.beginPath();
ctx.moveTo(lastX,lastY);
ctx.lineTo(X,Y);
ctx.stroke();
// set lastXY for next frame
lastX=X;
lastY=Y;
// update the rect position
rect.setX(X);
rect.setY(Y);
// draw the changed line-image and rect to the kinetic layer
layer.draw();
}
// start animating!
animate();
}); // end $(function(){});
</script>
</head>
<body>
<div id="container"></div>
</body>
</html>

HTML5 Canvas: How to make a loading spinner by rotating the image in degrees?

I am making a loading spinner with html5 canvas. I have my graphic on the canvas but when i rotate it the image rotates off the canvas. How do I tell it to spin the graphic on its center point?
<!DOCTYPE html>
<html>
<head>
<title>Canvas test</title>
<script type="text/javascript">
window.onload = function() {
var drawingCanvas = document.getElementById('myDrawing');
// Check the element is in the DOM and the browser supports canvas
if(drawingCanvas && drawingCanvas.getContext) {
// Initaliase a 2-dimensional drawing context
var context = drawingCanvas.getContext('2d');
//Load the image object in JS, then apply to canvas onload
var myImage = new Image();
myImage.onload = function() {
context.drawImage(myImage, 0, 0, 27, 27);
}
myImage.src = "img/loading.png";
context.rotate(45);
}
}
</script>
</head>
<body>
<canvas id="myDrawing" width="27" height="27">
</canvas>
</body>
</html>
Here is the complete working example:)
<!DOCTYPE html>
<html>
<head>
<title>Canvas Cog</title>
<script type="text/javascript">
var cog = new Image();
function init() {
cog.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABsAAAAbCAYAAACN1PRVAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABK1JREFUeNqMVt1ZGzkUvVfS4IW1l8GO82w6IBXE7mCpAFMB+Pt4Z6iApALcAe4AU0HoAJfg7BPYHinnXmmciX+y0YdmJHnQ0bk/R5cvh5cUyFPwRD4EChgEvGWMB36R3+JaiTkmD5gOs8yNb25uLlerFf1pM2yIGA82TEY7xow1oj4GBU6S6yywPNG4JwDH+XGv0Whs7ndN8n97mmPsLCSYgy7ImPQE/pFDyAF+7L0fgTNFUDBcLal90taD1doQ/T6NT9DnW8zkT+jJuQVYukG3hifCVk/L3JOxMBa8VVlSp9MhHKLaB+zpNo1fdgEpmByuMqUAV5viOQLwXNax9KBAFNEEpN1pUwnQmvl6aTza6zNjrCKaymeyOdYAMgfg18iG4T/qw+AC94zvpzDjcwqOXo3VGH26H0xMZ7jPxgT0R2zUi4BYt6bAfEbJvJFZKA4ODgZ5nhcJLE9mk35X21vWC/TXKmiwr2xszoQd/PQv3t/QCzY2twpqBpb5FKOp+hCgzWaTWq0W1Xx0ij5An9WC5VtiLMwvNBrVaSGMvQk5jHQVPN7sb0HzAtE+QJrNgrcUNEARieWCut0ugR0tl8sKcJ5Ahc3jRviPK8ZGTaaBwGKyT+gTiwM4a3Jrba6MbeVXo5F4kp9shn29ndUYC9vLirGDXzRhrYhD8DME5Hkg22df5rDYS/RXmVIsaP/Q/SXs600YnifTjbeSWliEdTYb3QyTqYfdDKTL4B1KS6tVqf6SgGq3P9BvZGpvNIrPCgVKZlGlCDQDxJiCjVppCab05DJHzb+b1Gm36X80cVjLuzozexs0f6IgRkA5XRhzIixRL1+IzhwdHVHrn1Y9oXe1i10aKT6bGGhg1CKK+cT0zCGCs0oXTIogybJMw/779//o48duMvnO9rzLn+Kz8wgS5Shqo4njpCoOQA5Ajb8adHh4SMvVghaLhYb/HsBip88krNVISSEigOlhjmi0LziNhr6wOsgO9C1339vbGznnNAU2AM9Svk235cqKieKGkldAf7DGvTrjnjJnzyQoMu0ZTuZgUqvmlYR+f39XIE4uqCX1E/rDZpCYmKwOOmivAfYK9KF1AM7EdG4uAMLAOjmQideQXOJQkyUisqYiFRhtSFbxCxj8do0T30dmTvLhC+an0MZZVBHX09tBTG4qFigZEJEChjTIEwtRik81Qa7uOQU0IrYAe7FRjqYw6SlYjgAyN1GmHsFIGPfVnxzFuFITKEkfYK+oWZ5qKlIkcZ7UE92oXBmeIgIxtAO5UtSHqo9uiLW+sme5ejSIRASeAFR4LYy8MMzL1aq3EYWzJF28BgMEzGYpBkrMKelgl+P6uTcVY8NjLYyYPwMTCcufSaouH6al9xNJcjC82vDb9uVZKbrWIumNO+waVsu1TCC+Wxcg6xaSpsZSYM2wLO9/U8qZWH+wztQnsfAxV/E3MIKZVf1FsmJVV8mamhEmxZ0X7sSsABsGv1tZJGejmptU7FBUDYzPAXQBwFEEl+9+stFEroJEci2ELwIMmZuWoSTE9DYYcWVCjlJrZWMpeBhlAEqBiulPE84S3ixU5gSTwGGOdyEVNJXxA8nPevshwABHktBS1YoQ+QAAAABJRU5ErkJggg=='; // Set source path
setInterval(draw,10);
}
var rotation = 0;
function draw(){
var ctx = document.getElementById('myCanvas').getContext('2d');
ctx.globalCompositeOperation = 'destination-over';
ctx.save();
ctx.clearRect(0,0,27,27);
ctx.translate(13.5,13.5); // to get it in the origin
rotation +=1;
ctx.rotate(rotation*Math.PI/64); //rotate in origin
ctx.translate(-13.5,-13.5); //put it back
ctx.drawImage(cog,0,0);
ctx.restore();
}
init();
</script>
</head>
<body>
<canvas width="27" height="27" id="myCanvas"></canvas>
</body>
</html>
rotate turns the canvas(?) around your current position, which is 0, 0 to start. you need to "move" to your desired center point, which you can accomplish with
context.translate(x,y);
after you move your reference point, you want to center your image over that point. you can do this by calling
context.drawImage(myImage, -(27/2), -(27/2), 27, 27);
this tells the browser to start drawing the image from above and to the left of your current reference point, by have the size of the image, whereas before you were starting at your reference point and drawing entirely below and to the right (all directions relative to the rotation of the canvas).
since your canvas is the size of your image, your call to translate will use the same measurement, (27/2), for x and y coordinates.
so, to put it all together
// initialization:
context.translate(27/2, 27/2);
// onload:
context.rotate(Math.PI * 45 / 180);
context.drawImage(myImage, -(27/2), -(27/2), 27, 27);
edit: also, rotation units are radians, so you'll need to translate degrees to radians in your code.
edits for rearranging stuff.
For anyone else looking into something like this, you might want to look at this script which does exactly what was originally being requested:
http://projects.nickstakenburg.com/spinners/
You can find the github source here:
https://github.com/staaky/spinners
He uses rotate, while keeping a cache of rectangles which slowly fade out, the older they are.
I find another way to do html loading spinner. You can use sprite sheet animation. This approach can work both by html5 canvas or normal html/javascript/css. Here is a simple way implemented by html/javascript/css.
It uses sprite sheet image as background. It create a Javascript timer to change the background image position to control the sprite sheet animation. The example code is below. You can also check the result here: http://jmsliu.com/1769/html-ajax-loading-spinner.html
<html>
<head><title></title></head>
<body>
<div class="spinner-bg">
<div id="spinner"></div>
</div>
<style>
.spinner-bg
{
width:44px;
height:41px;
background: #000000;
}
#spinner
{
width: 44px;
height: 41px;
background:url(./preloadericon.png) no-repeat;
}
</style>
<script>
var currentbgx = 0;
var circle = document.getElementById("spinner");
var circleTimer = setInterval(playAnimation, 100);
function playAnimation() {
if (circle != null) {
circle.style.backgroundPosition = currentbgx + "px 0";
}
currentbgx -= 44; //one frame width, there are 5 frame
//start from 0, end at 176, it depends on the png frame length
if (currentbgx < -176) {
currentbgx = 0;
}
}
</script>
</body>

Categories

Resources