特效描述:利用html5实现 svg 动态气泡 滑块特效。利用html5实现svg动态气泡滑块特效
代码结构
1. HTML代码
values="1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 18 -7" result="goo"/>
const SVG_NS = "http://www.w3.org/2000/svg";
const XLink_NS = "http://www.w3.org/1999/xlink";
const svg = document.querySelector("svg");
let draggable = false;
let rid = null;
let m = { x: 0, y: 0 };
const t = { x: 100, y: 100 }; // translate
let dx = 0; // distance between the center of the balloon and the click point
const spring = 0.09;
const friction = 0.80;
class Slider {
constructor() {
this.target = {
x:0,
y:0,
r:5,
fontSize:5
};
this.pos = {
x:0,
y:0,
r:5,
fontSize:5
};
this.vel = {
x:0,
y:0,
r:0,
fontSize:0
};
/*this.track = {
props: { x: -50, y: -1, width: 100, height: 2 },
tagName: "rect"
};*/
this.thumb = {
props: { cx: 0, cy: 0, r: 2,style:"pointer-events: none;" },
tagName: "circle"
};
this.balloon = {
props: { cx: 0, cy: 0, r: 5 },
tagName: "circle"
};
this.label = {
props: { x: 0, y: 0,style:"font-size:5px" },
tagName: "text",
text_content: "50"
};
//this.track.elmt = drawElement(this.track, _slider);
this.thumb.elmt = drawElement(this.thumb, _thumb);
this.balloon.elmt = drawElement(this.balloon, _thumb);
this.label.elmt = drawElement(this.label, _thumb);
}
getThisTargetY(){
if(draggable){
this.target.y = -11;
this.target.r = 9;
this.target.fontSize = 8;
}else{
this.target.y = 0;
this.target.r = 5;
this.target.fontSize = 5;};
}
getThisTargetX(m){
this.target.x = m.x - dx;
if (this.target.x < -50) {
this.target.x = -50 ;
}
if (this.target.x > 50) {
this.target.x = 50;
}
}
getNewPos(prop){//x,y,r,fontSize
let dist = this.target[prop] - this.pos[prop];
let acc = dist * spring;
this.vel[prop] += acc;
this.vel[prop] *= friction;
this.pos[prop] += this.vel[prop];
}
update(){
this.getNewPos("y");
this.getNewPos("x");
this.getNewPos("r");
this.thumb.props.cx = this.target.x;
this.balloon.props.cx = this.pos.x;
this.label.props.x = this.pos.x;
this.label.elmt.textContent = Math.round(this.target.x) + 50;
this.label.props.y = this.balloon.props.cy = this.pos.y;
this.label.props.style = "font-size:"+this.target.fontSize+"px"
this.balloon.props.r = this.pos.r;
updateElement(this.label);
updateElement(this.thumb);
updateElement(this.balloon);
}
}
let slider = new Slider();
function drawElement(o, parent) {
let elmt = document.createElementNS(SVG_NS, o.tagName);
for (let name in o.props) {
if (o.props.hasOwnProperty(name)) {
elmt.setAttributeNS(null, name, o.props[name]);
}
}
if (o.text_content) {
elmt.textContent = o.text_content;
}
parent.appendChild(elmt);
return elmt;
}
function updateElement(o) {
for (let name in o.props) {
if (o.props.hasOwnProperty(name)) {
o.elmt.setAttributeNS(null, name, o.props[name]);
}
}
}
function oMousePosSVG(e) {
let p = svg.createSVGPoint();
p.x = e.clientX;
p.y = e.clientY;
let ctm = svg.getScreenCTM().inverse();
p = p.matrixTransform(ctm);
return p;
}
function transformedMousePos(e, t) {
let m = oMousePosSVG(e);
return {
x: m.x - t.x,
y: m.y - t.y
};
}
function Animation() {
requestId = window.requestAnimationFrame(Animation);
slider.update();
}
Animation();
slider.balloon.elmt.addEventListener("mousedown",
function(e) {
e.preventDefault();
draggable = true;
svg.style.cursor = "move";
m = transformedMousePos(e, t);// mouse position
// distance between the center of the balloon and the click point
dx = m.x - this.getAttributeNS(null, "cx");
slider.getThisTargetY();
},
false
);
svg.addEventListener("mouseup",
function(e) {
draggable = false;
svg.style.cursor = "default";
slider.getThisTargetY();
},
false
);
svg.addEventListener("mousemove", function(e) {
if (draggable) {
m = transformedMousePos(e, t);
slider.getThisTargetX(m)
} else {
svg.style.cursor = "default";
}
});