I am creating a hover map animation using Snap.svg, but I seem to be having problems with the animation portion. The map was created in Illustrator and exported as an SVG file and is linked to an HTML page.
Once I add the code below, everything disappears.
veryCold.mouseover(function() {
this.animate({
fill: "#ff0000"
}, 600);
}).mouseout(function() {
this.animate({
fill: "#bada55"
}, 200);
I am new to Stack Overflow, so please let me know if you need any additional information. Any help you can provide will be greatly appreciated. Thank you!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Snap.svg</title>
<style>
body {
background: #333;
}
</style>
<script src="Snap.svg-0.4.1/dist/snap.svg.js"></script>
<script src="Snap.svg-0.4.1/dist/snap-min.svg.js"></script>
</head>
<body>
<svg width="0" height="0">
</svg>
<script>
var s = Snap(1080, 700);
Snap.load("BuildingAmerica_ClimateMap_Vector-CJ-20150129-Buttons.svg", function(f) {
var g = f.selectAll("g"),
wra = f.selectAll("path[class='st0']").attr({display: "none",}),
wrb = f.selectAll("path[class='st1']").attr({display: "inline", fill: "#FFFFFF"}),
wrc = f.selectAll("path[class='st2']").attr({"opacity": 0.75}),
wrd = f.selectAll("path[class='st3']").attr({fill: "#63B1C0"}),
wre = f.selectAll("path[class='st4']").attr({"opacity": 0, fill: "#63B1C0"}),
wrf = f.selectAll("path[class='st5']").attr({fill: "#C97F4C"}),
wrg = f.selectAll("path[class='st6']").attr({fill: "#B25415"}),
wrh = f.selectAll("path[class='st7']").attr({fill: "#C87D4B"}),
wri = f.selectAll("path[class='st8']").attr({"opacity": 0, fill: "#C97F4C"}),
wrj = f.selectAll("path[class='st9']").attr({fill: "#8CB533"}),
wrk = f.selectAll("path[class='st10']").attr({"opacity": 0, fill: "#8CB533"}),
wrl = f.selectAll("path[class='st11']").attr({fill: "#EEA135"}),
wrm = f.selectAll("path[class='st12']").attr({"opacity": 0, fill: "#EEA135"}),
wrn = f.selectAll("path[class='st13']").attr({fill: "#6D7CBC"}),
wro = f.selectAll("path[class='st14']").attr({fill: "#323E96"}),
wrp = f.selectAll("path[class='st15']").attr({fill: "#333B97"}),
wrq = f.selectAll("path[class='st16']").attr({"opacity": 0, fill:"#6D7CBC"}),
wrr = f.selectAll("path[class='st17']").attr({fill: "none", stroke: "#FFFFFF", strokeWidth: 0.2709}),
wrs = f.selectAll("path[class='st18']").attr({fill: "none", stroke: "#000000", strokeWidth: 0.4});
s.append(g);
s.append(wrb);
s.append(wra);
s.append(wrc);
var veryCold = s.group(wrn, wro, wrp, wrq);
veryCold.mouseover(function() {
this.animate({
fill: "#ff0000"
}, 600);
}).mouseout(function() {
this.animate({
fill: "#bada55"
}, 200);
var mixedHumid = s.group(wrj, wrk);
var hotHumid = s.group(wrl, wrm);
var hotDry = s.group(wrf, wrg, wrh, wri);
var marine = s.group(wrd, wre);
s.append(wrr);
s.append(wrs);
});
</script>
</body>
</html>
veryCold.mouseover(function() {
this.animate({
fill: "#ff0000"
}, 600);
}).mouseout(function() {
this.animate({
fill: "#bada55"
}, 200);
}); // <--- It looks like you're missing this line
From what you've shared it looks like your code isn't properly formatted.
Related
I'm using this code to create a compass needle on an HTML page (instead of the range input i'm using data derived form a separate software). However, I'd like to add a compass face image behind it. Any ideas how I do that? Thanks (The code is from another thread by #Coderino Javarino) Perhaps you can help if you see this?
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body {
margin: 0;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
</style>
</head>
<body>
<input type="range" min="0" max="360" value="0" id="slider" oninput="updateAngle(this.value)">
<script>
// Feel free to change or delete any of the code you see in this editor!
var svg = d3.select("body").append("svg")
.attr("width", 200)
.attr("height", 200)
.attr('viewBox', '-50 -50 100 100')
var path_d = "M 0,0 L 0,-10 L 50,0 L 0,10 Z";
function updateAngle(value) {
var angle = parseInt(value);
var data = [{
angle: angle,
color: 'black'
}, {
angle: (180 + angle) % 360,
color: 'red'
}];
paths = svg.selectAll('path')
.data(data);
paths.enter()
.append('path')
.attr('d', path_d)
.merge(paths)
.style('fill', d => d.color)
.attr('transform', d => `rotate(${d.angle})`);
paths.exit().remove();
}
updateAngle(0);
</script>
</body>
I'm currently learning Phaser 3. However, all the documentation I can find is about Phaser2.
When you create a game you have to set the width and height in the config:
var config = {
type: Phaser.AUTO,
width: 800,
height: 600,
};
How can I scale the scene to fullscreen?
UPDATE
Phaser 3.16 is released on now (Feb, 2019), which has inbuilt Scale Manager. It provide various methods to scale your game. Check it out before trying the code below.
Phaser.Scale Docs
Notes on Scale Manager
Old Answer
You can resize the canvas element using resize function mentioned in code snippet and execute that function before starting game and whenever screen is resized. This way you can maintain the aspect ratio of 800:600(4:3) and fit the canvas element to full-screen according to screen ratio.
Run code snippet in Full Page Mode and resize your browser to see how canvas element is resized. Size of blue rectangle is the size of your canvas(game).
var game;
var gameWidth = 800;
var gameHeight = 600;
window.onload = function() {
var config = {
type: Phaser.CANVAS,
width: gameWidth,
height: gameHeight,
scene: [intro]
};
game = new Phaser.Game(config);
resize();
window.addEventListener("resize", resize, false);
};
function resize() {
var canvas = document.querySelector("canvas");
var windowWidth = window.innerWidth;
var windowHeight = window.innerHeight;
var windowRatio = windowWidth / windowHeight;
var gameRatio = game.config.width / game.config.height;
if (windowRatio < gameRatio) {
canvas.style.width = windowWidth + "px";
canvas.style.height = (windowWidth / gameRatio) + "px";
} else {
canvas.style.width = (windowHeight * gameRatio) + "px";
canvas.style.height = windowHeight + "px";
}
}
var intro = new Phaser.Scene('intro');
intro.create = function() {
var rect = new Phaser.Geom.Rectangle(0, 0, 800, 600);
var graphics = this.add.graphics({
fillStyle: {
color: 0x0000ff
}
});
graphics.fillRectShape(rect);
};
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
body {
background: #000000;
padding: 0px;
margin: 0px;
}
canvas {
display: block;
margin: 0;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>
<script src="https://cdn.jsdelivr.net/npm/phaser#3.6.0/dist/phaser.min.js"></script>
</head>
<body>
</body>
</html>
You should check out this post. It explains this code in detail.
css style (in index.html) should be as simple as
body { margin:0; padding:0; overflow:hidden }
body>canvas { width:100%!important; height:100%!important;
position:fixed; top:0; left:0 }
!important suffix is needed to override the dynamic html style
for example
<canvas width="800" height="600"
style="width: 681.778px; height: 511.333px;
margin-left: 0px; margin-top: 0px;"></canvas>
phaser config in index.js
const config = {
parent: "phaser-example",
type: Phaser.AUTO,
width: 800,
height: 600,
scene: {
preload: preload,
create: create
},
// https://rexrainbow.github.io/phaser3-rex-notes/docs/site/scalemanager/
scale: {
// ignore aspect ratio:
mode: Phaser.Scale.RESIZE,
// keep aspect ratio:
//mode: Phaser.Scale.FIT,
//mode: Phaser.Scale.ENVELOP, // larger than Scale.FIT
//mode: Phaser.Scale.HEIGHT_CONTROLS_WIDTH, // auto width
//mode: Phaser.Scale.WIDTH_CONTROLS_HEIGHT, // auto height
autoCenter: Phaser.Scale.NO_CENTER,
//autoCenter: Phaser.Scale.CENTER_BOTH,
//autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
//autoCenter: Phaser.Scale.CENTER_VERTICALLY,
},
autoRound: false,
};
If I want to add an extra line to an existing polyline, should I remove this existing polyline from the canvas first, modify the points matrix, and add the new polyline? Or is it possible to change the existing polyline, like changing the text of a text object?
You may remove whole polyline and add a new one or else you need to calculate the dimensions(left,top and pathoffset) and set it to polyline.
DEMO
var canvas = new fabric.Canvas('c');
var points = [];
var random = fabric.util.getRandomInt;
points.push(new fabric.Point(random(100,200),random(200,300)));
points.push(new fabric.Point(random(200,300),random(100,200)));
points.push(new fabric.Point(random(200,250),random(150,200)));
var polyLine = new fabric.Polyline(points, {
stroke: 'black',
fill: ''
});
canvas.add(polyLine);
setPolyCoords();
function addPoint(){
polyLine.points.push(new fabric.Point(random(100,400),random(100,400)));
setPolyCoords();
}
function setPolyCoords(){
polyLine._calcDimensions();
polyLine.set({
top : polyLine.minY,
left : polyLine.minX,
pathOffset : {
x: polyLine.minX + polyLine.width / 2,
y: polyLine.minY + polyLine.height / 2
}
});
polyLine.dirty = true;
polyLine.setCoords();
canvas.renderAll();
}
canvas {
border: 1px solid #f00;
margin: 0px;
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.22/fabric.js"></script>
<button onclick='addPoint()'>Add Point</button>
<canvas id="c" width="400" height="400"></canvas>
With Fabric version 2.7.0 this is become easier then in #Durga his answer.
See the new code in the demo below.
You can also skip setting the dirty flag manually by passing objectCaching: false to your polyline during construction:
var polyLine = new fabric.Polyline(points, {
stroke: 'black',
fill: '',
objectCaching: false
});
DEMO
var canvas = new fabric.Canvas('c');
var points = [];
var random = fabric.util.getRandomInt;
points.push(new fabric.Point(random(100,200),random(200,300)));
points.push(new fabric.Point(random(200,300),random(100,200)));
points.push(new fabric.Point(random(200,250),random(150,200)));
var polyLine = new fabric.Polyline(points, {
stroke: 'black',
fill: ''
});
canvas.add(polyLine);
function addPoint(){
polyLine.points.push(new fabric.Point(random(100,400),random(100,400)));
polyLine.dirty = true;
canvas.renderAll();
}
canvas {
border: 1px solid #f00;
margin: 0px;
display: block;
}
<script src="https://rawgit.com/fabricjs/fabric.js/master/dist/fabric.min.js"></script>
<button onclick='addPoint()'>Add Point</button>
<canvas id="c" width="400" height="400"></canvas>
I'm trying to create a multi-line chart with D3, but I'm stuck on toggling the visibility of lines off. So far, there is only one line, whilst I try to figure it all out (still a bit of a beginner with this), but I can't get the legend to appear, so I can't test if it'll actually get rid of the line too. Here is the JavaScript code:
var BlackBird = [{
"population": "100",
"year": "1970"
}, {
"population": "100.8",
"year": "1971"
}, {
"population": "103.5",
"year": "1972"
}, {
"population": "95.6",
"year": "1973"
}, {
"population": "101.7",
"year": "1974"
}, {
"population": "102",
"year": "1975"
}
];
var vis = d3.select("#visualisation"),
WIDTH = 1110,
HEIGHT = 580,
MARGINS = {
top: 30,
right: 20,
bottom: 20,
left: 50
},
xScale = d3.scale.linear()
.range([MARGINS.left, WIDTH - MARGINS.right])
.domain([1970,2008]),
yScale = d3.scale.linear()
.range([HEIGHT - MARGINS.top, MARGINS.bottom])
.domain([0,300]),
xAxis = d3.svg.axis()
.scale(xScale)
.ticks(25)
.tickFormat(d3.format('0f')),
yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.ticks(12);
vis.append("svg:g")
.attr("class", "axis")
.attr("transform", "translate(0," + (HEIGHT - MARGINS.bottom) + ")")
.call(xAxis);
vis.append("svg:g")
.attr("class", "axis")
.attr("transform", "translate(" + (MARGINS.left) + ",0)")
.call(yAxis);
var lineGen = d3.svg.line()
.x(function(d) {
return xScale(d.year);
})
.y(function(d) {
return yScale(d.population);
})
.interpolate("basis");
vis.append('path')
.attr('d', lineGen(BlackBird))
.attr('stroke-width', 5)
.attr('fill', 'none')
.attr('opacity', '0.2')
.attr("id", "aline");
vis.append("text")
.attr("x", WIDTH + MARGINS.left +10)
.attr("y", 10)
.attr("class", "legend")
.style("fill", "steelblue")
.on("click", function(){
var active = aline.active ? false : true,
newOpacity = active ? 0 : 1;
d3.select("#aline").attr("opacity", newOpacity);
aline.active = active;
})
.text("Blue Line");
HTML:
<!DOCTYPE html> <html lang= "en"> <head> <meta charset="UTF-8"> <title>D3 Birds</title> <link rel="stylesheet" href="D3Bird2.css"> </head> <body> <svg id="visualisation" width="1140" height="600"></svg> <div id ="BlaBird"> <img src="Blackbird.png" alt="A Blackbird" class= "Birdie"> </div> <script src="d3.min.js" charset="utf-8"> </script> <script src="script2.js" charset="utf-8"></script> </body> </html>
CSS:
.axis path {
fill: none;
stroke: #777;
shape-rendering: crispEdges;
}
.axis text {
font-family: Lato;
font-size: 13px;
}
#aline {
stroke: #000;
opacity: 0.5;
transition: 0.5s;
}
#aline: hover {
opacity: 1;
transition: 0.5s;
}
.Birdie {
transition: 0.5s;
opacity: 0.5;
}
#BlaBird {
position: absolute;
left: 1150px;
top: 30px;
}
.legend {
font-size: 16px;
font-weight: bold;
text-anchor: start;
}
First, you didn't include your HTML markup, but I'm assuming #visualisation is an SVG element. Make sure you've assigned it height and width attributes.
Second, you don't assign a stroke color to your line. I'm assuming you do this in CSS somewhere.
Third, after fixing your variable names, this line:
.attr("x", width + margin.left +10)
is the problem. This pushes the text element outside of it's SVG.
Here's an example where I've fixed some of this up.
EDITS
New problem after looking at your CSS. You are setting the attribute opacity in code, the CSS sets the style opacity. When both are set the browser will use the style. So change your click handler to:
.on("click", function() {
var active = aline.active ? false : true,
newOpacity = active ? 0 : 1;
d3.select("#aline").style("opacity", newOpacity); //<-- set style, not attr
aline.active = active;
})
Example updated.
I have an array of points(pair of x,y) and I draw circles by these points
for (var i = 0; i < points.length;i++){
var circle = new Kinetic.Circle({
x: points[i].x,
y: points[i].y,
radius: 7,
fill: "green",
stroke: "black",
name:i,
strokeWidth: 2
});
circle.on("click", function() {
alert(name); //here I want to get name of circle
});
layer.add(circle);
}
I added new attribute name to each circle, like ID and I want to alert name of circle when mouse is clicked at it.
I am not sure that adding new attribute name to circle is correct.
So,how to add new attribute "name" to circle so that when clicking at circle it alerts its value of name?
Try this below code
<!DOCTYPE HTML>
<html>
<head>
<style>
body
{
margin: 0px;
padding: 0px;
}
</style>
</head>
<body onload="displaycircle()">
<div id="container">
</div>
<script src="http://www.html5canvastutorials.com/libraries/kinetic-v4.0.0.js"></script>
<script>
function displaycircle() {
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
for (var i = 0; i < 10; i++) {
var circle = new Kinetic.Circle({
x: Math.random() * stage.getWidth(),
y: Math.random() * stage.getHeight(),
radius: 30,
fill: "green",
stroke: "black",
name: i,
strokeWidth: 2,
draggable: true
});
layer.add(circle);
stage.add(layer);
circle.on("click", function() {
alert(this.attrs.name); //here you can get name of circle
});
}
}
</script>
</body>
</html>