Why absolute positioned indicater goes out of relative positioned container? - javascript

Well I have designed a color picker, from where a selected color will show beside the canvas. Now the problem is everytime I am trying to drag the indicator it goes out of the canvas even after the position is relative.
Every time i am trying to drag the indicator it goes out of canvas. I have highlighted the indicator in the image below
var canvas = document.getElementById('color-picker');
var context = canvas.getContext('2d');
var w = 250;
var h = 250;
canvas.width = w;
canvas.height = h;
var x = canvas.width / 2;
var y = canvas.height / 2;
var radius = x;
for (var angle = 0; angle <= 360; angle += 1) {
var startAngle = (angle - 2) * Math.PI / 180;
var endAngle = angle * Math.PI / 180;
context.beginPath();
context.moveTo(x, y);
context.arc(x, y, radius, startAngle, endAngle, false);
context.closePath();
var gradient = context.createRadialGradient(x, y, 0, x, y, radius);
gradient.addColorStop(0, 'hsl(' + angle + ', 10%, 100%)');
gradient.addColorStop(1, 'hsl(' + angle + ', 100%, 50%)');
context.fillStyle = gradient;
context.fill();
}
var m = {
x: canvas.width / 2,
y: canvas.height / 2
};
var drag = false;
var location_path = document.getElementById('_lp_');
var lp_width = location_path.offsetWidth;
var lp_height = location_path.offsetHeight;
var container = document.getElementById('container');
var selected_color = document.getElementById('selected_color');
var def_color = "#f8fff9";
selected_color.style.backgroundColor = def_color;
container.addEventListener('mousedown', dragged, false);
container.addEventListener('mousemove', moving, false);
window.addEventListener('mouseup', noDrag, false);
function dragged() {
drag = true;
}
function noDrag() {
drag = false;
}
function moving(e) {
if (drag) {
var ink_x = (e.clientX - container.offsetLeft);
var ink_y = (e.clientY - container.offsetTop);
m.x = e.clientX - container.offsetLeft - lp_width / 2;
m.y = e.clientY - container.offsetTop - lp_height - 10; //why 10? 10 for padding
if (Distance(ink_x, ink_y, w / 2, h / 2) > radius) {
drag = false;
}
location_path.style.left = m.x + 'px';
location_path.style.top = m.y + 'px';
var getData = context.getImageData(ink_x, ink_y, 1, 1);
var pxl = getData.data;
var r = pxl[0];
var g = pxl[1];
var b = pxl[2];
var a = pxl[3];
// indicator.style.background = "rgb(" + r + ',' + g + ',' + b + ")";
selected_color.style.background = "rgb(" + r + ',' + g + ',' + b + ")";
}
}
function rgb2hex(red, green, blue) {
var rgb = blue | (green << 8) | (red << 16);
return '#' + (0x1000000 + rgb).toString(16).slice(1)
}
function Distance(x1, y1, x2, y2) {
var dx = x2 - x1;
var dy = y2 - y1;
return Math.sqrt(dx * dx + dy * dy);
}
.lighting-wrapper {
margin: 5% auto;
}
.lighting-left,
.lighting-right {
padding: 50px;
}
.lighting-color-picker-wrapper,
.lighting-selected-color-wrapper {
position: relative;
width: 250px;
height: 250px;
margin: 150px auto;
border-radius: 50%;
}
.location-path {
position: absolute;
width: 40px;
height: 40px;
padding: 10px;
background: #fff;
border-radius: 50%;
border-bottom-left-radius: 0%;
top: 58px;
left: 92px;
transform: rotate(-45deg);
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
user-select: none;
transition: all 0.1s;
}
<div class="container">
<div class="lighting-wrapper shadow-sm">
<div class="row align-items-center">
<div class="col-md-6 d-flex justify-content-center lighting-left">
<div class="lighting-color-picker-wrapper" id="container">
<canvas id="color-picker" class="position-relative"></canvas>
<div id="_lp_" class="location-path"></div>
</div>
</div>
<div class="col-md-6 d-flex justify-content-center lighting-right">
<div class="lighting-selected-color-wrapper" id="selected_color">
</div>
</div>
</div>
</div>
</div>

Looks like your code is affected by the page scroll.
Try change the "e.clientY" to "e.pageY".
var canvas = document.getElementById('color-picker');
var context = canvas.getContext('2d');
var w = 250;
var h = 250;
canvas.width = w;
canvas.height = h;
var x = canvas.width / 2;
var y = canvas.height / 2;
var radius = x;
for (var angle = 0; angle <= 360; angle += 1) {
var startAngle = (angle - 2) * Math.PI / 180;
var endAngle = angle * Math.PI / 180;
context.beginPath();
context.moveTo(x, y);
context.arc(x, y, radius, startAngle, endAngle, false);
context.closePath();
var gradient = context.createRadialGradient(x, y, 0, x, y, radius);
gradient.addColorStop(0, 'hsl(' + angle + ', 10%, 100%)');
gradient.addColorStop(1, 'hsl(' + angle + ', 100%, 50%)');
context.fillStyle = gradient;
context.fill();
}
var m = {
x: canvas.width / 2,
y: canvas.height / 2
};
var drag = false;
var location_path = document.getElementById('_lp_');
var lp_width = location_path.offsetWidth;
var lp_height = location_path.offsetHeight;
var container = document.getElementById('container');
var selected_color = document.getElementById('selected_color');
var def_color = "#f8fff9";
selected_color.style.backgroundColor = def_color;
container.addEventListener('mousedown', dragged, false);
container.addEventListener('mousemove', moving, false);
window.addEventListener('mouseup', noDrag, false);
function dragged() {
drag = true;
}
function noDrag() {
drag = false;
}
function moving(e) {
if (drag) {
var ink_x = (e.pageX - container.offsetLeft);
var ink_y = (e.pageY - container.offsetTop);
if (Distance(ink_x, ink_y, w / 2, h / 2) > radius) {
var vector = { x: ink_x - w / 2, y: ink_y - h / 2 };
normalize(vector);
ink_x = Math.trunc(vector.x * radius) + w / 2;
ink_y = Math.trunc(vector.y * radius) + h / 2;
drag = false;
}
m.x = ink_x - lp_width / 2;
m.y = ink_y - lp_height - 10; //why 10? 10 for padding
location_path.style.left = m.x + 'px';
location_path.style.top = m.y + 'px';
var getData = context.getImageData(ink_x, ink_y, 1, 1);
var pxl = getData.data;
var r = pxl[0];
var g = pxl[1];
var b = pxl[2];
var a = pxl[3];
// indicator.style.background = "rgb(" + r + ',' + g + ',' + b + ")";
selected_color.style.background = "rgb(" + r + ',' + g + ',' + b + ")";
}
}
function rgb2hex(red, green, blue) {
var rgb = blue | (green << 8) | (red << 16);
return '#' + (0x1000000 + rgb).toString(16).slice(1)
}
function Distance(x1, y1, x2, y2) {
var dx = x2 - x1;
var dy = y2 - y1;
return Math.sqrt(dx * dx + dy * dy);
}
function normalize(vector) {
var length = Math.sqrt(Math.pow(vector.x, 2) + Math.pow(vector.y, 2));
vector.x = vector.x / length;
vector.y = vector.y / length;
}
.lighting-wrapper {
margin: 5% auto;
}
.lighting-left,
.lighting-right {
padding: 50px;
}
.lighting-color-picker-wrapper,
.lighting-selected-color-wrapper {
position: relative;
width: 250px;
height: 250px;
margin: 150px auto;
border-radius: 50%;
}
.location-path {
position: absolute;
width: 40px;
height: 40px;
padding: 10px;
background: #fff;
border-radius: 50%;
border-bottom-left-radius: 0%;
top: 58px;
left: 92px;
transform: rotate(-45deg);
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
user-select: none;
transition: all 0.1s;
}
<div class="container">
<div class="lighting-wrapper shadow-sm">
<div class="row align-items-center">
<div class="col-md-6 d-flex justify-content-center lighting-left">
<div class="lighting-color-picker-wrapper" id="container">
<canvas id="color-picker" class="position-relative"></canvas>
<div id="_lp_" class="location-path"></div>
</div>
</div>
<div class="col-md-6 d-flex justify-content-center lighting-right">
<div class="lighting-selected-color-wrapper" id="selected_color">
</div>
</div>
</div>
</div>
</div>

Related

How to generate and animate a hexagonal sine wave in javascript after drawing a hexagon in HTML canvas?

After having tried sine and cosine wave animations, I am facing issues while animating a hexagonal wave with rotating radius. I am unable to get the diagonal wave lines to be straight in the wave. They come out slightly curled.
var hexStep = 0;
var hexID;
function drawAxes(context) {
var width = context.canvas.width;
var height = context.canvas.height;
context.beginPath();
context.strokeStyle = "rgb(128,128,128)";
context.lineWidth = 1;
// X-axis
context.moveTo(0, height / 2);
context.lineTo(width, height / 2);
// Sine Wave starting wall
context.moveTo(width / 4, 0);
context.lineTo(width / 4, height);
// Sine Wave Y-axis
context.moveTo((2.5 * width) / 4, 0);
context.lineTo((2.5 * width) / 4, height);
// Shape Y-axis
context.moveTo(width / 8, 0);
context.lineTo(width / 8, height);
context.stroke();
}
// Hexagon
function drawHexagon(context, x, y, r, side) {
var width = context.canvas.width;
var height = context.canvas.height;
var angle = (2 * Math.PI) / side;
context.beginPath();
context.strokeStyle = "midnightblue";
context.lineWidth = 2;
context.moveTo(x + r, y);
var hx = 0;
var hy = 0;
for (var i = 1; i <= side; i++) {
hx = x + r * Math.cos(angle * i);
hy = y + r * Math.sin(angle * i);
context.lineTo(hx, hy);
}
context.stroke();
}
function getHexagonalWave(context, x, y, r, side, step, freq) {
var width = context.canvas.width;
var height = context.canvas.height;
var angle = (2 * Math.PI) / side;
var inr = r * Math.sqrt(0.75);
context.beginPath();
context.strokeStyle = "midnightblue";
context.lineWidth = 2;
context.moveTo(x, y);
var sf = step / freq;
var hr = inr / Math.cos(((sf + angle / 2) % angle) - angle / 2);
var hx = x + hr * Math.sin(sf);
var hy = y - hr * Math.cos(sf);
context.lineTo(hx, hy);
var wx = width / 4;
context.moveTo(hx, hy);
context.lineTo(wx, hy);
context.moveTo(wx, hy);
var hvr = 0;
var wvx = 0;
var wvy = 0;
var id = 0;
for (var i = 0; i < width; i++) {
hvr = inr / Math.cos((((i + step) / freq + angle / 2) % angle) - angle / 2);
wvy = y - hvr * Math.cos((i + step) / freq);
wvx = wx + hvr * Math.sin((i + step) / freq);
context.lineTo(wx + i, wvy);
}
context.stroke();
}
function doGenerateHexagonalWave() {
var canvas = document.getElementById("canvas3");
var context = canvas.getContext("2d");
var width = canvas.width;
var height = canvas.height;
var x = width / 8;
var y = height / 2;
var r = (1.5 * height) / 4;
var side = 6;
var freq = 60;
context.clearRect(0, 0, width, height); // Check
drawAxes(context);
drawHexagon(context, x, y, r, side);
getHexagonalWave(context, x, y, r, side, hexStep, freq);
hexStep++;
hexID = window.requestAnimationFrame(doGenerateHexagonalWave);
}
function doStopHexagonalWave() {
window.cancelAnimationFrame(hexID);
}
function doClearHexagonalWave() {
window.cancelAnimationFrame(hexID);
var canvas = document.getElementById("canvas3");
var context = canvas.getContext("2d");
var width = canvas.width;
var height = canvas.height;
context.clearRect(0, 0, width, height);
}
body {
background-color:darkgray;
margin-left: 10px;
}
h1 {
margin: 5px;
}
hr {
border: 1px solid;
}
canvas {
margin: 5px;
margin-bottom: -8px;
background-color:lightgrey;
/*
width: 500px;
height: 100px;
*/
}
p {
margin-left: 5px;
}
<h1>Hexagonal Wave</h1>
<hr>
<div>
</p>
<canvas id="canvas3" width="800" height="200">
</canvas>
<p>
<input type="button" value="Generate" onclick="doGenerateHexagonalWave()"/>
<input type="button" value="Stop" onclick="doStopHexagonalWave()" />
<input type="button" value="Clear" onclick="doClearHexagonalWave()" />
</p>
</div>
How do I get the angles to form straight edges between vertices in the wave by using the variable 'wvx' in the for loop ? Can't seem to figure it out!

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>

Javascript error: Uncaught RangeError: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': Out of memory at ImageData creation

I was writing a simple web app for drawing pictures. I was writing code for a flood fill tool. The tool works for filling small spaces but for big spaces it will fill partway and just stop. I checked the console and it was spammed with errors of
Uncaught RangeError: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': Out of memory at ImageData creation
function move(e, s, c){
if(!e.value)
e.style.right = s + "px";
else
e.style.right = c + "px";
e.value = !e.value;
}
function fixGradient(){
var color1 = 238;
var color2 = 221;
var y = 42;
var height = 50;
var slope = (color1 - color2) / (0 - height);
var intercept = color1 - ((slope) * y);
var screenHeight = window.innerHeight;
var bottomColor = Math.round(slope * screenHeight + intercept);
var color = "rgb(" + bottomColor + ", " + bottomColor + ", " + bottomColor + ")";
document.getElementById("panel").style.backgroundImage = "linear-gradient(#FCFCFC, " + color + ")";
}
var colorValue = "#000000";
function setColor(color){
ctx.fillStyle = color;
ctx.strokeStyle = color;
colorValue = color.toUpperCase();
}
var con = 1 / Math.sqrt(2);
var mouseDown = false;
var click = false;
var size = 2;
var position = [0, 0, 0, 0, 0, 0, 0, 0];
var ctx;
var tool = 0;
var canvas;
var busy = false;
function set(t){
tool = Number(t);
}
function getFile(){
document.getElementById("bgchooser").click();
}
function setBG(e){
/*
var f = new FileReader();
f.readAsDataURL( el("f").files[0] );
f.onload = function(e){
var b64 = e.target.result;
el("loc").value = b64;
change();
}
*/
var file = e.files[0];
var reader = new FileReader(file);
reader.readAsDataURL(file);
reader.onload = function(r){
var b64 = r.target.result;
canvas.style.backgroundImage = "url('" + b64 + "')";
}
}
window.onload = function(){
canvas = document.getElementById("c");
canvas.addEventListener("mousedown", function(){
mouseDown = true;
position[6] = position[0];
position[7] = position[1];
});
window.addEventListener("mouseup", function(){
mouseDown = false;
});
window.addEventListener("keydown", function(e){
var keyCode = e.keyCode || e.which;
if(keyCode == 82){
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
});
canvas.addEventListener("click", function(){
click = true;
});
window.addEventListener("mousemove", function(e){
position[4] = position[2];
position[5] = position[3];
position[2] = position[0];
position[3] = position[1];
position[0] = e.clientX;
position[1] = e.clientY;
});
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
ctx = canvas.getContext("2d");
var scale = [1, 1];
setInterval(function(){
fixGradient();
size = Number(document.getElementById("size").value) * con;
document.getElementById("display").style.height = size + "px";
document.getElementById("liveDisplay").innerHTML = size + "px";
ctx.lineWidth = size;
scale[0] = canvas.width / window.innerWidth;
scale[1] = canvas.height / window.innerHeight;
if(tool==0){
canvas.style.cursor = "url(eyedrop.cur), crosshair";
if(mouseDown){
ctx.beginPath();
ctx.moveTo(position[4] * scale[0], position[5] * scale[1]);
ctx.lineTo(position[2] * scale[0], position[3] * scale[1]);
ctx.lineTo(position[0] * scale[0], position[1] * scale[1]);
ctx.stroke();
//fill gaps
ctx.beginPath();
ctx.arc(position[0] * scale[0], position[1] * scale[1], size / 2, 0, 2 * Math.PI, true);
ctx.fill();
} else {
//if(click&&position[6]==position[0]&&position[7]==position[1]) ctx.fillRect(position[0] * scale[0] - (size / 2), position[1] * scale[1] - (size / 2), size, size);
position[2] = position[0];
position[3] = position[1];
position[4] = position[0];
position[5] = position[1];
click = false;
}
} else if(tool==1){
if(mouseDown){
ctx.clearRect(position[0] * scale[0] - size / 2, position[1] * scale[1] - size / 2, size, size);
}
} else if(tool==2){
var x = position[0];
var y = position[1];
var index = x * 4 + y * canvas.width * 4;
var imgdata = canvas.getImageData(0, 0, canvas.width, canvas.height);
var data = imgdata.data;
} else if(tool==3){
//paint bucket may be taken out or not left in
var x = position[0];
var y = position[1];
var idata;
try{
idata = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
} catch(e){
setTimeout(100);
idata = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
}
var idataindex = 4 * (x + y * canvas.width)
if(mouseDown){
flood(canvas, ctx, x, y, [idata[idataindex], idata[idataindex + 1], idata[idataindex + 2], idata[idataindex + 3]], [255, 0, 0, 255]);
mouseDown = false;
}
}
}, 0);
}
function getPixel(data, x, y, width){
return [data[4 * (y * width + x)], data[4 * (y * width + x) + 1], data[4 * (y * width + x) + 2], data[4 * (y * width + x) + 3]];
}
function scan(x, y, o, n, c, t){
console.log("Scanning: (" + x + ", " + y + "), old=new: " + (o==n) + ", old: " + o + ", new: " + n);
if(o != n){
var data = t.getImageData(0, 0, c.width, c.height).data;
if(y!=0){
var top = getPixel(data, x, y - 1, c.width);
if(top[0] == o[0] && top[1] == o[1] && top[2] == o[2] && top[3] == o[3]){
t.fillRect(x, y - 1, 1, 1);
scan(x, y - 1, o, n, c, t);
}
}
if(x!=c.width){
var right = getPixel(data, x + 1, y, c.width);
if(right[0] == o[0] && right[1] == o[1] && right[2] == o[2] && right[3] == o[3]){
t.fillRect(x + 1, y, 1, 1);
scan(x + 1, y, o, n, c, t);
}
}
if(x!=0){
var left = getPixel(data, x - 1, y, c.width);
if(left[0] == o[0] && left[1] == o[1] && left[2] == o[2] && left[3] == o[3]){
t.fillRect(x - 1, y, 1, 1);
scan(x - 1, y, o, n, c, t);
}
}
if(y!=c.height){
var bottom = getPixel(data, x, y + 1, c.width);
if(bottom[0] == o[0] && bottom[1] == o[1] && bottom[2] == o[2] && bottom[3] == o[3]){
t.fillRect(x, y + 1, 1, 1);
scan(x, y + 1, o, n, c, t);
}
}
}
}
function flood(c, cctx, x, y, oldColor, newColor){
if(!busy){
busy = true;
var oldFill = ctx.fillStyle;
//ctx.fillStyle = "rgb(" + newColor[0] + ", " + newColor[1] + ", " + newColor[2] + ")";
ctx.fillRect(x, y, 1, 1);
scan(x, y, oldColor, newColor, c, ctx);
busy = false;
}
}
body{
margin: 0px;
overflow: hidden;
}
.canvas{
width: 100%;
height: 100%;
position: absolute;
background: white;
cursor: url(aero_pen.cur), crosshair;
}
.button{
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
border: 1px solid #808080;
border-right: medium none;
box-sizing: border-box;
background-image: linear-gradient(#EEEEEE, #DDDDDD);
width: 50px;
height: 50px;
position: absolute;
top: 40px;
right: 0px;
transition: right 0.2s;
z-index: 11;
}
.panel{
border-left: 1px solid #808080;
width: 251px;
box-sizing: border-box;
z-index: 10;
position: absolute;
top: 0px;
right: -251px;
background-image: linear-gradient(#FCFCFC, #262626);
height: 100%;
transition: right 0.2s;
padding-left: 20px;
padding-top: 10px;
padding-right: 20px;
overflow: auto;
padding-bottom: 20px;
}
label{
font-family: Tahoma;
}
input[type=color], input[type=range], input[type=button]{
width: calc(100% - 6px);
}
.display{
width: 100%;
height: 2px;
background-color: black;
border-radius: 4px;
}
select{
width: 100%;
padding: 4px;
font-weight: bold;
appearance: button;
border: 1px inset #808080;
}
option:hover{
background-color: #808080;
color: white;
}
.hidden{
display: none;
}
<!DOCTYPE HTML>
<html>
<head>
<title>Art Program</title>
</head>
<body>
<canvas id="c" class="canvas"></canvas>
<div class="expand button" onclick="move(this, 250, 0); move(document.getElementById('panel'), 0, -251);" value="false"></div>
<div class="panel" value="false" id="panel">
<div>
<label>Color: </label>
<br/>
<input type="color" value="black" onchange="setColor(this.value);"/>
</div>
<hr/>
<div>
<label>Tool: </label>
<br/>
<input type="radio" name="tool" value="0" checked="true" onclick="set(this.value);"/>
<label>Pencil</label><br/>
<input type="radio" name="tool" value="1" onclick="set(this.value);"/>
<label>Eraser</label><br/>
<input type="radio" name="tool" value="2" onclick="set(this.value);"/>
<label>Eyedropper</label><br/>
<input type="radio" name="tool" value="3" onclick="set(this.value);"/>
<label>Flood Fill</label>
</div>
<hr/>
<div>
<label>Background: </label>
<br/>
<input type="file" class="hidden" id="bgchooser" onchange="setBG(this);"/>
<input type="button" value="Choose Background" onclick="getFile();"/>
</div>
<hr/>
<div>
<label>Language: </label>
<br/>
<select>
<option>বাঙালি</option>
<option>English (UK)</option>
<option>English (US)</option>
<option>Español</option>
<option>فُصْحَى</option>
<option>汉语</option>
<option>漢語</option>
<option>हिन्दी</option>
<option>português</option>
</select>
</div>
<hr/>
<div>
<label>Size: </label>
<br/>
<input type="range" min="1" max="100" value="2" id="size"/>
<br/>
<label id="liveDisplay">2</label>
<div class="display" id="display"></div>
</div>
</div>
</body>
</html>
Sorry for the code snippet, but I thought it would be best to put it in all its entirety. Is there a way to prevent these RangeErrors (not SecurityErrors)?
zoomed up slowed down visual

Javascript glitch effect, text is too big, how do I resize?

I've used some code from a Pen I found online to produce a glitch text effect. However, the text is too big for the page, and I don't understand how I can change it.
Here is how the text displays:
too big
Here is how I want it to display:
how I'd like it
Here is the html:
<div class="glitch">
<div id="wrapper">
<canvas id="stage"></canvas>
Css:
.glitch {
background: black;
overflow: hidden;
margin: 0;
padding: 0;
width: 100%;
}
#wrapper {
width: 100%;
padding: 0;
margin: 0 auto;
max-width: 100%;
/*overflow: hidden;*/
text-align: center;
}
img {
display: none;
}
canvas {
box-sizing: border-box;
padding: 0 40px 0 0;
margin: 20px auto 0;
text-align: center;
max-width: 100%;
}
JS:
(function (){
"use strict";
var textSize = 10;
var glitcher = {
init: function () {
setTimeout((function () {
this.canvas = document.getElementById('stage');
this.context = this.canvas.getContext('2d');
this.initOptions();
this.resize();
this.tick();
}).bind(this), 100);
},
initOptions: function () {
var gui = new dat.GUI(),
current = gui.addFolder('Current'),
controls = gui.addFolder('Controls');
this.width = document.documentElement.offsetWidth;
this.height = document.documentElement.offsetHeight;
this.textSize = Math.floor(this.width / 7);
// sets text size based on window size
if (this.textSize > this.height) {
this.textSize = Math.floor(this.height/1.5); }
// tries to make text fit if window is
// very wide, but not very tall
this.font = '900 ' + this.textSize + 'px "Josefin Sans"';
this.context.font = this.font;
this.text = "ROYAL ARCADE";
this.textWidth = (this.context.measureText(this.text)).width;
this.fps = 60;
this.channel = 0; // 0 = red, 1 = green, 2 = blue
this.compOp = 'lighter'; // CompositeOperation = lighter || darker || xor
this.phase = 0.0;
this.phaseStep = 0.05; //determines how often we will change channel and amplitude
this.amplitude = 0.0;
this.amplitudeBase = 2.0;
this.amplitudeRange = 2.0;
this.alphaMin = 0.8;
this.glitchAmplitude = 20.0;
this.glitchThreshold = 0.9;
this.scanlineBase = 40;
this.scanlineRange = 40;
this.scanlineShift = 15;
current.add(this, 'channel', 0, 2).listen();
current.add(this, 'phase', 0, 1).listen();
current.add(this, 'amplitude', 0, 5).listen();
// comment out below to hide ability to change text string
var text = controls.add(this, 'text');
text.onChange((function (){
this.textWidth = (this.context.measureText(this.text)).width;
}).bind(this));
// comment out above to hide ability to change text string
controls.add(this, 'fps', 1, 60);
controls.add(this, 'phaseStep', 0, 1);
controls.add(this, 'alphaMin', 0, 1);
controls.add(this, 'amplitudeBase', 0, 5);
controls.add(this, 'amplitudeRange', 0, 5);
controls.add(this, 'glitchAmplitude', 0, 100);
controls.add(this, 'glitchThreshold', 0, 1);
controls.open();
gui.close(); // start the control panel cloased
},
tick: function () {
setTimeout((function () {
this.phase += this.phaseStep;
if (this.phase > 1) {
this.phase = 0.0;
this.channel = (this.channel === 2) ? 0 : this.channel + 1;
this.amplitude = this.amplitudeBase + (this.amplitudeRange * Math.random());
}
this.render();
this.tick();
}).bind(this), 1000 / this.fps);
},
render: function () {
var x0 = this.amplitude * Math.sin((Math.PI * 2) * this.phase) >> 0,
x1, x2, x3;
if (Math.random() >= this.glitchThreshold) {
x0 *= this.glitchAmplitude;
}
x1 = this.width - this.textWidth >> 1;
x2 = x1 + x0;
x3 = x1 - x0;
this.context.clearRect(0, 0, this.width, this.height);
this.context.globalAlpha = this.alphaMin + ((1 - this.alphaMin) * Math.random());
switch (this.channel) {
case 0:
this.renderChannels(x1, x2, x3);
break;
case 1:
this.renderChannels(x2, x3, x1);
break;
case 2:
this.renderChannels(x3, x1, x2);
break;
}
this.renderScanline();
if (Math.floor(Math.random() * 2) > 1) {
this.renderScanline();
// renders a second scanline 50% of the time
}
},
renderChannels: function (x1, x2, x3) {
this.context.font = this.font;
this.context.fillStyle = "rgb(255,0,0)";
this.context.fillText(this.text, x1, this.height / 2);
this.context.globalCompositeOperation = this.compOp;
this.context.fillStyle = "rgb(0,255,0)";
this.context.fillText(this.text, x2, this.height / 2);
this.context.fillStyle = "rgb(0,0,255)";
this.context.fillText(this.text, x3, this.height / 2);
},
renderScanline: function () {
var y = this.height * Math.random() >> 0,
o = this.context.getImageData(0, y, this.width, 1),
d = o.data,
i = d.length,
s = this.scanlineBase + this.scanlineRange * Math.random() >> 0,
x = -this.scanlineShift + this.scanlineShift * 2 * Math.random() >> 0;
while (i-- > 0) {
d[i] += s;
}
this.context.putImageData(o, x, y);
},
resize: function () {
this.width = document.documentElement.offsetWidth;
//this.height = window.innerHeight;
this.height = document.documentElement.offsetHeight;
if (this.canvas) {
this.canvas.height = this.height;
//document.documentElement.offsetHeight;
this.canvas.width = this.width;
//document.documentElement.offsetWidth;
this.textSize = Math.floor(this.canvas.width / 7);
// RE-sets text size based on window size
if (this.textSize > this.height) {
this.textSize = Math.floor(this.canvas.height/1.5); }
// tries to make text fit if window is
// very wide, but not very tall
this.font = '900 ' + this.textSize + 'px "Josefin Sans"';
this.context.font = this.font;
}
}
};
document.onload = glitcher.init();
window.onresize = glitcher.resize();
// return;
// executes anonymous function onload
})();
Thanks to anyone who can help me
I couldn't figure it out but here's an example of the glitch effect and the problem. Maybe someone can see what's going on here.
(function() {
"use strict";
var textSize = 10;
var glitcher = {
init: function() {
setTimeout((function() {
this.canvas = document.getElementById('stage');
this.context = this.canvas.getContext('2d');
this.initOptions();
this.resize();
this.tick();
}).bind(this), 100);
},
initOptions: function() {
var gui = new dat.GUI(),
current = gui.addFolder('Current'),
controls = gui.addFolder('Controls');
this.width = document.documentElement.offsetWidth;
this.height = document.documentElement.offsetHeight;
this.textSize = Math.floor(this.width / 7);
// sets text size based on window size
if (this.textSize > this.height) {
this.textSize = Math.floor(this.height / 1.5);
}
// tries to make text fit if window is
// very wide, but not very tall
this.font = '900 ' + this.textSize + 'px "Josefin Sans"';
this.context.font = this.font;
this.text = "ROYAL ARCADE";
this.textWidth = (this.context.measureText(this.text)).width;
this.fps = 60;
this.channel = 0; // 0 = red, 1 = green, 2 = blue
this.compOp = 'lighter'; // CompositeOperation = lighter || darker || xor
this.phase = 0.0;
this.phaseStep = 0.05; //determines how often we will change channel and amplitude
this.amplitude = 0.0;
this.amplitudeBase = 2.0;
this.amplitudeRange = 2.0;
this.alphaMin = 0.8;
this.glitchAmplitude = 20.0;
this.glitchThreshold = 0.9;
this.scanlineBase = 40;
this.scanlineRange = 40;
this.scanlineShift = 15;
current.add(this, 'channel', 0, 2).listen();
current.add(this, 'phase', 0, 1).listen();
current.add(this, 'amplitude', 0, 5).listen();
// comment out below to hide ability to change text string
var text = controls.add(this, 'text');
text.onChange((function() {
this.textWidth = (this.context.measureText(this.text)).width;
}).bind(this));
// comment out above to hide ability to change text string
controls.add(this, 'fps', 1, 60);
controls.add(this, 'phaseStep', 0, 1);
controls.add(this, 'alphaMin', 0, 1);
controls.add(this, 'amplitudeBase', 0, 5);
controls.add(this, 'amplitudeRange', 0, 5);
controls.add(this, 'glitchAmplitude', 0, 100);
controls.add(this, 'glitchThreshold', 0, 1);
controls.open();
gui.close(); // start the control panel cloased
},
tick: function() {
setTimeout((function() {
this.phase += this.phaseStep;
if (this.phase > 1) {
this.phase = 0.0;
this.channel = (this.channel === 2) ? 0 : this.channel + 1;
this.amplitude = this.amplitudeBase + (this.amplitudeRange * Math.random());
}
this.render();
this.tick();
}).bind(this), 1000 / this.fps);
},
render: function() {
var x0 = this.amplitude * Math.sin((Math.PI * 2) * this.phase) >> 0,
x1, x2, x3;
if (Math.random() >= this.glitchThreshold) {
x0 *= this.glitchAmplitude;
}
x1 = this.width - this.textWidth >> 1;
x2 = x1 + x0;
x3 = x1 - x0;
this.context.clearRect(0, 0, this.width, this.height);
this.context.globalAlpha = this.alphaMin + ((1 - this.alphaMin) * Math.random());
switch (this.channel) {
case 0:
this.renderChannels(x1, x2, x3);
break;
case 1:
this.renderChannels(x2, x3, x1);
break;
case 2:
this.renderChannels(x3, x1, x2);
break;
}
this.renderScanline();
if (Math.floor(Math.random() * 2) > 1) {
this.renderScanline();
// renders a second scanline 50% of the time
}
},
renderChannels: function(x1, x2, x3) {
this.context.font = this.font;
this.context.fillStyle = "rgb(255,0,0)";
this.context.fillText(this.text, x1, this.height / 2);
this.context.globalCompositeOperation = this.compOp;
this.context.fillStyle = "rgb(0,255,0)";
this.context.fillText(this.text, x2, this.height / 2);
this.context.fillStyle = "rgb(0,0,255)";
this.context.fillText(this.text, x3, this.height / 2);
},
renderScanline: function() {
var y = this.height * Math.random() >> 0,
o = this.context.getImageData(0, y, this.width, 1),
d = o.data,
i = d.length,
s = this.scanlineBase + this.scanlineRange * Math.random() >> 0,
x = -this.scanlineShift + this.scanlineShift * 2 * Math.random() >> 0;
while (i-- > 0) {
d[i] += s;
}
this.context.putImageData(o, x, y);
},
resize: function() {
this.width = document.documentElement.offsetWidth;
//this.height = window.innerHeight;
this.height = document.documentElement.offsetHeight;
if (this.canvas) {
this.canvas.height = this.height;
//document.documentElement.offsetHeight;
this.canvas.width = this.width;
//document.documentElement.offsetWidth;
this.textSize = Math.floor(this.canvas.width / 7);
// RE-sets text size based on window size
if (this.textSize > this.height) {
this.textSize = Math.floor(this.canvas.height / 1.5);
}
// tries to make text fit if window is
// very wide, but not very tall
this.font = '900 ' + this.textSize + 'px "Josefin Sans"';
this.context.font = this.font;
}
}
};
//document.onload = glitcher.init;
glitcher.init();
window.onresize = glitcher.resize;
// return;
// executes anonymous function onload
})();
.glitch {
background: black;
overflow: hidden;
margin: 0;
padding: 0;
width: 100%;
}
#wrapper {
width: 100%;
padding: 0;
margin: 0 auto;
max-width: 100%;
/*overflow: hidden;*/
text-align: center;
}
img {
display: none;
}
canvas {
box-sizing: border-box;
padding: 0 40px 0 0;
margin: 20px auto 0;
text-align: center;
max-width: 100%;
}
<script type="text/javascript" src="https://raw.githubusercontent.com/dataarts/dat.gui/master/build/dat.gui.js"></script>
<div class="glitch">
<div id="wrapper">
<canvas id="stage"></canvas>
</div>
</div>

Categories

Resources