Why is this codepen demo not working locally? - javascript

I just stumbled upon a codepen demo http://codepen.io/timohausmann/pen/icCer
Then code works fine in codepen window. When, I copied it in a local HTML file it stopped working.
Here is the code all combined in one .html file
<!DOCTYPE html>
<html>
<head>
<style>
body {
margin: 0;
overflow: hidden;
}
#myCanvas {
display: block;
}
#button {
font-family: "Gill Sans", "Gill Sans MT", Calibri, sans-serif;
position: absolute;
font-size: 1.5em;
text-transform: uppercase;
padding: 7px 20px;
left: 50%;
width: 200px;
margin-left: -100px;
top: 50%;
border-radius: 10px;
color: white;
text-shadow: -1px -1px 1px rgba(0,0,0,0.8);
border: 5px solid transparent;
border-bottom-color: rgba(0,0,0,0.35);
background: hsla(260, 100%, 50%, 1);
cursor: pointer;
animation: pulse 1s infinite alternate;
transition: background 0.4s, border 0.2s, margin 0.2s;
}
#button:hover {
background: hsla(220, 100%, 60%, 1);
margin-top: -1px;
animation: none;
}
#button:active {
border-bottom-width: 0;
margin-top: 5px;
}
#keyframes pulse {
0% {
margin-top: 0px;
}
100% {
margin-top: 6px;
}
}
</style>
</head>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script>
window.requestAnimFrame = (function () {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
Math.randMinMax = function(min, max, round) {
var val = min + (Math.random() * (max - min));
if( round ) val = Math.round( val );
return val;
};
Math.TO_RAD = Math.PI/180;
Math.getAngle = function( x1, y1, x2, y2 ) {
var dx = x1 - x2,
dy = y1 - y2;
return Math.atan2(dy,dx);
};
Math.getDistance = function( x1, y1, x2, y2 ) {
var xs = x2 - x1,
ys = y2 - y1;
xs *= xs;
ys *= ys;
return Math.sqrt( xs + ys );
};
var FX = {};
(function() {
var canvas = document.getElementById('myCanvas'),
ctx = canvas.getContext('2d'),
lastUpdate = new Date(),
mouseUpdate = new Date(),
lastMouse = [],
width, height;
FX.particles = [];
setFullscreen();
document.getElementById('button').addEventListener('mousedown', buttonEffect);
function buttonEffect() {
var button = document.getElementById('button'),
height = button.offsetHeight,
left = button.offsetLeft,
top = button.offsetTop,
width = button.offsetWidth,
x, y, degree;
for(var i=0;i<40;i=i+1) {
if( Math.random() < 0.5 ) {
y = Math.randMinMax(top, top+height);
if( Math.random() < 0.5 ) {
x = left;
degree = Math.randMinMax(-45,45);
} else {
x = left + width;
degree = Math.randMinMax(135,225);
}
} else {
x = Math.randMinMax(left, left+width);
if( Math.random() < 0.5 ) {
y = top;
degree = Math.randMinMax(45,135);
} else {
y = top + height;
degree = Math.randMinMax(-135, -45);
}
}
createParticle({
x: x,
y: y,
degree: degree,
speed: Math.randMinMax(100, 150),
vs: Math.randMinMax(-4,-1)
});
}
}
window.setTimeout(buttonEffect, 100);
loop();
window.addEventListener('resize', setFullscreen );
function createParticle( args ) {
var options = {
x: width/2,
y: height/2,
color: 'hsla('+ Math.randMinMax(160, 290) +', 100%, 50%, '+(Math.random().toFixed(2))+')',
degree: Math.randMinMax(0, 360),
speed: Math.randMinMax(300, 350),
vd: Math.randMinMax(-90,90),
vs: Math.randMinMax(-8,-5)
};
for (key in args) {
options[key] = args[key];
}
FX.particles.push( options );
}
function loop() {
var thisUpdate = new Date(),
delta = (lastUpdate - thisUpdate) / 1000,
amount = FX.particles.length,
size = 2,
i = 0,
p;
ctx.fillStyle = 'rgba(15,15,15,0.25)';
ctx.fillRect(0,0,width,height);
ctx.globalCompositeStyle = 'lighter';
for(;i<amount;i=i+1) {
p = FX.particles[ i ];
p.degree += (p.vd * delta);
p.speed += (p.vs);// * delta);
if( p.speed < 0 ) continue;
p.x += Math.cos(p.degree * Math.TO_RAD) * (p.speed * delta);
p.y += Math.sin(p.degree * Math.TO_RAD) * (p.speed * delta);
ctx.save();
ctx.translate( p.x, p.y );
ctx.rotate( p.degree * Math.TO_RAD );
ctx.fillStyle = p.color;
ctx.fillRect( -size, -size, size*2, size*2 );
ctx.restore();
}
lastUpdate = thisUpdate;
requestAnimFrame( loop );
}
function setFullscreen() {
width = canvas.width = window.innerWidth;
height = canvas.height = window.innerHeight;
};
})();
</script>
<button id="button">click me</button>
<canvas id="myCanvas" width="500" height="500"></canvas>
</body>
</html>
This is code from all three codepen windows put together but it doesn't seem to work?

Add jQuery library
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>

Related

Resizing font on a canvas

I use the wheel of fortune by Roko C. Buljan from here: how to draw a wheel of fortune?
This is my first experience with JS and canvas.
I want to put long sentences in labels, but they go out of bounds.
I've tried using a flexible font, but that doesn't really work and isn't exactly what I need. I need the text inside each block to move to a new line and reduce the font if it goes out of bounds.
Can this be implemented in this code, or would I need to write everything from scratch?
const sectors = [
{color:"#f82", label:"parallellogram into parallellogram"},
{color:"#0bf", label:"10"},
{color:"#fb0", label:"StackStack StackStack"},
{color:"#0fb", label:"50"},
{color:"#b0f", label:"StackStackStackStackStackStack"},
{color:"#f0b", label:"Stack Stack"},
{color:"#bf0", label:"Stack"},
];
const rand = (m, M) => Math.random() * (M - m) + m;
const tot = sectors.length;
const EL_spin = document.querySelector("#spin");
const ctx = document.querySelector("#wheel").getContext('2d');
const dia = ctx.canvas.width;
const rad = dia / 2;
const PI = Math.PI;
const TAU = 2 * PI;
const arc = TAU / sectors.length;
const friction = 0.991; // 0.995=soft, 0.99=mid, 0.98=hard
let angVel = 0; // Angular velocity
let ang = 0; // Angle in radians
const getIndex = () => Math.floor(tot - ang / TAU * tot) % tot;
function drawSector(sector, i) {
const ang = arc * i;
ctx.save();
// COLOR
ctx.beginPath();
ctx.fillStyle = sector.color;
ctx.moveTo(rad, rad);
ctx.arc(rad, rad, rad, ang, ang + arc);
ctx.lineTo(rad, rad);
ctx.fill();
// TEXT
ctx.translate(rad, rad);
ctx.rotate(ang + arc / 2);
ctx.textAlign = "right";
ctx.fillStyle = "#fff";
ctx.font = "bold 14px sans-serif";
ctx.fillText(sector.label, rad - 10, 10);
//
ctx.restore();
};
function rotate() {
const sector = sectors[getIndex()];
ctx.canvas.style.transform = `rotate(${ang - PI / 2}rad)`;
EL_spin.textContent = !angVel ? "SPIN" : sector.label;
EL_spin.style.background = sector.color;
}
function finishedSpinning() { // Called when the wheel stops spinning
const sector = sectors[getIndex()];
alert(sector.label);
}
function frame() {
if (!angVel) return;
const isSpinning = angVel > 0; // Check if the wheel is currently spinning
angVel *= friction; // Decrement velocity by friction
if (angVel < 0.002) angVel = 0; // Bring to stop
ang += angVel; // Update angle
ang %= TAU; // Normalize angle
rotate();
if (isSpinning && angVel === 0) { // If the wheel was spinning, but isn't anymore, it has just stopped
finishedSpinning();
}
}
function engine() {
frame();
requestAnimationFrame(engine)
}
// INIT
sectors.forEach(drawSector);
rotate(); // Initial rotation
engine(); // Start engine
EL_spin.addEventListener("click", () => {
if (!angVel) angVel = rand(0.25, 0.35);
});
#wheelOfFortune {
display: inline-block;
position: relative;
overflow: hidden;
}
#wheel {
display: block;
}
#spin {
font: 1.5em/0 sans-serif;
user-select: none;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 50%;
left: 50%;
width: 30%;
height: 30%;
margin: -15%;
background: #fff;
color: #fff;
box-shadow: 0 0 0 8px currentColor, 0 0px 15px 5px rgba(0, 0, 0, 0.6);
border-radius: 50%;
transition: 0.8s;
}
#spin::after {
content: "";
position: absolute;
top: -17px;
border: 10px solid transparent;
border-bottom-color: currentColor;
border-top: none;
}
<div id="wheelOfFortune">
<canvas id="wheel" width="300" height="300"></canvas>
<div id="spin">SPIN</div>
</div>
That's what I'm trying to do
Solution: HTML5 canvas ctx.fillText won't do line breaks?
New problem - long words as in the first label
Here's what I got, ready for any suggestions for improvement
(mainly the part with text centering - line 89)
It would also be nice to add a shadow to the text to stand out against the background of bright colors
New problem - long words as in the first label
const sectors = [
{ color: "#0fb", label: "Параллелограмм в паралеллограмме" },
{ color: "#0bf", label: "Бесплатная настройка виджета" },
{ color: "#fb0", label: "Два пресета цветов по цене одного" },
{ color: "#0fb", label: "1строчка" },
{ color: "#b0f", label: "Год премиум поддержки в подарок в подарок" },
{ color: "#f0b", label: "Скидка 10% на любой пакет" },
{ color: "#bf0", label: "Виджет 'Juice Contact' в подарок" },
{ color: "#f82", label: "Скидка 5% на любой пакет" },
{ color: "#bf0", label: "" },
];
function printAtWordWrap(context, text, x, y, lineHeight, fitWidth) {
fitWidth = fitWidth || 0;
if (fitWidth <= 0) {
context.fillText(text, x, y);
return;
}
let words = text.split(" ");
let currentLine = 0;
let idx = 1;
while (words.length > 0 && idx <= words.length) {
const str = words.slice(0, idx).join(" ");
const w = context.measureText(str).width;
if (w > fitWidth) {
if (idx == 1) {
idx = 2;
}
context.fillText(
words.slice(0, idx - 1).join(" "),
x,
y + lineHeight * currentLine
);
currentLine++;
words = words.splice(idx - 1);
idx = 1;
} else {
idx++;
}
}
if (idx > 0)
context.fillText(words.join(" "), x, y + lineHeight * currentLine);
}
const rand = (m, M) => Math.random() * (M - m) + m;
const tot = sectors.length;
const EL_spin = document.querySelector("#spin");
const ctx = document.querySelector("#wheel").getContext("2d");
const dia = ctx.canvas.width;
const rad = dia / 2;
const PI = Math.PI;
const TAU = 2 * PI;
const arc = TAU / sectors.length;
const friction = 0.991; // 0.995=soft, 0.99=mid, 0.98=hard
let angVel = 0; // Angular velocity
let ang = 0; // Angle in radians
const getIndex = () => Math.floor(tot - (ang / TAU) * tot) % tot;
// calcFontSize not used
const calcFontSize = () => {
const maxChars = Math.max(...sectors.map((ob) => ob.label.length));
const width = rad * 0.9 - 15;
const w = (width / maxChars) * 1.3;
const h = ((TAU * rad) / tot) * 0.5;
return Math.min(w, h);
};
function drawSector(sector, i) {
const ang = arc * i;
ctx.save();
// COLOR
ctx.beginPath();
ctx.fillStyle = sector.color;
ctx.moveTo(rad, rad);
ctx.arc(rad, rad, rad, ang, ang + arc);
ctx.lineTo(rad, rad);
ctx.fill();
// TEXT
ctx.translate(rad, rad);
ctx.rotate(ang + arc / 2);
ctx.textAlign = "center";
ctx.fillStyle = "#fff";
const fontSize = 15;
ctx.font = `bold ${fontSize}px sans-serif`;
// values for centering text - not ideal for now (need tuning)
const w = ctx.measureText(sector.label).width;
console.log(sector.label, w);
let y;
const lineWidth = 130; // width before line break
switch (true) {
case w < lineWidth:
y = fontSize / 3;
break;
case w >= lineWidth && w < 2 * lineWidth:
y = fontSize / 3 - 10;
break;
case w >= 2 * lineWidth && w < 3 * lineWidth:
y = fontSize / 3 - 20;
break;
case w >= 3 * lineWidth && w < 4 * lineWidth:
y = fontSize / 3 - 30;
break;
case w >= 4 * lineWidth:
y = fontSize / 3 - 40;
break;
default:
y = fontSize / 3;
}
printAtWordWrap(ctx, sector.label, rad * 0.7, y, 21, lineWidth);
ctx.restore();
}
function rotate() {
const sector = sectors[getIndex()];
ctx.canvas.style.transform = `rotate(${ang - PI / 2}rad)`;
EL_spin.textContent = !angVel
? "SPIN"
: ""; /* sector.label instead "" - if u want to display text inside spin element */
EL_spin.style.background = sector.color;
}
function finishedSpinning() {
// Called when the wheel stops spinning
const sector = sectors[getIndex()];
alert(sector.label);
}
function frame() {
if (!angVel) return;
const isSpinning = angVel > 0; // Check if the wheel is currently spinning
angVel *= friction; // Decrement velocity by friction
if (angVel < 0.002) angVel = 0; // Bring to stop
ang += angVel; // Update angle
ang %= TAU; // Normalize angle
rotate();
if (isSpinning && angVel === 0) {
// If the wheel was spinning, but isn't anymore, it has just stopped
finishedSpinning();
}
}
function engine() {
frame();
requestAnimationFrame(engine);
}
// INIT
sectors.forEach(drawSector);
rotate(); // Initial rotation
engine(); // Start engine
EL_spin.addEventListener("click", () => {
if (!angVel) angVel = rand(0.25, 0.35);
});
#wheelOfFortune {
display: inline-block;
position: relative;
overflow: hidden;
}
#wheel {
display: block;
}
#spin {
font: 1.5em/0 sans-serif;
user-select: none;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 50%;
left: 50%;
width: 30%;
height: 30%;
margin: -15%;
background: #fff;
color: #fff;
box-shadow: 0 0 0 8px currentColor, 0 0px 15px 5px rgba(0, 0, 0, 0.6);
border-radius: 50%;
transition: 0.8s;
}
#spin::after {
content: "";
position: absolute;
top: -17px;
border: 10px solid transparent;
border-bottom-color: currentColor;
border-top: none;
}
<body style="background-color: darkcyan">
<div id="wheelOfFortune">
<canvas id="wheel" width="480" height="480"></canvas>
<div id="spin">SPIN</div>
</div>
</body>

Mapping image onto JS cloth and creating a slider

Here is all the code for the website, it has many bugs, like the footer which is stuck in the middle. So the idea is to create 11 different tissues in the format of this image mapped to the JS I have, bit i dont know how to do that.[![sample tissue][1]][1]
I would like to create a slider that functions when you click on the collection number it switchees to the next collection.
Also all the links only take the size and not the column width when hovered.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>$</title>
<link rel="stylesheet" href="normalize.css">
<style type="text/css">
* {
margin: 0;
overflow: hidden;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
font-family: sans-serif;
}
body {
}
#c {
display: block;
margin: 20px auto 0;
}
#info {
position: absolute;
left: -1px;
top: -1px;
width: auto;
max-width: 420px;
height: auto;
background: #f8f8f8;
border-bottom-right-radius: 10px;
border:1px solid #ccc;
}
#top {
background: #fff;
width: 100%;
height: auto;
position: relative;
border-bottom: 1px solid #eee;
}
p {
font-family: Arial, sans-serif;
color: #666;
text-align: justify;
font-size: 16px;
margin: 0px 16px;
}
#github, #twitter {
color:#3377ee;
font-family: Helvetica, Arial, sans-serif;
font-size: 14px;
margin: 0 auto;
text-align: center;
text-decoration:none;
}
.center {
text-align: center;
}
#net {
text-align:center;
white-space:nowrap;
font-size:19px;
background:rgba(0,0,0,0.1);
padding:8px 12px;
border-radius:8px;
display:block;
color:#888;
}
#net > span {
color:#3377ee;
font-family: Helvetica, Arial, sans-serif;
font-size: 14px;
display: block;
margin: 0 auto;
text-align: center;
text-decoration:none;
}
.bull {
opacity: 0.3;
margin: 0 6px;
font-size: 14px;
}
.row {
display: flex;
flex-direction: row;
flex-wrap: wrap;
border-bottom: 1px solid black;
}
.column {
flex-basis: 100%;
border-right: 1px solid black;
}
#media screen and (min-width: 800px) {
.column {
flex: 1;
}
}
#media screen and (min-width: 800px) {
._25 {
flex: 2.5;
}
._55 {
flex: 5.5;
}
._20 {
flex: 2;
}
}
a:link {
text-decoration: none;
}
a:visited {
text-decoration: none;
color: black;
}
a:hover {
text-decoration: none;
color: white;
background: black;}
a:active {
text-decoration: none;
color: white;
background: black;
}
</style>
</head>
<body>
<div class="row">
<div class="column">
Rakṣas Sari collection
</div>
<div class="column">
Concept
</div>
<div class="column">
Process
</div>
</div>
<div class="row">
<div class="column">
Red Collection N°1
</div>
<div class="column">
Collection N°2
</div>
<div class="column">
Collection N°3
</div>
<div class="column">
Collection N°4
</div>
<div class="column">
Collection N°5
</div>
<div class="column">
Collection N°6
</div>
<div class="column">
Collection N°7
</div>
<div class="column">
Collection N°8
</div>
<div class="column">
Collection N°9
</div>
<div class="column">
Collection N°10
</div>
<div class="column">
Collection N°11
</div>
</div>
<div class="row">
<div class="column _25">
Project photoshoot
</div>
<div class="column _55">
<canvas id="c"></canvas>
<div id="top">
<a id="close" href="">Reset tissue</a>
</div>
</div>
<div class="column _20">
Red is a celebratory color. It commemorates a couple’s union. It symbolizes love, sensuality, and passion. That’s why it features prominently in auspicious occasions, such as weddings, festivals, and births. As red also signifies chastity, it is the color of choice for brides.
</div>
</div>
<footer>
<div class="row">
<div class="column">
©Copyright Angelo Barbattini
</div>
<div class="column">
ECAL 2022
</div>
</div>
</footer style="position: fixed;bottom: 0;">
<!--div id="new">
Wobble some <a target="_blank" href="https://codepen.io/dissimulate/details/dJgMaO">jelly</a> <span class="bull">•</span>
Check out my <a target="_blank" href="https://www.instagram.com/abro_oks/">instagram!</a>
</div-->
<script type="text/javascript">
document.getElementById("close").onmousedown = function (e) {
e.preventDefault();
document.getElementById("info").style.display = "none";
return false;
};
// settings
var physics_accuracy = 3,
mouse_influence = 20,
mouse_cut = 5,
gravity = 1200,
cloth_height = 30,
cloth_width = 50,
start_y = 20,
spacing = 7,
tear_distance = 60;
window.requestAnimFrame =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
};
var canvas,
ctx,
cloth,
boundsx,
boundsy,
mouse = {
down: false,
button: 1,
x: 0,
y: 0,
px: 0,
py: 0
};
var Point = function (x, y) {
this.x = x;
this.y = y;
this.px = x;
this.py = y;
this.vx = 0;
this.vy = 0;
this.pin_x = null;
this.pin_y = null;
this.constraints = [];
};
Point.prototype.update = function (delta) {
if (mouse.down) {
var diff_x = this.x - mouse.x,
diff_y = this.y - mouse.y,
dist = Math.sqrt(diff_x * diff_x + diff_y * diff_y);
if (mouse.button == 1) {
if (dist < mouse_influence) {
this.px = this.x - (mouse.x - mouse.px) * 1.8;
this.py = this.y - (mouse.y - mouse.py) * 1.8;
}
} else if (dist < mouse_cut) this.constraints = [];
}
this.add_force(0, gravity);
delta *= delta;
nx = this.x + (this.x - this.px) * 0.99 + (this.vx / 2) * delta;
ny = this.y + (this.y - this.py) * 0.99 + (this.vy / 2) * delta;
this.px = this.x;
this.py = this.y;
this.x = nx;
this.y = ny;
this.vy = this.vx = 0;
};
Point.prototype.draw = function () {
if (!this.constraints.length) return;
var i = this.constraints.length;
while (i--) this.constraints[i].draw();
};
Point.prototype.resolve_constraints = function () {
if (this.pin_x != null && this.pin_y != null) {
this.x = this.pin_x;
this.y = this.pin_y;
return;
}
var i = this.constraints.length;
while (i--) this.constraints[i].resolve();
this.x > boundsx
? (this.x = 2 * boundsx - this.x)
: 1 > this.x && (this.x = 2 - this.x);
this.y < 1
? (this.y = 2 - this.y)
: this.y > boundsy && (this.y = 2 * boundsy - this.y);
};
Point.prototype.attach = function (point) {
this.constraints.push(new Constraint(this, point));
};
Point.prototype.remove_constraint = function (constraint) {
this.constraints.splice(this.constraints.indexOf(constraint), 1);
};
Point.prototype.add_force = function (x, y) {
this.vx += x;
this.vy += y;
var round = 400;
this.vx = ~~(this.vx * round) / round;
this.vy = ~~(this.vy * round) / round;
};
Point.prototype.pin = function (pinx, piny) {
this.pin_x = pinx;
this.pin_y = piny;
};
var Constraint = function (p1, p2) {
this.p1 = p1;
this.p2 = p2;
this.length = spacing;
};
Constraint.prototype.resolve = function () {
var diff_x = this.p1.x - this.p2.x,
diff_y = this.p1.y - this.p2.y,
dist = Math.sqrt(diff_x * diff_x + diff_y * diff_y),
diff = (this.length - dist) / dist;
if (dist > tear_distance) this.p1.remove_constraint(this);
var px = diff_x * diff * 0.5;
var py = diff_y * diff * 0.5;
this.p1.x += px;
this.p1.y += py;
this.p2.x -= px;
this.p2.y -= py;
};
Constraint.prototype.draw = function () {
ctx.moveTo(this.p1.x, this.p1.y);
ctx.lineTo(this.p2.x, this.p2.y);
};
var Cloth = function () {
this.points = [];
var start_x = canvas.width / 2 - (cloth_width * spacing) / 2;
for (var y = 0; y <= cloth_height; y++) {
for (var x = 0; x <= cloth_width; x++) {
var p = new Point(start_x + x * spacing, start_y + y * spacing);
x != 0 && p.attach(this.points[this.points.length - 1]);
y == 0 && p.pin(p.x, p.y);
y != 0 && p.attach(this.points[x + (y - 1) * (cloth_width + 1)]);
this.points.push(p);
}
}
};
Cloth.prototype.update = function () {
var i = physics_accuracy;
while (i--) {
var p = this.points.length;
while (p--) this.points[p].resolve_constraints();
}
i = this.points.length;
while (i--) this.points[i].update(0.016);
};
Cloth.prototype.draw = function () {
ctx.beginPath();
var i = cloth.points.length;
while (i--) cloth.points[i].draw();
ctx.stroke();
};
function update() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
cloth.update();
cloth.draw();
requestAnimFrame(update);
}
function start() {
canvas.onmousedown = function (e) {
mouse.button = e.which;
mouse.px = mouse.x;
mouse.py = mouse.y;
var rect = canvas.getBoundingClientRect();
(mouse.x = e.clientX - rect.left),
(mouse.y = e.clientY - rect.top),
(mouse.down = true);
e.preventDefault();
};
canvas.onmouseup = function (e) {
mouse.down = false;
e.preventDefault();
};
canvas.onmousemove = function (e) {
mouse.px = mouse.x;
mouse.py = mouse.y;
var rect = canvas.getBoundingClientRect();
(mouse.x = e.clientX - rect.left),
(mouse.y = e.clientY - rect.top),
e.preventDefault();
};
canvas.oncontextmenu = function (e) {
e.preventDefault();
};
boundsx = canvas.width - 1;
boundsy = canvas.height - 1;
ctx.strokeStyle = "#888";
cloth = new Cloth();
update();
}
window.onload = function () {
canvas = document.getElementById("c");
ctx = canvas.getContext("2d");
canvas.width = 560;
canvas.height = 350;
start();
};
</script>
</body>
</html>```
[1]: https://i.stack.imgur.com/Celmj.jpg
The questioner is focusing on the problem of getting an actual image to look like material being moved with the wind.
The code presented to do this divides a canvas into small rectangular elements and moves each of those as required by the 'physics' given (value of gravity/wind for example).
The original just draws grid lines for each of these areas. What we need is for the equivalent rectangle in the original image to be copied to that point.
This snippet achieves this by adding a origx/y to the info kept about each point so that we know where to find the original rectangle.
It brings the image into an img element (it is important to wait until this is loaded before doing more with it) then copies it to an off-screen canvas that has the same dimensions as the one which will hold the material. This canvas is inspected when we need the 'mini image' to put at a given point.
WARNING: this code (even without the introduction of an image) is pretty processor intensive. On a farily powerful laptop with good GPU it was taking around 19% of CPU and not much less of GPU and the fan was whirring. This is even when there is no movement of the mouse. The code could do with a thorough look through, for example to stop the timer when user activity is completed, and perhaps putting the frame rate down (it's 60fps in the given code). I would not recommend it be put in a webpage and left there running - it will be a battery drainer.
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<!--
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
-->
<script type="text/javascript" src=""></script>
<link rel="stylesheet" type="text/css" href="">
<style type="text/css">
body {}
.wrapper {}
* {
margin: 0;
overflow: hidden;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
body {
background: #333;
}
canvas {
background: #333;
width: 100%;
height: 376px;
margin: 0 auto;
display: block;
border: solid red 2px;
}
#info {
position: absolute;
left: -1px;
top: -1px;
width: auto;
max-width: 380px;
height: auto;
background: #f2f2f2;
border-bottom-right-radius: 10px;
}
#top {
background: #fff;
width: 100%;
height: auto;
position: relative;
border-bottom: 1px solid #eee;
}
p {
font-family: Arial, sans-serif;
color: #666;
text-align: justify;
font-size: 16px;
margin: 10px;
}
a {
font-family: sans-serif;
color: #444;
text-decoration: none;
font-size: 20px;
}
#site {
float: left;
margin: 10px;
color: #38a;
border-bottom: 1px dashed #888;
}
#site:hover {
color: #7af;
}
#close {
float: right;
margin: 10px;
}
#p {
font-family: Verdana, sans-serif;
position: absolute;
right: 10px;
bottom: 10px;
color: #adf;
border: 1px dashed #555;
padding: 4px 8px;
}
</style>
<img src="https://i.stack.imgur.com/Celmj.jpg" style="margin-top: -2000px; position: absolute;">
<canvas width="1360" height="376" style="margin-top: -2000px; position: absolute;"></canvas>
<script type="text/javascript">
/*
Copyright (c) 2013 lonely-pixel.com, Stuffit at codepen.io (http://codepen.io/stuffit)
View this and others at http://lonely-pixel.com
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
const mycanvas = document.querySelector('canvas');
const mycontext = mycanvas.getContext('2d');
// settings
var physics_accuracy = 5,
mouse_influence = 20,
mouse_cut = 6,
gravity = 900,
cloth_height = 30,
cloth_width = 50,
start_y = 20,
spacing = 7,
tear_distance = 60;
window.requestAnimFrame =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
var canvas,
ctx,
cloth,
boundsx,
boundsy,
mouse = {
down: false,
button: 1,
x: 0,
y: 0,
px: 0,
py: 0
};
window.onload = function() {
// ADDED TO BRING IN THE IMAGE
mycontext.clearRect(0, 0, mycanvas.width, mycanvas.height);
mycontext.drawImage(document.querySelector('img'), 0, 0, 1180, 376);
canvas = document.getElementById('c');
ctx = canvas.getContext('2d');
canvas.width = canvas.clientWidth;
canvas.height = 376;
canvas.onmousedown = function(e) {
mouse.button = e.which;
mouse.px = mouse.x;
mouse.py = mouse.y;
var rect = canvas.getBoundingClientRect();
mouse.x = e.clientX - rect.left,
mouse.y = e.clientY - rect.top,
mouse.down = true;
e.preventDefault();
};
canvas.onmouseup = function(e) {
mouse.down = false;
e.preventDefault();
};
canvas.onmousemove = function(e) {
mouse.px = mouse.x;
mouse.py = mouse.y;
var rect = canvas.getBoundingClientRect();
mouse.x = e.clientX - rect.left,
mouse.y = e.clientY - rect.top,
e.preventDefault();
};
canvas.oncontextmenu = function(e) {
e.preventDefault();
};
boundsx = canvas.width - 1;
boundsy = canvas.height - 1;
ctx.strokeStyle = 'rgba(222,222,222,0.6)';
ctx.strokeStyle = 'magenta';
cloth = new Cloth();
update();
};
var Point = function(x, y) {
this.x = x;
this.y = y;
this.px = x;
this.py = y;
this.vx = 0;
this.vy = 0;
this.pin_x = null;
this.pin_y = null;
this.constraints = [];
//added - remember where this point was originally so we can get the right bit of the img
this.origx = x;
this.origy = y;
};
Point.prototype.update = function(delta) {
if (mouse.down) {
var diff_x = this.x - mouse.x,
diff_y = this.y - mouse.y,
dist = Math.sqrt(diff_x * diff_x + diff_y * diff_y);
if (mouse.button == 1) {
if (dist < mouse_influence) {
this.px = this.x - (mouse.x - mouse.px) * 1.8;
this.py = this.y - (mouse.y - mouse.py) * 1.8;
}
} else if (dist < mouse_cut) this.constraints = [];
}
this.add_force(0, gravity);
delta *= delta;
nx = this.x + ((this.x - this.px) * .99) + ((this.vx / 2) * delta);
ny = this.y + ((this.y - this.py) * .99) + ((this.vy / 2) * delta);
this.px = this.x;
this.py = this.y;
this.x = nx;
this.y = ny;
this.vy = this.vx = 0
};
Point.prototype.draw = function() {
if (this.constraints.length <= 0) return;
var i = this.constraints.length;
while (i--) this.constraints[i].draw();
};
Point.prototype.resolve_constraints = function() {
if (this.pin_x != null && this.pin_y != null) {
this.x = this.pin_x;
this.y = this.pin_y;
return;
}
var i = this.constraints.length;
while (i--) this.constraints[i].resolve();
this.x > boundsx ? this.x = 2 * boundsx - this.x : 1 > this.x && (this.x = 2 - this.x);
this.y < 1 ? this.y = 2 - this.y : this.y > boundsy && (this.y = 2 * boundsy - this.y);
};
Point.prototype.attach = function(point) {
this.constraints.push(
new Constraint(this, point)
);
};
Point.prototype.remove_constraint = function(lnk) {
var i = this.constraints.length;
while (i--)
if (this.constraints[i] == lnk) this.constraints.splice(i, 1);
};
Point.prototype.add_force = function(x, y) {
this.vx += x;
this.vy += y;
};
Point.prototype.pin = function(pinx, piny) {
this.pin_x = pinx;
this.pin_y = piny;
};
var Constraint = function(p1, p2) {
this.p1 = p1;
this.p2 = p2;
this.length = spacing;
};
Constraint.prototype.resolve = function() {
var diff_x = this.p1.x - this.p2.x,
diff_y = this.p1.y - this.p2.y,
dist = Math.sqrt(diff_x * diff_x + diff_y * diff_y),
diff = (this.length - dist) / dist;
if (dist > tear_distance) this.p1.remove_constraint(this);
var px = diff_x * diff * 0.5;
var py = diff_y * diff * 0.5;
this.p1.x += px;
this.p1.y += py;
this.p2.x -= px;
this.p2.y -= py;
};
let num = 0;
Constraint.prototype.draw = function() {
ctx.drawImage(mycanvas, this.p1.origx, this.p1.origy, spacing, spacing, this.p1.x, this.p1.y, spacing + 1, spacing + 1);
};
var Cloth = function() {
this.points = [];
var start_x = canvas.width / 2 - cloth_width * spacing / 2;
for (var y = 0; y <= cloth_height; y++) {
for (var x = 0; x <= cloth_width; x++) {
var p = new Point(start_x + x * spacing, start_y + y * spacing);
x != 0 && p.attach(this.points[this.points.length - 1]);
y == 0 && p.pin(p.x, p.y);
y != 0 && p.attach(this.points[x + (y - 1) * (cloth_width + 1)])
this.points.push(p);
}
}
};
Cloth.prototype.update = function() {
var i = physics_accuracy;
while (i--) {
var p = this.points.length;
while (p--) this.points[p].resolve_constraints();
}
i = this.points.length;
while (i--) this.points[i].update(.016);
};
Cloth.prototype.draw = function() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
var i = cloth.points.length;
while (i--) cloth.points[i].draw();
ctx.stroke();
};
function update() {
cloth.update();
cloth.draw();
requestAnimFrame(update);
}
</script>
</head>
<body>
<canvas id="c" width="800" height="376"> </canvas>
</body>
</html>
Note: it is possible to 'tear' the material with a right click and this facility probably needs removing - unless you want users to ruin the look of the cloth :)

How to Draw on rotated canvas using mouse?

I want to draw on img its work fine but when i rotate the image its drawing axis is total change and it not draw on the right area
https://codepen.io/ali-shahzil/project/editor/AddPLW
var canvas;
var ctx;
var SCALE_MIN = 1,
SCALE_MAX = 25;
var currScale = 0; // def pic width=600px, 100px=1scale unit
var xscale = 1.0;
var scaleFactor = 1.00;
var painting = false,
mark = true,
lastX = 0,
lastY = 0,
lineThickness = 0.3,
width = 600,
height = 600;
var img = new Image();
img.src = 'img.JPG';
img.onload = function() {
canvas = document.getElementById("canvas1"),
ctx = canvas.getContext("2d");
canvas.height = height;
canvas.width = width;
ctx.drawImage(img, 5, 40, canvas.width, canvas.height);
canvas = document.getElementById("canvas2"),
ctx = canvas.getContext("2d");
canvas.height = height;
canvas.width = width;
ctx.drawImage(img, 5, 40, canvas.width, canvas.height);
canvas = ctx = ''; //reset
}
function doMarking() {
var checkBox = document.getElementById("mark");
if (checkBox.checked == true) {
mark = true;
if (canvas != null)
canvas.style.cursor = "pointer";
//currImgId = '';
} else {
mark = false;
if (canvas != null);
canvas.style.cursor = "";
}
lastX = 0,
lastY = 0,
painting = false;
}
function mouseDown(e) {
if (!mark)
return;
painting = true;
ctx.fillStyle = "#ffffff";
lastX = e.pageX - (e.target).offsetLeft;
lastY = e.pageY - (e.target).offsetTop;
//Calculating the scale how much it increase
var rect = canvas.getBoundingClientRect(); // abs. size of element
scaleX = canvas.width / rect.width; // relationship bitmap vs. element for X
scaleY = canvas.height / rect.height; // relationship bitmap vs. element for Y
lastX = lastX * scaleX;
lastY = lastY * scaleY;
//console.log('Before lasX=' + lastX + ' lastY=' + lastY+',currScale='+currScale);
//lastX=transformSimple(lastX);
// lastY=transformSimple(lastY);
//console.log('After lasX=' + lastX + ' lastY=' + lastY+', currScale='+currScale);
//console.log('offleft=' + (e.target).offsetLeft + ', offsetTop=' + (e.target).offsetTop);
// console.log('e=' + e);
}
/*
canvas1.onmousedown=function (e) {
console.log('mousedown2 id=' + e);
if (!mark)
return;
painting = true;
ctx.fillStyle = "#ffffff";
lastX = e.pageX - this.offsetLeft;
lastY = e.pageY - this.offsetTop;
console.log('lasX=' + lastX + ' lastY=' + lastY);
}
*/
function mouseUp(e) {
if (!mark)
return;
painting = false;
}
function mouseMove(e) {
if (!mark)
return;
if (painting) {
mouseX = e.pageX - (e.target).offsetLeft;
mouseY = e.pageY - (e.target).offsetTop;
//Calculating the scale how much it increase
var rect = canvas.getBoundingClientRect(); // abs. size of element
scaleX = canvas.width / rect.width; // relationship bitmap vs. element for X
scaleY = canvas.height / rect.height; // relationship bitmap vs. element for Y
mouseX = mouseX * scaleX;
mouseY = mouseY * scaleY;
// mouseX=transformSimple(mouseX);
// mouseY=transformSimple(mouseY);
//console.log('mx=' + mouseX + ', my=' + mouseY);
// find all points between
var x1 = mouseX,
x2 = lastX,
y1 = mouseY,
y2 = lastY;
var steep = (Math.abs(y2 - y1) > Math.abs(x2 - x1));
if (steep) {
var x = x1;
x1 = y1;
y1 = x;
var y = y2;
y2 = x2;
x2 = y;
}
if (x1 > x2) {
var x = x1;
x1 = x2;
x2 = x;
var y = y1;
y1 = y2;
y2 = y;
}
var dx = x2 - x1,
dy = Math.abs(y2 - y1),
error = 0,
de = dy / dx,
yStep = -1,
y = y1;
if (y1 < y2) {
yStep = 1;
}
lineThickness = 5 - Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) / 10;
if (lineThickness < 1) {
lineThickness = 1;
}
for (var x = x1; x < x2; x++) {
if (steep) {
// translate(y,x);
ctx.fillRect(y, x, lineThickness, lineThickness);
//ctx.fillRect(transformSimple(y), transformSimple(x), lineThickness, lineThickness);
} else {
ctx.fillRect(x, y, lineThickness, lineThickness);
}
error += de;
if (error >= 0.5) {
y += yStep;
error -= 1.0;
}
// console.log('x=' + x + ', y=' + y );
}
lastX = mouseX;
lastY = mouseY;
}
}
/*
canvas.addEventListener('click', function (event) {
if (mark)
return;
//get the img of convas
});*/
//-------------- img zooms
function zoomin_canvas() {
if (canvas != null) {
var currWidth = canvas.clientWidth;
//console.log('zoomin currWidth='+currWidth);
if (currWidth >= 1500) return false;
else {
canvas.style.width = (currWidth + 100) + "px";
//if (currScale < SCALE_MAX)
// currScale++;
//console.log('scale=' + currScale);
}
}
}
function zoomout_canvas() {
if (canvas != null) {
var currWidth = canvas.clientWidth;
if (currWidth <= 100) return false;
else {
canvas.style.width = (currWidth - 100) + "px";
//if (currScale > SCALE_MIN)
// currScale--;
//console.log('scale=' + currScale);
}
}
}
var currImgId = null;
function selectImg(e) {
if (currImgId != null) {
document.getElementById(currImgId).style.border = "none";
}
e.target.style.border = "2px solid orange";
currImgId = (e.target).getAttribute('id');
if (typeof canvas !== 'undefined') {
// the variable is defined
canvas = e.target;
ctx = canvas.getContext("2d");
}
//ctx.drawImage(img, 5, 40, canvas.width, canvas.height);
}
function rotate() {
if (currImgId != null) {
document.getElementById(currImgId).setAttribute("class", "rotated-image");
}
}
var degrees = 0;
function rotateRight() {
console.log('currimgid=' + currImgId);
var img = document.getElementById(currImgId);
degrees = parseInt(img.getAttribute("rotate"));
degrees = (degrees + 90) % 360;
img.style.setProperty('-ms-transform', 'rotate(' + degrees + 'deg)');
img.style.setProperty('-webkit-transform', 'rotate(' + degrees + 'deg)');
img.style.setProperty('transform', 'rotate(' + degrees + 'deg)');
img.setAttribute("rotate", degrees);
}
function rotateLeft() {
var img = document.getElementById(currImgId);
degrees = parseInt(img.getAttribute("rotate"));
degrees = (degrees - 90) % 360;
img.style.setProperty('-ms-transform', 'rotate(' + degrees + 'deg)');
img.style.setProperty('-webkit-transform', 'rotate(' + degrees + 'deg)');
img.style.setProperty('transform', 'rotate(' + degrees + 'deg)');
img.setAttribute("rotate", degrees);
}
function translate(X, Y) {
console.log('untransformed x=' + X + ', y=' + Y);
// const point = {x: 0, y: 0};
const matrix = ctx.getTransform();
const transformedPoint = {
x: matrix.a * X + matrix.c * Y + matrix.e,
y: matrix.b * X + matrix.d * Y + matrix.f,
};
console.log('transformed x=' + transformedPoint.x + ', y=' + transformedPoint.y);
}
function translateSimple(X, Y) {
//console.log('scalefactor='+scaleFactor);
console.log('untransformed x=' + X + ', y=' + Y);
if (scaleFactor >= 1.0)
console.log('transformed x=' + X / scaleFactor + ', y=' + Y / scaleFactor);
else
console.log('transformed x=' + X * scaleFactor + ', y=' + Y * scaleFactor);
}
function transformSimple(a) {
//return (parseInt(a/(scaleFactor*scaleFactor)));
if (currScale == 0)
return (a);
else
return (a - 16 * (currScale));
}
function draw() {
for (var x = 100; x < 102; x++)
ctx.fillRect(100, x, 4.9, 4.9);
}
.main_bottom {
background-color: #e8e9eb;
display: flex;
align-items: center;
justify-content: space-around;
border: 10px solid #e8e9eb;
border-top: 30px solid #e8e9eb;
height: 90vh;
}
form {
display: flex;
justify-content: center;
align-items: center;
flex-direction: row;
margin-bottom: 5px;
}
.scrollit {
/*overflow-y: auto;*/
/* overflow-y: scroll;*/
height: 300px;
overflow-x: hidden;
overflow-y: auto;
}
.first {
display: flex;
flex-direction: row;
visibility: hidden;
}
.submit {
display: flex;
flex-direction: row;
}
img {
width: 100%;
max-width: 800px;
height: auto;
display: block;
margin-left: auto;
margin-right: auto;
}
.fix {
height: 300px;
margin-top: 200px;
}
body,
html {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#container {
width: 100%;
height: 100%;
}
#left_panel {
display: flex;
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 700px;
background-color: white;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2);
flex-direction: column;
overflow: scroll;
}
#right_panel {
display: flex;
position: absolute;
right: 0;
top: 0;
bottom: 0;
width: 700px;
margin-right: 15px;
background-color: white;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2);
flex-direction: column;
overflow: scroll;
}
#drag {
position: absolute;
left: -4px;
top: 0;
bottom: 0;
width: 8px;
cursor: w-resize;
}
/*img zooms*/
#navbar {
overflow: hidden;
background-color: #099;
position: fixed;
top: 0;
width: 100%;
padding-top: 3px;
padding-bottom: 3px;
padding-left: 20px;
}
#navbar a {
float: left;
display: block;
color: #666;
text-align: center;
padding-right: 20px;
text-decoration: none;
font-size: 17px;
}
#navbar a:hover {
background-color: #ddd;
color: black;
}
#navbar a.active {
background-color: #4caf50;
color: white;
}
.main {
padding: 16px;
margin-top: 30px;
width: 100%;
height: 100vh;
overflow: auto;
cursor: grab;
cursor: -o-grab;
cursor: -moz-grab;
cursor: -webkit-grab;
}
.main img {
height: auto;
width: auto;
}
.button {
width: 300px;
height: 60px;
}
/*---- toggle switch*/
.switch {
position: relative;
display: inline-block;
width: 30px;
height: 17px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: 0.4s;
transition: 0.4s;
}
.slider:before {
position: absolute;
content: "";
height: 13px;
width: 13px;
left: 4px;
bottom: 2px;
background-color: white;
-webkit-transition: 0.4s;
transition: 0.4s;
}
input:checked+.slider {
background-color: #2196f3;
}
input:focus+.slider {
box-shadow: 0 0 1px #2196f3;
}
input:checked+.slider:before {
-webkit-transform: translateX(13px);
-ms-transform: translateX(13px);
transform: translateX(13px);
}
/* Rounded sliders */
.slider.round {
border-radius: 17px;
}
.slider.round:before {
border-radius: 50%;
}
.both {
margin-top: 50px;
display: flex;
justify-content: center;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./styles.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<title>Order by Picture</title>
</head>
<body>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<div id="navbar">
<button type="button" onclick="zoomin_canvas()">+</button>
<button type="button" onclick="zoomout_canvas()">-</button>
<button id="rotateRight" onclick="rotateRight()">Right</button>
<button id="rotateLeft" onclick="rotateLeft()">Left</button>
<button id="Button1" onclick="draw()">draw</button
<label> Marking</label>
<label class="switch">
<input type="checkbox" checked onclick="doMarking()" id="mark">
<span class="slider round"></span>
</label>
</div>
<div class="both">
<div class="canvas1">
<canvas id="canvas1" rotate="0" onclick="selectImg(event)" onmousedown="mouseDown(event)" onmouseup="mouseUp(event)" onmousemove="mouseMove(event)">
Your browser does not support the HTML5 canvas tag.
</canvas>
</div>
<div class="canvas2">
<canvas id="canvas2" rotate="0" onclick="selectImg(event)" onmousedown="mouseDown(event)" onmouseup="mouseUp(event)" onmousemove="mouseMove(event)">
Your browser does not support the HTML5 canvas tag.
</canvas>
</div>
</div>
</body>
</html>
Don't rotate the canvas
Draw the rotated image on the canvas, rather than rotate the canvas.
When you draw image on the canvas, rotate it, then you can draw over it using the normal mouse coords.
Rotating image on canvas
The code below will draw an image rotated by any amount. The image will be scaled down if needed to ensure it fits the canvas. The function will rotate the image any angle you want.
// ctx is canvas 2D context
// deg in degrees rotated CW from 3 O-clock
// img to render. NOTE image must be loaded first
function drawRotatedImage(ctx, deg, img) {
const w = img.naturalWidth;
const h = img.naturalHeight;
const cw = ctx.canvas.width;
const ch = ctx.canvas.height;
// convert deg to radians
const rad = deg * Math.PI / 180;
// Get vector for rotated xAxis ax, ay. With aax, aay in first quadrant
const ax = Math.cos(rad), aax = Math.abs(ax);
const ay = Math.sin(rad), aay = Math.abs(ay);
// get the rotated width and height of image
const tw = aax * w + aay * h;
const th = aay * w + aax * h;
// get scale so that image fits the canvas. Dont enlarge only reduce if to big
const scale = Math.min(1, cw / tw, ch / th);
// set canvas transform to center of canvas, rotated and scaled to fit
ctx.setTransform(ax * scale, ay * scale, -ay * scale, ax * scale, cw / 2, ch / 2);
// draw image on canvas offset by half its width and height
ctx.drawImage(img, -w / 2, -h / 2);
// restore canvas transform to default
ctx.setTransform(1, 0, 0, 1, 0, 0);
}
Example
Example using the above function to render image to canvas and then use mouse to draw over the image. Click rotate to rotate the image.
const ctx = canvas.getContext("2d");
const mouse = {x: 0, y: 0, b: false, ox: 0, oy: 0};
var rot = 90;
const img = new Image;
img.src = "https://i.stack.imgur.com/C7qq2.png?s=420&g=1";
img.onload = () => rotImage(ctx, rot, img);
resize();
addEventListener("resize", resize);
rotBtn.addEventListener("click", () => img.complete && rotImage(ctx, rot += 90, img));
addEventListener("mousemove", mouseEvent);
addEventListener("mousedown", mouseEvent);
addEventListener("mouseup", mouseEvent);
addEventListener("mouseout", mouseEvent);
function resize() {
canvas.width = innerWidth;
canvas.height = innerHeight;
ctx.lineWidth = 3;
ctx.lineCap = "round";
ctx.strokeStyle = "#00F";
img.complete && rotImage(ctx, rot, img);
}
function mouseEvent(e) {
mouse.ox = mouse.x;
mouse.oy = mouse.y;
mouse.x = e.pageX;
mouse.y = e.pageY;
if (e.type === "mousedown") { mouse.b = true }
else if (e.type === "mouseup" || e.type === "mouseout") { mouse.b = false }
mouse.b && drawWithMouse(ctx, mouse);
}
function drawWithMouse(ctx, mouse) {
ctx.beginPath();
ctx.lineTo(mouse.ox, mouse.oy);
ctx.lineTo(mouse.x, mouse.y);
ctx.stroke();
}
function rotImage(ctx, deg, img) {
const cw = ctx.canvas.width, ch = ctx.canvas.height;
const w = img.naturalWidth, h = img.naturalHeight;
const rad = deg * Math.PI / 180;
const ax = Math.cos(rad), aax = Math.abs(ax);
const ay = Math.sin(rad), aay = Math.abs(ay);
const tw = aax * w + aay * h;
const th = aay * w + aax * h;
const sc = Math.min(1, cw / tw, ch / th);
ctx.clearRect(0, 0, cw, ch);
ctx.setTransform(ax * sc, ay * sc, -ay * sc, ax * sc, cw / 2, ch / 2);
ctx.drawImage(img, -w / 2, -h / 2);
ctx.setTransform(1, 0, 0, 1, 0, 0);
}
* {font-family: arial;}
button { position: absolute; top: 10px; left: 10px }
canvas { position: absolute; top: 0px; left: 0px }
<canvas id="canvas"></canvas>
<button id="rotBtn">Rotate</button>

How do i add a link to this animated button

Essentially i found this button that i wanted to add to my wixsite that links to a store. I have gotten the button animation to work and this button exists as a html element on wix. But all the button does currently is do the animation and dosent link. Could someone edit this code so after the animation plays the user will be redirected to a certain link.
I've tried looking up link code and inserting it in logical places to determine where it might work but obviously i dident find anything. And even if it did it likely would have redirected before the animation finished.
Here is the code without any of my attempts to try and fix this problem.
window.requestAnimFrame = (function () {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
Math.randMinMax = function (min, max, round) {
var val = min + (Math.random() * (max - min));
if (round) val = Math.round(val);
return val;
};
Math.TO_RAD = Math.PI / 180;
Math.getAngle = function (x1, y1, x2, y2) {
var dx = x1 - x2,
dy = y1 - y2;
return Math.atan2(dy, dx);
};
Math.getDistance = function (x1, y1, x2, y2) {
var xs = x2 - x1,
ys = y2 - y1;
xs *= xs;
ys *= ys;
return Math.sqrt(xs + ys);
};
var FX = {};
(function () {
var canvas = document.getElementById('myCanvas'),
ctx = canvas.getContext('2d'),
lastUpdate = new Date(),
mouseUpdate = new Date(),
lastMouse = [],
width, height;
FX.particles = [];
setFullscreen();
document.getElementById('button').addEventListener('mousedown', buttonEffect);
function buttonEffect() {
var button = document.getElementById('button'),
height = button.offsetHeight,
left = button.offsetLeft,
top = button.offsetTop,
width = button.offsetWidth,
x, y, degree;
for (var i = 0; i < 40; i = i + 1) {
if (Math.random() < 0.5) {
y = Math.randMinMax(top, top + height);
if (Math.random() < 0.5) {
x = left;
degree = Math.randMinMax(-45, 45);
} else {
x = left + width;
degree = Math.randMinMax(135, 225);
}
} else {
x = Math.randMinMax(left, left + width);
if (Math.random() < 0.5) {
y = top;
degree = Math.randMinMax(45, 135);
} else {
y = top + height;
degree = Math.randMinMax(-135, -45);
}
}
createParticle({
x: x,
y: y,
degree: degree,
speed: Math.randMinMax(100, 150),
vs: Math.randMinMax(-4, -1)
});
}
}
window.setTimeout(buttonEffect, 100);
loop();
window.addEventListener('resize', setFullscreen);
function createParticle(args) {
var options = {
x: width / 2,
y: height / 2,
color: 'hsla(' + Math.randMinMax(160, 290) + ', 100%, 50%, ' + (Math.random().toFixed(2)) + ')',
degree: Math.randMinMax(0, 360),
speed: Math.randMinMax(300, 350),
vd: Math.randMinMax(-90, 90),
vs: Math.randMinMax(-8, -5)
};
for (key in args) {
options[key] = args[key];
}
FX.particles.push(options);
}
function loop() {
var thisUpdate = new Date(),
delta = (lastUpdate - thisUpdate) / 1000,
amount = FX.particles.length,
size = 2,
i = 0,
p;
ctx.fillStyle = 'rgba(15,15,15,0.25)';
ctx.fillRect(0, 0, width, height);
ctx.globalCompositeStyle = 'lighter';
for (; i < amount; i = i + 1) {
p = FX.particles[i];
p.degree += (p.vd * delta);
p.speed += (p.vs);// * delta);
if (p.speed < 0) continue;
p.x += Math.cos(p.degree * Math.TO_RAD) * (p.speed * delta);
p.y += Math.sin(p.degree * Math.TO_RAD) * (p.speed * delta);
ctx.save();
ctx.translate(p.x, p.y);
ctx.rotate(p.degree * Math.TO_RAD);
ctx.fillStyle = p.color;
ctx.fillRect(-size, -size, size * 2, size * 2);
ctx.restore();
}
lastUpdate = thisUpdate;
requestAnimFrame(loop);
}
function setFullscreen() {
width = canvas.width = window.innerWidth;
height = canvas.height = window.innerHeight;
};
})();
body {
margin: 0;
overflow: hidden;
}
#myCanvas {
display: block;
}
#button {
font-family: "Gill Sans", "Gill Sans MT", Calibri, sans-serif;
position: absolute;
font-size: 1.5em;
text-transform: uppercase;
padding: 7px 20px;
left: 50%;
width: 200px;
margin-left: -100px;
top: 50%;
border-radius: 10px;
color: white;
text-shadow: -1px -1px 1px rgba(0,0,0,0.8);
border: 5px solid transparent;
border-bottom-color: rgba(0,0,0,0.35);
background: hsla(260, 100%, 50%, 1);
cursor: pointer;
outline: 0 !important;
animation: pulse 1s infinite alternate;
transition: background 0.4s, border 0.2s, margin 0.2s;
}
#button:hover {
background: hsla(220, 100%, 60%, 1);
margin-top: -1px;
animation: none;
}
#button:active {
border-bottom-width: 0;
margin-top: 5px;
}
#keyframes pulse {
0% {
margin-top: 0px;
}
100% {
margin-top: 6px;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
</head>
<body>
<button id="button">Donate</button>
<canvas id="myCanvas" width="500" height="500"></canvas>
</body>
</html>
So again the expected result is to play the animation for the button then redirect to another page and the current result is the button simply playing the animation when clicked. If anyone could please write this code it would be super helpful.
Try changing your button to a href link. You may have to add some extra styling to the id class, but this should work.
<a id="button" href="https://www.linktosite.com">Link Button</a>
Put this on the button html tag onclick="location.href='http://www.link.com'"
You should add an activity when click on button. For example:
<button id="button" onclick="window.location.href = 'https://www.google.com';">Donate</button>
Demo:
window.requestAnimFrame = (function () {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
Math.randMinMax = function (min, max, round) {
var val = min + (Math.random() * (max - min));
if (round) val = Math.round(val);
return val;
};
Math.TO_RAD = Math.PI / 180;
Math.getAngle = function (x1, y1, x2, y2) {
var dx = x1 - x2,
dy = y1 - y2;
return Math.atan2(dy, dx);
};
Math.getDistance = function (x1, y1, x2, y2) {
var xs = x2 - x1,
ys = y2 - y1;
xs *= xs;
ys *= ys;
return Math.sqrt(xs + ys);
};
var FX = {};
(function () {
var canvas = document.getElementById('myCanvas'),
ctx = canvas.getContext('2d'),
lastUpdate = new Date(),
mouseUpdate = new Date(),
lastMouse = [],
width, height;
FX.particles = [];
setFullscreen();
document.getElementById('button').addEventListener('mousedown', buttonEffect);
function buttonEffect() {
var button = document.getElementById('button'),
height = button.offsetHeight,
left = button.offsetLeft,
top = button.offsetTop,
width = button.offsetWidth,
x, y, degree;
for (var i = 0; i < 40; i = i + 1) {
if (Math.random() < 0.5) {
y = Math.randMinMax(top, top + height);
if (Math.random() < 0.5) {
x = left;
degree = Math.randMinMax(-45, 45);
} else {
x = left + width;
degree = Math.randMinMax(135, 225);
}
} else {
x = Math.randMinMax(left, left + width);
if (Math.random() < 0.5) {
y = top;
degree = Math.randMinMax(45, 135);
} else {
y = top + height;
degree = Math.randMinMax(-135, -45);
}
}
createParticle({
x: x,
y: y,
degree: degree,
speed: Math.randMinMax(100, 150),
vs: Math.randMinMax(-4, -1)
});
}
}
window.setTimeout(buttonEffect, 100);
loop();
window.addEventListener('resize', setFullscreen);
function createParticle(args) {
var options = {
x: width / 2,
y: height / 2,
color: 'hsla(' + Math.randMinMax(160, 290) + ', 100%, 50%, ' + (Math.random().toFixed(2)) + ')',
degree: Math.randMinMax(0, 360),
speed: Math.randMinMax(300, 350),
vd: Math.randMinMax(-90, 90),
vs: Math.randMinMax(-8, -5)
};
for (key in args) {
options[key] = args[key];
}
FX.particles.push(options);
}
function loop() {
var thisUpdate = new Date(),
delta = (lastUpdate - thisUpdate) / 1000,
amount = FX.particles.length,
size = 2,
i = 0,
p;
ctx.fillStyle = 'rgba(15,15,15,0.25)';
ctx.fillRect(0, 0, width, height);
ctx.globalCompositeStyle = 'lighter';
for (; i < amount; i = i + 1) {
p = FX.particles[i];
p.degree += (p.vd * delta);
p.speed += (p.vs);// * delta);
if (p.speed < 0) continue;
p.x += Math.cos(p.degree * Math.TO_RAD) * (p.speed * delta);
p.y += Math.sin(p.degree * Math.TO_RAD) * (p.speed * delta);
ctx.save();
ctx.translate(p.x, p.y);
ctx.rotate(p.degree * Math.TO_RAD);
ctx.fillStyle = p.color;
ctx.fillRect(-size, -size, size * 2, size * 2);
ctx.restore();
}
lastUpdate = thisUpdate;
requestAnimFrame(loop);
}
function setFullscreen() {
width = canvas.width = window.innerWidth;
height = canvas.height = window.innerHeight;
};
})();
body {
margin: 0;
overflow: hidden;
}
#myCanvas {
display: block;
}
#button {
font-family: "Gill Sans", "Gill Sans MT", Calibri, sans-serif;
position: absolute;
font-size: 1.5em;
text-transform: uppercase;
padding: 7px 20px;
left: 50%;
width: 200px;
margin-left: -100px;
top: 50%;
border-radius: 10px;
color: white;
text-shadow: -1px -1px 1px rgba(0,0,0,0.8);
border: 5px solid transparent;
border-bottom-color: rgba(0,0,0,0.35);
background: hsla(260, 100%, 50%, 1);
cursor: pointer;
outline: 0 !important;
animation: pulse 1s infinite alternate;
transition: background 0.4s, border 0.2s, margin 0.2s;
}
#button:hover {
background: hsla(220, 100%, 60%, 1);
margin-top: -1px;
animation: none;
}
#button:active {
border-bottom-width: 0;
margin-top: 5px;
}
#keyframes pulse {
0% {
margin-top: 0px;
}
100% {
margin-top: 6px;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
</head>
<body>
<button id="button" onclick="window.location.href = 'https://www.google.com';">Donate</button>
<canvas id="myCanvas" width="500" height="500"></canvas>
</body>
</html>

codepen demo is not working in local browser?

I just stumbled upon a codepen demo. Then code works fine in codepen window. When, I copied it in a local HTML file it stopped working. Here is the code all combined in one .html file
<!DOCTYPE html>
<html>
<head>
<style>
body {
margin: 0;
overflow: hidden;
}
#myCanvas {
display: block;
}
#button {
font-family: "Gill Sans", "Gill Sans MT", Calibri, sans-serif;
position: absolute;
font-size: 1.5em;
text-transform: uppercase;
padding: 7px 20px;
left: 50%;
width: 200px;
margin-left: -100px;
top: 50%;
border-radius: 10px;
color: white;
text-shadow: -1px -1px 1px rgba(0,0,0,0.8);
border: 5px solid transparent;
border-bottom-color: rgba(0,0,0,0.35);
background: hsla(260, 100%, 50%, 1);
cursor: pointer;
animation: pulse 1s infinite alternate;
transition: background 0.4s, border 0.2s, margin 0.2s;
}
#button:hover {
background: hsla(220, 100%, 60%, 1);
margin-top: -1px;
animation: none;
}
#button:active {
border-bottom-width: 0;
margin-top: 5px;
}
#keyframes pulse {
0% {
margin-top: 0px;
}
100% {
margin-top: 6px;
}}
</style>
</head>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script>
window.requestAnimFrame = (function () {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
Math.randMinMax = function(min, max, round) {
var val = min + (Math.random() * (max - min));
if( round ) val = Math.round( val );
return val;
};
Math.TO_RAD = Math.PI/180;
Math.getAngle = function( x1, y1, x2, y2 ) {
var dx = x1 - x2,
dy = y1 - y2;
return Math.atan2(dy,dx);
};
Math.getDistance = function( x1, y1, x2, y2 ) {
var xs = x2 - x1,
ys = y2 - y1;
xs *= xs;
ys *= ys;
return Math.sqrt( xs + ys );
};
var FX = {};
(function() {
var canvas = document.getElementById('myCanvas'),
ctx = canvas.getContext('2d'),
lastUpdate = new Date(),
mouseUpdate = new Date(),
lastMouse = [],
width, height;
FX.particles = [];
setFullscreen();
document.getElementById('button').addEventListener('mousedown', buttonEffect);
function buttonEffect() {
var button = document.getElementById('button'),
height = button.offsetHeight,
left = button.offsetLeft,
top = button.offsetTop,
width = button.offsetWidth,
x, y, degree;
for(var i=0;i<40;i=i+1) {
if( Math.random() < 0.5 ) {
y = Math.randMinMax(top, top+height);
if( Math.random() < 0.5 ) {
x = left;
degree = Math.randMinMax(-45,45);
} else {
x = left + width;
degree = Math.randMinMax(135,225);
}
} else {
x = Math.randMinMax(left, left+width);
if( Math.random() < 0.5 ) {
y = top;
degree = Math.randMinMax(45,135);
} else {
y = top + height;
degree = Math.randMinMax(-135, -45);
}
}
createParticle({
x: x,
y: y,
degree: degree,
speed: Math.randMinMax(100, 150),
vs: Math.randMinMax(-4,-1)
});
}
}
window.setTimeout(buttonEffect, 100);
loop();
window.addEventListener('resize', setFullscreen );
function createParticle( args ) {
var options = {
x: width/2,
y: height/2,
color: 'hsla('+ Math.randMinMax(160, 290) +', 100%, 50%, '+(Math.random().toFixed(2))+')',
degree: Math.randMinMax(0, 360),
speed: Math.randMinMax(300, 350),
vd: Math.randMinMax(-90,90),
vs: Math.randMinMax(-8,-5)
};
for (key in args) {
options[key] = args[key];
}
FX.particles.push( options );
}
function loop() {
var thisUpdate = new Date(),
delta = (lastUpdate - thisUpdate) / 1000,
amount = FX.particles.length,
size = 2,
i = 0,
p;
ctx.fillStyle = 'rgba(15,15,15,0.25)';
ctx.fillRect(0,0,width,height);
ctx.globalCompositeStyle = 'lighter';
for(;i<amount;i=i+1) {
p = FX.particles[ i ];
p.degree += (p.vd * delta);
p.speed += (p.vs);// * delta);
if( p.speed < 0 ) continue;
p.x += Math.cos(p.degree * Math.TO_RAD) * (p.speed * delta);
p.y += Math.sin(p.degree * Math.TO_RAD) * (p.speed * delta);
ctx.save();
ctx.translate( p.x, p.y );
ctx.rotate( p.degree * Math.TO_RAD );
ctx.fillStyle = p.color;
ctx.fillRect( -size, -size, size*2, size*2 );
ctx.restore();
}
lastUpdate = thisUpdate;
requestAnimFrame( loop );
}
function setFullscreen() {
width = canvas.width = window.innerWidth;
height = canvas.height = window.innerHeight;
};
})();
</script>
<button id="button">click me</button>
<canvas id="myCanvas" width="500" height="500"></canvas>
</body>
</html>
You need to use your script code in $.ready() LIKE,
$(function(){
window.requestAnimFrame = (function () {
....
....
})();
});
As your script is loaded first but it doesn't find any DOM element, so it not works.
Also you don't need to include jquery, as you are not using any jquery functionality in your code so try it like,
<!DOCTYPE html>
<html>
<head>
<style>
// your style here
</style>
</head>
<body>
<button id="button">click me</button>
<canvas id="myCanvas" width="500" height="500"></canvas>
<script>
// and no need to include jquery if not used
// you script goes here after adding DOM elements
</script>
</body>
</html>
It might help to put the script tags inside the <head></head> tags.
<!DOCTYPE html>
<html>
<head>
<style>
body {
margin: 0;
overflow: hidden;
}
#myCanvas {
display: block;
}
#button {
font-family: "Gill Sans", "Gill Sans MT", Calibri, sans-serif;
position: absolute;
font-size: 1.5em;
text-transform: uppercase;
padding: 7px 20px;
left: 50%;
width: 200px;
margin-left: -100px;
top: 50%;
border-radius: 10px;
color: white;
text-shadow: -1px -1px 1px rgba(0,0,0,0.8);
border: 5px solid transparent;
border-bottom-color: rgba(0,0,0,0.35);
background: hsla(260, 100%, 50%, 1);
cursor: pointer;
animation: pulse 1s infinite alternate;
transition: background 0.4s, border 0.2s, margin 0.2s;
}
#button:hover {
background: hsla(220, 100%, 60%, 1);
margin-top: -1px;
animation: none;
}
#button:active {
border-bottom-width: 0;
margin-top: 5px;
}
#keyframes pulse {
0% {
margin-top: 0px;
}
100% {
margin-top: 6px;
}}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script>
window.requestAnimFrame = (function () {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
Math.randMinMax = function(min, max, round) {
var val = min + (Math.random() * (max - min));
if( round ) val = Math.round( val );
return val;
};
Math.TO_RAD = Math.PI/180;
Math.getAngle = function( x1, y1, x2, y2 ) {
var dx = x1 - x2,
dy = y1 - y2;
return Math.atan2(dy,dx);
};
Math.getDistance = function( x1, y1, x2, y2 ) {
var xs = x2 - x1,
ys = y2 - y1;
xs *= xs;
ys *= ys;
return Math.sqrt( xs + ys );
};
var FX = {};
(function() {
var canvas = document.getElementById('myCanvas'),
ctx = canvas.getContext('2d'),
lastUpdate = new Date(),
mouseUpdate = new Date(),
lastMouse = [],
width, height;
FX.particles = [];
setFullscreen();
document.getElementById('button').addEventListener('mousedown', buttonEffect);
function buttonEffect() {
var button = document.getElementById('button'),
height = button.offsetHeight,
left = button.offsetLeft,
top = button.offsetTop,
width = button.offsetWidth,
x, y, degree;
for(var i=0;i<40;i=i+1) {
if( Math.random() < 0.5 ) {
y = Math.randMinMax(top, top+height);
if( Math.random() < 0.5 ) {
x = left;
degree = Math.randMinMax(-45,45);
} else {
x = left + width;
degree = Math.randMinMax(135,225);
}
} else {
x = Math.randMinMax(left, left+width);
if( Math.random() < 0.5 ) {
y = top;
degree = Math.randMinMax(45,135);
} else {
y = top + height;
degree = Math.randMinMax(-135, -45);
}
}
createParticle({
x: x,
y: y,
degree: degree,
speed: Math.randMinMax(100, 150),
vs: Math.randMinMax(-4,-1)
});
}
}
window.setTimeout(buttonEffect, 100);
loop();
window.addEventListener('resize', setFullscreen );
function createParticle( args ) {
var options = {
x: width/2,
y: height/2,
color: 'hsla('+ Math.randMinMax(160, 290) +', 100%, 50%, '+(Math.random().toFixed(2))+')',
degree: Math.randMinMax(0, 360),
speed: Math.randMinMax(300, 350),
vd: Math.randMinMax(-90,90),
vs: Math.randMinMax(-8,-5)
};
for (key in args) {
options[key] = args[key];
}
FX.particles.push( options );
}
function loop() {
var thisUpdate = new Date(),
delta = (lastUpdate - thisUpdate) / 1000,
amount = FX.particles.length,
size = 2,
i = 0,
p;
ctx.fillStyle = 'rgba(15,15,15,0.25)';
ctx.fillRect(0,0,width,height);
ctx.globalCompositeStyle = 'lighter';
for(;i<amount;i=i+1) {
p = FX.particles[ i ];
p.degree += (p.vd * delta);
p.speed += (p.vs);// * delta);
if( p.speed < 0 ) continue;
p.x += Math.cos(p.degree * Math.TO_RAD) * (p.speed * delta);
p.y += Math.sin(p.degree * Math.TO_RAD) * (p.speed * delta);
ctx.save();
ctx.translate( p.x, p.y );
ctx.rotate( p.degree * Math.TO_RAD );
ctx.fillStyle = p.color;
ctx.fillRect( -size, -size, size*2, size*2 );
ctx.restore();
}
lastUpdate = thisUpdate;
requestAnimFrame( loop );
}
function setFullscreen() {
width = canvas.width = window.innerWidth;
height = canvas.height = window.innerHeight;
};
})();
</script>
</head>
<body>
<button id="button">click me</button>
<canvas id="myCanvas" width="500" height="500"></canvas>
</body>
</html>

Categories

Resources