Create a button out of a javascript canvas object - javascript

function draw() {
var canvas = document.getElementById('navigation');
if(canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.beginPath();
//shape 1
ctx.moveTo(300, 1120);
ctx.lineTo(230, 1070);
ctx.lineTo(160, 880);
ctx.lineTo(170, 770);
ctx.lineTo(260, 640);
ctx.lineTo(350, 710);
ctx.lineTo(360, 820);
//shape 2
ctx.moveTo(340, 1050);
ctx.lineTo(390, 820);
ctx.lineTo(450, 710);
ctx.lineTo(450, 810);
ctx.fill();
}
}
<html>
<head>
</head>
<body onload="draw();">
<canvas id="navigation" width="1500" height="1500"></canvas>
</body>
</html>
I've got this snippet of code, and I was wondering if it's possible to make Shape 1 and Shape 2 independently clickable buttons, each redirecting to a different webpage.

Here is another way of achieving it... instead of using canvas here the svg object gets used... though using an experimental feature (clip-path, css property)
<style type="text/css">
body { margin: 0; }
</style>
<style type="text/css">
svg {
display: block;
height: 0;
}
</style>
<svg>
<defs>
<clipPath id="c1">
<path
d="
M 300, 1120
L 230, 1070
L 160, 880
L 170, 770
L 260, 640
L 350, 710
L 360, 820
Z
M 340, 1050
L 390, 820
L 450, 710
L 450, 810
Z
"/>
</clipPath>
</defs>
</svg>
<style type="text/css">
a {
display: block;
width: 1500px;
height: 1500px;
background: black;
transition: all .2s;
font-size: 0;
clip-path: url(#c1);
}
a:hover {
background: lime;
}
</style>
Click me...

Related

Dashed path using SVG

I followed this and made my own svg path scroll. I achieved the animation but I can seem to find that why the dashes are not appearing on the line. I tried different things but still could not find any solution. Please can some one help.
// Get the id of the <path> element and the length of <path>
var myline = document.getElementById("myline");
var length = myline.getTotalLength();
circle = document.getElementById("circle");
// The start position of the drawing
myline.style.strokeDasharray = length;
// Hide the triangle by offsetting dash. Remove this line to show the triangle before scroll draw
myline.style.strokeDashoffset = length;
// Find scroll percentage on scroll (using cross-browser properties), and offset dash same amount as percentage scrolled
window.addEventListener("scroll", myFunction);
function myFunction() {
// What % down is it?
var scrollpercent = (document.body.scrollTop + document.documentElement.scrollTop * 4) / (document.documentElement.scrollHeight - document.documentElement.clientHeight);
// Length to offset the dashes
var draw = length * scrollpercent;
// Reverse the drawing (when scrolling upwards)
myline.style.strokeDashoffset = length - draw;
//get point at length
endPoint = myline.getPointAtLength(draw);
circle.setAttribute("cx", endPoint.x);
circle.setAttribute("cy", endPoint.y);
}
body {
height: 2000px;
background: #f1f1f1;
}
#circle {
fill: #000;
}
#myLine {
stroke-dasharray: 8;
}
#mySVG {
position: relative;
top: 10%;
width: 90vw;
height: 90vh;
margin-left: -50px;
}
.st0 {
fill: none;
stroke-dashoffset: 3px;
stroke: green;
stroke-width: 5;
stroke-miterlimit: 10;
stroke-dasharray: 20;
}
.mask-style {
stroke: white;
stroke-width: 7;
}
<svg id="mySVG" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 420.099 699.491" style="padding-bottom: 0%; overflow: visible;">
<defs>
<mask id="dash-mask">
<path class="st0 mask-style" stroke-dasharray="10,9" d="M5381.266 335.957s-105.8-62.765-170.449 28.765-63.274 160.934 0 354.388 31.274 395.636-229.089 232.727" transform="translate(-4980.932 -313.455)"/>
</mask>
</defs>
<circle id="circle" cx="404" cy="20" r="8"/>
<path id="myline" class="st0" stroke-dasharray="10,9" d="M5381.266 335.957s-105.8-62.765-170.449 28.765-63.274 160.934 0 354.388 31.274 395.636-229.089 232.727" transform="translate(-4980.932 -313.455)" />
</svg>
So what i am trying is to just make the path dashed.
You need to construct the correct stroke-dash-array - right now the CSS specified stroke dasharray (10,9) is being over-written by myline.style.strokeDasharray = length. That needs to be something like "10, 9, 10, 9, 10, 9, 10,9, 10,9" + length - so the part of the line that is being hidden by the offset has an appropriate dash.
The following tweak is not completely correct - you need to write some code to construct the correct dash-array - but it should give you the idea.
// Get the id of the <path> element and the length of <path>
var myline = document.getElementById("myline");
var length = myline.getTotalLength();
circle = document.getElementById("circle");
// The start position of the drawing
myline.style.strokeDasharray = "0, " + length + " ,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9 " + length;
// Hide the triangle by offsetting dash. Remove this line to show the triangle before scroll draw
myline.style.strokeDashoffset = length;
// Find scroll percentage on scroll (using cross-browser properties), and offset dash same amount as percentage scrolled
window.addEventListener("scroll", myFunction);
function myFunction() {
// What % down is it?
var scrollpercent = (document.body.scrollTop + document.documentElement.scrollTop * 4) / (document.documentElement.scrollHeight - document.documentElement.clientHeight);
// Length to offset the dashes
var draw = length * scrollpercent;
// Reverse the drawing (when scrolling upwards)
myline.style.strokeDashoffset = length - draw;
//get point at length
endPoint = myline.getPointAtLength(draw);
circle.setAttribute("cx", endPoint.x);
circle.setAttribute("cy", endPoint.y);
}
body {
height: 2000px;
background: #f1f1f1;
}
#circle {
fill: #000;
}
#myLine {
stroke-dasharray: 8;
}
#mySVG {
position: relative;
top: 10%;
width: 90vw;
height: 90vh;
margin-left: -50px;
}
.st0 {
fill: none;
stroke-dashoffset: 3px;
stroke: green;
stroke-width: 5;
stroke-miterlimit: 10;
stroke-dasharray: 20;
}
.mask-style {
stroke: white;
stroke-width: 7;
}
<svg id="mySVG" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 420.099 699.491" style="padding-bottom: 0%; overflow: visible;">
<defs>
<mask id="dash-mask">
<path class="st0 mask-style" stroke-dasharray="10,9" d="M5381.266 335.957s-105.8-62.765-170.449 28.765-63.274 160.934 0 354.388 31.274 395.636-229.089 232.727" transform="translate(-4980.932 -313.455)"/>
</mask>
</defs>
<circle id="circle" cx="404" cy="20" r="8"/>
<path id="myline" class="st0" stroke-dasharray="10,9" d="M5381.266 335.957s-105.8-62.765-170.449 28.765-63.274 160.934 0 354.388 31.274 395.636-229.089 232.727" transform="translate(-4980.932 -313.455)" />
</svg>

Based on this SVG how do I isolate the neck area from the head

I was attempting to improve this body rendering model.
https://github.com/volcanioo/Human-Body-Rendering-HTML
But I was trying to add some more detail. I started by isolating the neck from the head.
So I figured out that the paths for drawing the neck is this.
<svg data-position='neck' id='neck' class='neck' xmlns='http://www.w3.org/2000/svg' width='56.594' height='95.031' viewBox='0 0 56.594 95.031'><path d='M15.92 68.5l8.8 12.546 3.97 13.984-9.254-7.38-4.622-15.848zm27.1 0l-8.8 12.546-3.976 13.988 9.254-7.38 4.622-15.848z'/></svg>
But as it happens now if I try to do this it will actually block the head area from being clicked.
Screencaps don't show it but I am hovering my cursor over the head.
Also another note is that when I separate the head from the neck, the hair goes funky as shown below.
Any help to isolate the neck from the head will be a big help.
Ill post the js, html and css files with my changes and explanations below.
window.onload = function () {
const pieces = document.getElementsByTagName('svg');
for (var i = 0; pieces.length; i++) {
let _piece = pieces[i];
_piece.onclick = function(t) {
if (t.target.getAttribute('data-position') != null) document.getElementById('data').innerHTML = t.target.getAttribute('data-position');
if (t.target.parentElement.getAttribute('data-position') != null) document.getElementById('data').innerHTML = t.target.parentElement.getAttribute('data-position');
}
}
}
.human-body {
width: 207px;
position: relative;
padding-top: 240px;
height: 260px;
display: block;
margin: 40px auto;
}
.human-body svg:hover {
cursor: pointer;
}
.human-body svg:hover path {
fill: #ff7d16;
}
.human-body svg {
position: absolute;
left: 50%;
fill: #57c9d5;
}
.human-body svg#head {
margin-left: -28.5px;
top: -6px;
}
.human-body svg#neck {
margin-left: -28.5px;
top: -6px;
}
.human-body svg#left-shoulder {
margin-left: -53.5px;
top: 69px;
}
.human-body svg#right-shoulder {
margin-left: 13.5px;
top: 69px;
}
.human-body svg#left-arm {
margin-left: -78px;
top: 112px;
}
.human-body svg#right-arm {
margin-left: 38px;
top: 112px;
z-index: 10001;
}
.human-body svg#chest {
margin-left: -43.5px;
top: 88px;
}
.human-body svg#stomach {
margin-left: -37.5px;
top: 130px;
}
.human-body svg#left-leg {
margin-left: -46.5px;
top: 205px;
z-index: 9999;
}
.human-body svg#right-leg {
margin-left: 1.5px;
top: 205px;
z-index: 9999;
}
.human-body svg#left-hand {
margin-left: -102.5px;
top: 224px;
}
.human-body svg#right-hand {
margin-left: 66.5px;
top: 224px;
z-index: 10000;
}
.human-body svg#left-foot {
margin-left: -35.5px;
top: 455px;
}
.human-body svg#right-foot {
margin-left: 5.5px;
top: 455px;
}
#area {
display: block;
width: 100%;
clear: both;
padding: 10px;
text-align: center;
font-size: 25px;
font-family: Courier New;
color: #a5a5a5;
}
#area #data {
color: black;
}
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Meta Tags -->
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<!-- Stylesheet Docs -->
<link rel="stylesheet" href="index.css">
<!-- Javascript Docs -->
<script type="text/javascript" src="index.js"></script>
</head>
<body>
<!-- Human Body //-->
<div class="human-body">
<svg data-position='head' id='head' class='head' xmlns='http://www.w3.org/2000/svg' width='56.594' height='95.031' viewBox='0 0 56.594 95.031'><path d='m27.1 0l-8.8 12.546-3.976 13.988 9.254-7.38 4.622-15.848zm6.11-27.775l.108-11.775-21.16-14.742L8.123 26.133 8.09 40.19l-3.24.215 1.462 9.732 5.208 1.81 2.36 11.63 9.72 11.018 10.856-.324 9.56-10.37 1.918-11.952 5.207-1.81 1.342-9.517zm-43.085-1.84l-.257-13.82L28.226 11.9l23.618 15.755-.216 10.37 4.976-17.085L42.556 2.376 25.49 0 10.803 3.673.002 24.415z'/></svg>
<svg data-position='neck' id='neck' class='neck' xmlns='http://www.w3.org/2000/svg' width='56.594' height='95.031' viewBox='0 0 56.594 95.031'><path d='M15.92 68.5l8.8 12.546 3.97 13.984-9.254-7.38-4.622-15.848zm27.1 0l-8.8 12.546-3.976 13.988 9.254-7.38 4.622-15.848z'/></svg>
<svg data-position='left-shoulder' id='left-shoulder' class='left-shoulder' xmlns='http://www.w3.org/2000/svg' width='109.532' height='46.594' viewBox='0 0 109.532 46.594'><path d='m 38.244,-0.004 1.98,9.232 -11.653,2.857 -7.474,-2.637 z M 17.005,10.536 12.962,8.35 0.306,22.35 0.244,27.675 c 0,0 16.52,-17.015 16.764,-17.14 z m 1.285,0.58 C 18.3,11.396 0.528,30.038 0.528,30.038 L -0.01,46.595 6.147,36.045 18.017,30.989 26.374,15.6 Z'/></svg>
<svg data-position='right-shoulder' id='right-shoulder' class='right-shoulder' xmlns='http://www.w3.org/2000/svg' width='109.532' height='46.594' viewBox='0 0 109.532 46.594'><path d='m 3.2759972,-0.004 -1.98,9.232 11.6529998,2.857 7.473999,-2.637 z m 21.2379988,10.54 4.044,-2.187 12.656,14 0.07,5.33 c 0,0 -16.524,-17.019 -16.769,-17.144 z m -1.285,0.58 c -0.008,0.28 17.762,18.922 17.762,18.922 l 0.537,16.557 -6.157,-10.55 -11.871,-5.057 L 15.147997,15.6 Z'/></svg>
<svg data-position='left-arm' id='left-arm' class='left-arm' xmlns='http://www.w3.org/2000/svg' width='156.344' height='119.25' viewBox='0 0 156.344 119.25'><path d='m21.12,56.5a1.678,1.678 0 0 1 -0.427,0.33l0.935,8.224l12.977,-13.89l1.2,-8.958a168.2,168.2 0 0 0 -14.685,14.294zm1.387,12.522l-18.07,48.91l5.757,1.333l19.125,-39.44l3.518,-22.047l-10.33,11.244zm-5.278,-18.96l2.638,18.74l-17.2,46.023l-2.657,-1.775l6.644,-35.518l10.575,-27.47zm18.805,-12.323a1.78,1.78 0 0 1 0.407,-0.24l3.666,-27.345l-7.037,-10.139l-7.258,10.58l-6.16,37.04l0.566,4.973a151.447,151.447 0 0 1 15.808,-14.87l0.008,0.001zm-13.742,-28.906l-3.3,35.276l-2.2,-26.238l5.5,-9.038z'/></svg>
<svg data-position='right-arm' id='right-arm' class='right-arm' xmlns='http://www.w3.org/2000/svg' width='156.344' height='119.25' viewBox='0 0 156.344 119.25'><path d='m 18.997,56.5 a 1.678,1.678 0 0 0 0.427,0.33 L 18.489,65.054 5.512,51.164 4.312,42.206 A 168.2,168.2 0 0 1 18.997,56.5 Z m -1.387,12.522 18.07,48.91 -5.757,1.333 L 10.798,79.825 7.28,57.778 17.61,69.022 Z m 5.278,-18.96 -2.638,18.74 17.2,46.023 2.657,-1.775 L 33.463,77.532 22.888,50.062 Z M 4.083,37.739 A 1.78,1.78 0 0 0 3.676,37.499 L 0.01,10.154 7.047,0.015 l 7.258,10.58 6.16,37.04 -0.566,4.973 A 151.447,151.447 0 0 0 4.091,37.738 l -0.008,10e-4 z m 13.742,-28.906 3.3,35.276 2.2,-26.238 -5.5,-9.038 z'/></svg>
<svg data-position='chest' id='chest' class='chest' xmlns='http://www.w3.org/2000/svg' width='86.594' height='45.063' viewBox='0 0 86.594 45.063'><path d='M19.32 0l-9.225 16.488-10.1 5.056 6.15 4.836 4.832 14.07 11.2 4.616 17.85-8.828-4.452-34.7zm47.934 0l9.225 16.488 10.1 5.056-6.15 4.836-4.833 14.07-11.2 4.616-17.844-8.828 4.45-34.7z'/></svg>
<svg data-position='stomach' id='stomach' class='stomach' xmlns='http://www.w3.org/2000/svg' width='75.25' height='107.594' viewBox='0 0 75.25 107.594'><path d='M19.25 7.49l16.6-7.5-.5 12.16-14.943 7.662zm-10.322 8.9l6.9 3.848-.8-9.116zm5.617-8.732L1.32 2.15 6.3 15.6zm-8.17 9.267l9.015 5.514 1.54 11.028-8.795-5.735zm15.53 5.89l.332 8.662 12.286-2.665.664-11.826zm14.61 84.783L33.28 76.062l-.08-20.53-11.654-5.736-1.32 37.5zM22.735 35.64L22.57 46.3l11.787 3.166.166-16.657zm-14.16-5.255L16.49 35.9l1.1 11.25-8.8-7.06zm8.79 22.74l-9.673-7.28-.84 9.78L-.006 68.29l10.564 14.594 5.5.883 1.98-20.735zM56 7.488l-16.6-7.5.5 12.16 14.942 7.66zm10.32 8.9l-6.9 3.847.8-9.116zm-5.617-8.733L73.93 2.148l-4.98 13.447zm8.17 9.267l-9.015 5.514-1.54 11.03 8.8-5.736zm-15.53 5.89l-.332 8.662-12.285-2.665-.664-11.827zm-14.61 84.783l3.234-31.536.082-20.532 11.65-5.735 1.32 37.5zm13.78-71.957l.166 10.66-11.786 3.168-.166-16.657zm14.16-5.256l-7.915 5.514-1.1 11.25 8.794-7.06zm-8.79 22.743l9.673-7.28.84 9.78 6.862 12.66-10.564 14.597-5.5.883-1.975-20.74z'/></svg>
<svg data-position='left-leg' id='left-leg' class='left-leg' xmlns='http://www.w3.org/2000/svg' width='93.626' height='250.625' viewBox='0 0 93.626 250.625'><path d='m 18.00179,139.99461 -0.664,5.99 4.647,5.77 1.55,9.1 3.1,1.33 2.655,-13.755 1.77,-4.88 -1.55,-3.107 z m 20.582,0.444 -3.32,9.318 -7.082,13.755 1.77,12.647 5.09,-14.2 4.205,-7.982 z m -26.557,-12.645 5.09,27.29 -3.32,-1.777 -2.656,8.875 z m 22.795,42.374 -1.55,4.88 -3.32,20.634 -0.442,27.51 4.65,26.847 -0.223,-34.39 4.87,-13.754 0.663,-15.087 z m -10.623,12.424 1.106,41.267 c 14.157565,64.57987 -5.846437,10.46082 -16.8199998,-29.07 l 5.5329998,-36.384 z m -9.71,-178.164003 0,22.476 15.71,31.073 9.923,30.850003 -1.033,-21.375 z m 25.49,30.248 0.118,-0.148 -0.793,-2.024 -16.545,-18.16 -1.242,-0.44 10.984,28.378 z m -6.255,10.766 6.812,17.6 2.274,-21.596 -1.344,-3.43 z m -26.4699998,17.82 0.827,25.340003 12.8159998,35.257 -3.928,10.136 -12.6099998,-44.51 z M 31.81879,76.04161 l 0.345,0.826 6.47,15.48 -4.177,38.342 -6.594,-3.526 5.715,-35.7 z m -21.465,-74.697003 0.827,21.373 L 4.1527902,65.02561 0.84679017,30.870607 Z m 2.068,27.323 14.677,32.391 3.307,26.000003 -6.2,36.58 -13.437,-37.241 -0.8269998,-38.342003 z'/></svg>
<svg data-position='right-leg' id='right-leg' class='right-leg' xmlns='http://www.w3.org/2000/svg' width='80' height='250.625' viewBox='0 0 80 250.625'><path d='m 26.664979,139.7913 0.663,5.99 -4.647,5.77 -1.55,9.1 -3.1,1.33 -2.655,-13.755 -1.77,-4.88 1.55,-3.107 z m -20.5820002,0.444 3.3200005,9.318 7.0799997,13.755 -1.77,12.647 -5.0899997,-14.2 -4.2000005,-7.987 z m 3.7620005,29.73 1.5499997,4.88 3.32,20.633 0.442,27.51 -4.648,26.847 0.22,-34.39 -4.8670002,-13.754 -0.67,-15.087 z m 10.6229997,12.424 -1.107,41.267 -8.852,33.28 9.627,-4.55 16.046,-57.8 -5.533,-36.384 z m -13.9460002,74.991 c -5.157661,19.45233 -2.5788305,9.72616 0,0 z M 30.177979,4.225305 l 0,22.476 -15.713,31.072 -9.9230002,30.850005 1.033,-21.375005 z m -25.4930002,30.249 -0.118,-0.15 0.793,-2.023 16.5450002,-18.16 1.24,-0.44 -10.98,28.377 z m 6.2550002,10.764 -6.8120002,17.6 -2.274,-21.595 1.344,-3.43 z m 26.47,17.82 -0.827,25.342005 -12.816,35.25599 3.927,10.136 12.61,-44.50999 z m -24.565,12.783005 -0.346,0.825 -6.4700002,15.48 4.1780002,38.34199 6.594,-3.527 -5.715,-35.69999 z m 19.792,51.74999 -5.09,27.29 3.32,-1.776 2.655,8.875 z m 1.671,-126.452995 -0.826,21.375 7.03,42.308 3.306,-34.155 z m -2.066,27.325 -14.677,32.392 -3.308,26.000005 6.2,36.57999 13.436,-37.23999 0.827,-38.340005 z'/></svg>
<svg data-position='left-hand' id='left-hand' class='left-hand' xmlns='http://www.w3.org/2000/svg' width='90' height='38.938' viewBox='0 0 90 38.938'><path d='m 21.255,-0.00198191 2.88,6.90000201 8.412,1.335 0.664,12.4579799 -4.427,17.8 -2.878,-0.22 2.8,-11.847 -2.99,-0.084 -4.676,12.6 -3.544,-0.446 4.4,-12.736 -3.072,-0.584 -5.978,13.543 -4.428,-0.445 6.088,-14.1 -2.1,-1.25 L 4.878,34.934 1.114,34.489 12.4,12.9 11.293,11.12 0.665,15.57 0,13.124 8.635,5.3380201 Z' /></svg>
<svg data-position='right-hand' id='right-hand' class='right-hand' xmlns='http://www.w3.org/2000/svg' width='90' height='38.938' viewBox='0 0 90 38.938'><path d='m 13.793386,-0.00198533 -2.88,6.90000163 -8.4120002,1.335 -0.664,12.4579837 4.427,17.8 2.878,-0.22 -2.8,-11.847 2.99,-0.084 4.6760002,12.6 3.544,-0.446 -4.4,-12.736 3.072,-0.584 5.978,13.543 4.428,-0.445 -6.088,-14.1 2.1,-1.25 7.528,12.012 3.764,-0.445 -11.286,-21.589 1.107,-1.78 10.628,4.45 0.665,-2.447 -8.635,-7.7859837 z'/></svg>
<svg data-position='left-foot' id='left-foot' class='left-foot' xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'><path d='m 19.558357,1.92821 c -22.1993328,20.55867 -11.0996668,10.27933 0,0 z m 5.975,5.989 -0.664,18.415 -1.55,6.435 -4.647,0 -1.327,-4.437 -1.55,-0.222 0.332,4.437 -5.864,-1.778 -1.5499998,-0.887 -6.64,-1.442 -0.22,-5.214 6.418,-10.87 4.4259998,-5.548 c 9.991542,-3.26362 9.41586,-8.41457 12.836,1.111 z'/></svg>
<svg data-position='right-foot' id='right-foot' class='right-foot' xmlns='http://www.w3.org/2000/svg' width='90' height='38.938' viewBox='0 0 90 38.938'><path d='m 11.723492,2.35897 c -40.202667,20.558 -20.1013335,10.279 0,0 z m -5.9740005,5.989 0.663,18.415 1.546,6.435 4.6480005,0 1.328,-4.437 1.55,-0.222 -0.333,4.437 5.863,-1.778 1.55,-0.887 6.638,-1.442 0.222,-5.214 -6.418,-10.868 -4.426,-5.547 -10.8440005,-4.437 z'/> </svg>
</div>
<!--// Human Body -->
<!-- Data Showing //-->
<div id="area">
Area: <span id="data"></span>
</div>
<!--// Data Showing -->
</body>
</html>
index.js - No changes have been made as the JS doesn't affect the functionality.
index.css - I have made changes to this, I added the section for the neck. I have played with the margin left and top value to see if it fixes the neck problems to no avail.
index.html - The only change I have made here was removing the path for the neck section and adding it to its own element.
I have played with the viewbox size as well as the necks own width and height so that head can be clicked but it seems to either disappear or not do anything.
The uncaught typeError shouldn't stop you from seeing it not working.
Any help from any web dev wizards would be fantastic.
Ill be floating around to answer any clarifications.
Thank you.

Fill SVG by dragging pointer

I want to fill color in number shown in image by dragging the green circle onto white path(it should fill with solid color from behind as dragged). I have used SVG and path also drawn in it. The draggable circle is also part of same SVG.
I am open if this can be done without SVG in any way.
Tried making it on canvas but gave that up because i could not drag there on given path.
My code below
var data = Snap.path.toCubic(document.getElementById("path2").getAttribute('d'))
dataLength = data.length,
svgPoints = [],
pointsString = data.toString();
for (var i = 0; i < dataLength; i++) {
var seg = data[i];
if (seg[0] === "M") {
var point = {};
point.x = seg[1];
point.y = seg[2];
svgPoints.push(point);
} else {
for (var j = 1; j < 6; j += 2) {
var point = {};
point.x = seg[j];
point.y = seg[j + 1];
svgPoints.push(point);
}
}
}
TweenMax.set('.knob', { x: svgPoints[0].x, y: svgPoints[0].y })
var circle = document.querySelector(".knob");
var path2 = document.querySelector("#path2");
var insidePath = false;
var lastPoint = {
x: 0,
y: 0
};
var draggable = new Draggable(circle, {
liveSnap: {
points: svgPoints
},
});
body {
background-color: #222;
background-color: rgb(145, 140, 140);
text-align: center;
overflow: hidden;
}
svg {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
#DiacoDesignLink,
#pens {
color: #fff;
}
<div id="container">
<svg id="Layer_1" x="0px" y="0px" width="159.129px" height="220px" viewBox="0 0 159.129 220"
enable-background="new 0 0 159.129 220" xml:space="preserve">
<g>
<g>
<g>
<g>
<path id="path1" fill-opacity="0.1" fill="#492015" stroke="#492015" stroke-width="2" d="M53.336,203.653c-1.298,0-3.084-0.039-5.461-0.119c-2.436-0.092-4.921-0.256-7.395-0.49
c-2.684-0.266-5.221-0.662-7.548-1.18c-2.998-0.666-5.336-1.623-7.147-2.926l-0.36-0.279c-1.794-1.531-3.288-3.475-4.511-5.83
c-1.01-1.92-1.9-4.066-2.642-6.373c-0.721-2.264-1.263-4.492-1.613-6.627c-0.367-2.186-0.554-4.188-0.554-5.945
c0-2.816,0.369-5.453,1.099-7.838c0.847-2.793,2.447-5.379,4.756-7.684c1.762-1.918,3.827-4.025,5.917-6.033
c2.04-1.969,3.972-3.863,5.738-5.629c2.023-2.174,4.901-5.242,8.487-9.061c3.534-3.768,7.361-8.021,11.374-12.639
c4.066-4.686,8.16-9.631,12.166-14.693c4.017-5.078,7.734-10.098,11.048-14.923c3.221-4.68,5.838-9.098,7.779-13.133
c1.644-3.399,2.512-6.299,2.512-8.391c0-1.375-0.297-2.325-0.962-3.083c-0.221-0.251-0.635-0.722-2.141-0.722
c-1.746,0-3.323,0.636-4.961,2.002c-2.642,2.201-5.342,4.639-8.025,7.248c-2.993,2.908-6.243,5.651-9.661,8.153
c-4.309,3.15-9.24,4.747-14.658,4.747c-6.606,0-11.969-2.07-15.938-6.153c-3.917-4.03-5.903-9.309-5.903-15.689
c0-7.845,1.773-15.239,5.271-21.979c3.415-6.558,7.982-12.276,13.577-16.998c5.478-4.625,11.74-8.323,18.614-10.99
c6.923-2.688,14.141-4.051,21.452-4.051c7.213,0,14.054,0.86,20.332,2.555c6.559,1.773,12.347,4.586,17.204,8.36
c4.975,3.873,8.934,8.849,11.769,14.79c2.816,5.913,4.244,13.005,4.244,21.083c0,6.229-1.081,12.806-3.213,19.55
c-2.046,6.456-4.772,13.028-8.104,19.534c-3.281,6.397-7.097,12.851-11.34,19.187c-4.183,6.23-8.548,12.273-12.975,17.967
c-4.371,5.615-8.796,10.916-13.156,15.758c2.113-0.24,4.252-0.48,6.417-0.719c8.575-0.955,16.974-1.439,24.959-1.439
c5.866,0,11.098,1.627,15.549,4.834c3.51,2.535,7.691,7.381,7.691,16.078c0,6.324-2.168,11.586-6.443,15.639
c-3.863,3.66-8.569,6.025-13.99,7.029c-4.546,1.066-10.146,2.094-16.107,2.953c-5.981,0.865-12.153,1.623-18.343,2.25
c-6.219,0.625-12.399,1.102-18.374,1.422C63.655,203.493,58.127,203.653,53.336,203.653z" />
</g>
</g>
</g>
</g>
<path id="path2" fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-miterlimit="10" d="M40.059,71.082
c0,0,13.449-34.797,52.919-31.959c13.451,0.967,33.333,16,11.667,52.667c0,0-26.563,43.722-48,64.999
c-4.263,4.23-20.334,22.002,1,24.002c0,0,31.666,3,72.333-11.668" />
<circle class="knob" r="25" fill="#88CE02" stroke-width="4" stroke="#fff" />
</svg>
</div>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/TweenMax.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/utils/Draggable.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.3.0/snap.svg-min.js"></script>
<script type="text/javascript" src="./sketch.js"></script>

gsap rotation - how to avoid sharp transitions

Could someone help me make this swing more fluently, without this sharp transitions from one direction to another? The animation should be like a swing on wind.
const stepDuration = 0.5, wing = '#wing';
gsap.set(wing, {transformOrigin: "50% 0%", rotation: 15})
const walk = () => {gsap.timeline({repeat: -1, defaults: { ease: "circ.inOut", duration: stepDuration }})
.add('start')
.to(wing, { rotation: -15 })
.to(wing, { rotation: 15 })
}
window.onload = () => {walk()};
svg {
position: fixed;
left: 50vw;
top: 25px;
width: 70%;
height: 70%;
animation: a01 9s;
background: #0099cc;
}
#wing {
fill: gold;
transform-origin: top center;
animation: awinga 25s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.0.4/gsap.min.js"></script>
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/MotionPathPlugin.min.js?v=15"></script>
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" version="1.1" viewBox="0 0 1280 720">
<path id='wing' d="M100 0 L150 0 L150 300 L100 300 Z" />
</svg>
<script>
</script>
What you want is basically a tweening/easing function that tapers out at the start and at the end, without a sharp gradient in between. The reason of your jerking is because for the circ.inOut easing, there is basically an infinitesimally small period of time where the gradient is infinite (right at the 50% mark), which causes the sharp jerking you see when it's mid-tween (right when your element rotates past the vertical midline):
Therefore, you should pick an easing function that doesn't have that abrupt change in the middle, e.g. power1.inOut or the likes of it:
[
const stepDuration = 0.5, wing = '#wing';
gsap.set(wing, {transformOrigin: "50% 0%", rotation: 15})
const walk = () => {gsap.timeline({repeat: -1, defaults: { ease: "power1.inOut", duration: stepDuration }})
.add('start')
.to(wing, { rotation: -15 })
.to(wing, { rotation: 15 })
}
window.onload = () => {walk()};
svg {
position: fixed;
left: 50vw;
top: 25px;
width: 70%;
height: 70%;
animation: a01 9s;
background: #0099cc;
}
#wing {
fill: gold;
transform-origin: top center;
animation: awinga 25s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.0.4/gsap.min.js"></script>
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/MotionPathPlugin.min.js?v=15"></script>
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" version="1.1" viewBox="0 0 1280 720">
<path id='wing' d="M100 0 L150 0 L150 300 L100 300 Z" />
</svg>
<script>
</script>

Can an SVG background be interactive?

I have an SVG image that I created. It is a rectangle with a circle inside it. The circle follows the users mouse using JavaScript. The image is represented by the following code:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlspace="preserve" preserveAspectRatio="xMidYMin slic">
<style>
* { vector-effect:non-scaling-stroke }
rect { fill: blue; }
circle { fill:orange; opacity:0.75; }
</style>
<rect cx="50%" cy="0" width="720" height="1278" id="origin" />
<circle cx="50%" cy="116" r="72" id="dot" />
<script>
var svg = document.documentElement,
pt = svg.createSVGPoint(),
dot = document.querySelector('#dot');
svg.addEventListener('mousemove',function(evt){
var loc = cursorPoint(evt);
dot.setAttribute('cx',loc.x);
dot.setAttribute('cy',loc.y);
},false);
function rotateElement(el,originX,originY,towardsX,towardsY){
var degrees = Math.atan2(towardsY-originY,towardsX-originX)*180/Math.PI + 90;
el.setAttribute(
'transform',
'translate('+originX+','+originY+') translate('+(-originX)+','+(-originY)+')'
);
}
// Get point in global SVG space
function cursorPoint(evt){
pt.x = evt.clientX; pt.y = evt.clientY;
return pt.matrixTransform(svg.getScreenCTM().inverse());
}
</script>
</svg>
What I would like to do with this image is use it as a CSS background. If I use CSS to set the image as a background {background: url("image.svg");} then the JavaScript no longer works, i.e. the circle no longer follows the cursor. I believe this is due to the fact that when the image is a background, it has other elements stacked on top of it.
So how can I have the image be a background and also remain interactive? Any suggestions would be greatly appreciated.
One of the way to get a scripted background SVG working, is to use CSS4 element(). It's currently only implemented in Firefox 4+ via -moz-element().
An example:
<div id="bg" style="width: 400px; height: 400px;">
<svg width="400" height="400" viewPort="0 0 400 400">
<!-- force correct 0,0 coordinates -->
<rect x="0" y="0" width="1" height="1" fill="transparent" />
<rect x="0" y="0" id="animable1" width="120" height="120" fill="blue" />
<rect x="0" y="0" id="animable2" width="60" height="60" fill="red" />
</svg>
</div>
<div id="target" style="border: 4px dashed black; height: 400px; width: 400px; background: gray -moz-element(#bg); background-size: 20%;"></div>
<script type="text/javascript">
var divTarget = document.getElementById("target");
var animable1 = document.getElementById("animable1");
var animable2 = document.getElementById("animable2");
document.addEventListener("mousemove", function(event){
var rotation = Math.atan2(event.clientY, event.clientX);
animable1.setAttribute("transform", "translate(140 140) rotate(" + (rotation / Math.PI * 360) + " 60 60)");
animable2.setAttribute("transform", "translate(170 170) rotate(" + (360 - rotation / Math.PI * 360) + " 30 30)");
}, false);
animable1.setAttribute("transform", "translate(140 140) rotate(0 60 60)");
animable2.setAttribute("transform", "translate(170 170) rotate(0 30 30)");
</script>
You should create two files one of the .css file and the other one is Of course, better to have separate files, because it is actually a part of the container is html. SVG within this container,'s JavaScripts. This divide-and-conquer simplification or incident. For this reason, the external file is actually being held as JavaScripts. This is a great way to will not loose in the code.
SVG defining:
<div><object id="circle-svg" width="400" height="300" type="image/svg+xml" data="moving_circle.svg"></object></div>
Here, the part of the data you describe your own SVG
for example, canvas:
canvas = d3.select("#circle-svg")
.on("mouseover", mouseover)
.on("mousemove", mousemove)
.on("mouseout", mouseout);
Part1:
Take a look at this code (html based)
<head>
<title>Controlling an SVG with Javascript</title>
<script type='text/javascript' src='svg-interaction.js'></script>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script>
<style type="text/css">
div.tooltip {
position: absolute;
text-align: center;
z-index: 10;
width: 140px;
height: auto;
padding: 8px;
font: 24px sans-serif;
background: red;
color: white;
border: solid 1px #aaa;
border-radius: 8px;
opacity: 0;
}
</style>
<head>
<body>
<h2>Controlling SVG with Javascript</h2>
<div class="page-content">
<div><object id="circle-svg" width="400" height="300" type="image/svg+xml" data="moving_circle.svg"></object></div>
You can define your scripts over there
Then you continue to the second phase (Your SVG study)
<svg viewBox="0 0 400 400" preserveAspectRatio="none"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:a3="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
a3:scriptImplementation="Adobe"
onload="init(evt)"
onzoom="updateTracker(evt)"
onscroll="updateTracker(evt)"
onresize="updateTracker(evt)">
<script type="text/ecmascript" a3:scriptImplementation="Adobe"><![CDATA[
/*****
*
* Globals
*
*****/
var elems = {
tracker: false,
cursor: false,
trans: true,
scale: true,
mx: true,
my: true,
ux: true,
uy: true
};
var frame = {
x_trans: 0,
y_trans: 0,
zoom : 1,
x_scale: 1,
y_scale: 1
};

Categories

Resources