Итак, я сделал эту скрипку, и цель состоит в том, чтобы выделить области человеческого тела, выбрав их соответствующие области в раскрывающемся списке.
На данный момент я сделал следующее:
let coords = {
maleFirst: {
hands: {
left: {
x: 100,
y: 360
},
right: {
x: 280,
y: 360
}
},
foot: {
left: {
x: 180,
y: 590
},
right:{
x: 210,
y: 590
}
}
},
maleSecond: {
hands: {
left: {
x: 365,
y: 360
},
right: {
x: 545,
y: 360
}
},
foot: {
left: {
x: 430,
y: 590
},
right:{
x: 480,
y: 590
}
}
}
}
let draw = (option) => {
let canvas = document.getElementById('canvas');
if (canvas.getContext) {
let ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (option === 'hands') {
coordsDraw(ctx, coords.maleFirst.hands.left.x, coords.maleFirst.hands.left.y);
coordsDraw(ctx, coords.maleFirst.hands.right.x, coords.maleFirst.hands.right.y);
coordsDraw(ctx, coords.maleSecond.hands.left.x, coords.maleSecond.hands.left.y);
coordsDraw(ctx, coords.maleSecond.hands.right.x, coords.maleSecond.hands.right.y);
}
if (option === 'foot') {
coordsDraw(ctx, coords.maleFirst.foot.left.x, coords.maleFirst.foot.left.y);
coordsDraw(ctx, coords.maleFirst.foot.right.x, coords.maleFirst.foot.right.y);
coordsDraw(ctx, coords.maleSecond.foot.left.x, coords.maleSecond.foot.left.y);
coordsDraw(ctx, coords.maleSecond.foot.right.x, coords.maleSecond.foot.right.y);
}
}
}
let coordsDraw = (ctx, x, y) => {
ctx.beginPath();
ctx.fillStyle = '#01567f'; // color of fill
ctx.arc(x, y, 5, 0, 2 * Math.PI);
ctx.fill();
ctx.closePath();
}
document.getElementById('options').addEventListener('change', function () {
draw(this.value)
});
#canvas {
background-image:url('http://www.coloringsky.com/wp-content/uploads/2015/11/How-to-Draw-Human-Body-Coloring-Pages.jpg');
background-repeat:no-repeat;
background-size:contain;
background-position:center;
width: 100%;
}
<select name="options" id="options">
<option value="#">Select option</option>
<option value="hands">hands</option>
<option value="foot">foot</option>
</select>
<br>
<br>
<canvas id="canvas" width="650" height="650"></canvas>
Идея, к которой я стремлюсь, состоит в том, чтобы иметь более «выдающийся» указатель, что-то среди этих строк:
// canvas related variables
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var $canvas = $("#canvas");
var canvasOffset = $canvas.offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;
var scrollX = $canvas.scrollLeft();
var scrollY = $canvas.scrollTop();
// set the context styles
ctx.lineWidth = 1;
ctx.strokeStyle = "gold";
ctx.fillStyle = "#888";
// variables used to draw & animate the ring
var PI2 = Math.PI * 2;
var ringX, ringY, ringRadius, ingCounter, ringCounterVelocity;
var cancelAnimationId;
// fill the canvas with a background color
ctx.fillRect(0, 0, canvas.width, canvas.height);
// tell handleMouseDown to handle all mousedown events
$("#canvas").mousedown(function (e) {
handleMouseDown(e);
});
// set the ring variables and start the animation
function ring(x, y) {
ringX = x;
ringY = y;
ringRadius = 0;
ringCounter = 0;
ringCounterVelocity = 4;
cancelAnimationId = requestAnimationFrame(animate);
}
// the animation loop
function animate() {
// return if the animation is complete
if (ringCounter > 200) {
ringCounter = 0;
}
// otherwise request another animation loop
cancelAnimationId = requestAnimationFrame(animate);
// ringCounter<100 means the ring is expanding
// ringCounter>=100 means the ring is shrinking
if (ringCounter < 100) {
// expand the ring using easeInCubic easing
ringRadius = easeInCubic(ringCounter, 0, 15, 100);
} else {
// shrink the ring using easeOutCubic easing
ringRadius = easeOutCubic(ringCounter - 100, 15, -15, 100);
}
// draw the ring at the radius set using the easing functions
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.arc(ringX, ringY, ringRadius, 0, PI2);
ctx.closePath();
ctx.stroke();
// increment the ringCounter for the next loop
ringCounter += ringCounterVelocity;
}
// Robert Penner's easing functions
//
// https://github.com/danro/jquery-easing/blob/master/jquery.easing.js
//
// now=elapsed time,
// startValue=value at start of easing,
// deltaValue=amount the value will change during the easing,
// duration=total time for easing
function easeInCubic(now, startValue, deltaValue, duration) {
return deltaValue * (now /= duration) * now * now + startValue;
}
function easeOutCubic(now, startValue, deltaValue, duration) {
return deltaValue * ((now = now / duration - 1) * now * now + 1) + startValue;
}
// handle mousedown events
function handleMouseDown(e) {
// tell the browser we'll handle this event
e.preventDefault();
e.stopPropagation();
// calc the mouse position
mouseX = parseInt(e.clientX - offsetX);
mouseY = parseInt(e.clientY - offsetY);
// animate a ring at the mouse position
cancelAnimationFrame(cancelAnimationId);
ring(mouseX, mouseY);
}
#canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h4>Click in the canvas to draw animated circle with easings.</h4>
<canvas id="canvas" width=300 height=300></canvas>
У меня проблемы с адаптацией анимации к тому, что я ищу, так как в итоге возникают ошибки, подобные этим:
let coords = {
maleFirst: {
hands: {
left: {
x: 100,
y: 360
},
right: {
x: 280,
y: 360
}
},
foot: {
left: {
x: 180,
y: 590
},
right:{
x: 210,
y: 590
}
}
},
maleSecond: {
hands: {
left: {
x: 365,
y: 360
},
right: {
x: 545,
y: 360
}
},
foot: {
left: {
x: 430,
y: 590
},
right:{
x: 480,
y: 590
}
}
}
}
let draw = (option) => {
let canvas = document.getElementById('canvas');
if (canvas.getContext) {
let ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (option === 'hands') {
coordsDraw(ctx, coords.maleFirst.hands.left.x, coords.maleFirst.hands.left.y);
coordsDraw(ctx, coords.maleFirst.hands.right.x, coords.maleFirst.hands.right.y);
coordsDraw(ctx, coords.maleSecond.hands.left.x, coords.maleSecond.hands.left.y);
coordsDraw(ctx, coords.maleSecond.hands.right.x, coords.maleSecond.hands.right.y);
}
if (option === 'foot') {
coordsDraw(ctx, coords.maleFirst.foot.left.x, coords.maleFirst.foot.left.y);
coordsDraw(ctx, coords.maleFirst.foot.right.x, coords.maleFirst.foot.right.y);
coordsDraw(ctx, coords.maleSecond.foot.left.x, coords.maleSecond.foot.left.y);
coordsDraw(ctx, coords.maleSecond.foot.right.x, coords.maleSecond.foot.right.y);
}
}
}
var ringRadius = 0, ringCounter = 0, ringCounterVelocity = 4;
let coordsDraw = (ctx, x, y) => {
if (ringCounter > 200) {
ringCounter = 0;
}
// otherwise request another animation loop
cancelAnimationId = requestAnimationFrame(coordsDraw(ctx, x, y));
// ringCounter<100 means the ring is expanding
// ringCounter>=100 means the ring is shrinking
if (ringCounter < 100) {
// expand the ring using easeInCubic easing
ringRadius = easeInCubic(ringCounter, 0, 15, 100);
} else {
// shrink the ring using easeOutCubic easing
ringRadius = easeOutCubic(ringCounter - 100, 15, -15, 100);
}
ctx.beginPath();
ctx.fillStyle = '#01567f'; // color of fill
ctx.arc(x, y, ringRadius, 0, 2 * Math.PI);
ctx.fill();
ctx.closePath();
ringCounter += ringCounterVelocity;
}
function easeInCubic(now, startValue, deltaValue, duration) {
return deltaValue * (now /= duration) * now * now + startValue;
}
function easeOutCubic(now, startValue, deltaValue, duration) {
return deltaValue * ((now = now / duration - 1) * now * now + 1) + startValue;
}
document.getElementById('options').addEventListener('change', function () {
draw(this.value)
});
#canvas {
background-image:url('http://www.coloringsky.com/wp-content/uploads/2015/11/How-to-Draw-Human-Body-Coloring-Pages.jpg');
background-repeat:no-repeat;
background-size:contain;
background-position:center;
width: 100%;
}
<select name="options" id="options">
<option value="#">Select option</option>
<option value="hands">hands</option>
<option value="foot">foot</option>
</select>
<br>
<br>
<canvas id="canvas" width="650" height="650"></canvas>
Uncaught RangeError: Maximum call stack size exceeded
at coordsDraw (select.js:299)
Любая помощь будет принята с благодарностью