mirror of
https://gitee.com/coder-xiaomo/algorithm-visualization
synced 2025-01-10 11:48:18 +08:00
完成链表绘制;引入GSAP动画库;完成基本的两个元素交换动画
This commit is contained in:
parent
fc9fed1ecb
commit
87b69a9bf7
@ -131,4 +131,164 @@ class Shape {
|
||||
.text(text)
|
||||
.style("fill", workSpace.settings.colorMap["text"])
|
||||
}
|
||||
|
||||
|
||||
// 绘制一个链表
|
||||
getLinkedListFragment(id, nodes) {
|
||||
var settings = this.workSpace.settings
|
||||
|
||||
let displayMaxWidth = 1 * settings.innerSize.width
|
||||
let displayMaxHeight = 1 * settings.innerSize.height
|
||||
let areaWidth = 1 * nodes.length // 按照1个Unit来计算
|
||||
let areaHeight = 1 // 按照1个Unit来计算
|
||||
|
||||
let oneUnit = 100
|
||||
// 可以假设高度相等比较宽度,这样好理解
|
||||
if (displayMaxWidth / displayMaxHeight > areaWidth / areaHeight) {
|
||||
// 展示区域左右有多余空间
|
||||
oneUnit = displayMaxHeight / areaHeight
|
||||
} else {
|
||||
// 展示区域上下有空间(或刚刚好)
|
||||
oneUnit = displayMaxWidth / areaWidth
|
||||
}
|
||||
|
||||
// 定义最大值
|
||||
if (oneUnit > 120) oneUnit = 120
|
||||
|
||||
let fragment = document.createDocumentFragment()
|
||||
fragment.customAttr = {
|
||||
nodes: nodes,
|
||||
type: "linkedList",
|
||||
oneUnit: oneUnit
|
||||
}
|
||||
console.log(fragment.customAttr)
|
||||
|
||||
// <g></g> 元素不能设置 width 和 height
|
||||
|
||||
let g = d3.select(fragment)
|
||||
.append("svg:g")
|
||||
.attr("id", id)
|
||||
.attr("fill", "white")
|
||||
.attr("transform", `translate(${settings.margin.left}, ${settings.margin.top})`)
|
||||
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
let node = nodes[i]
|
||||
let _g = g.append("svg:g")
|
||||
|
||||
_g.append("svg:rect")
|
||||
.attr("x", i * oneUnit)
|
||||
.attr("y", 0)
|
||||
.attr("width", oneUnit)
|
||||
.attr("height", oneUnit)
|
||||
.attr("fill", settings.colorMap["fill"])
|
||||
.attr("stroke", settings.colorMap["stroke"])
|
||||
|
||||
_g.append("svg:text")
|
||||
.text(node)
|
||||
.attr("x", i * oneUnit + oneUnit / 2)
|
||||
.attr("y", oneUnit / 2)
|
||||
.attr("width", oneUnit)
|
||||
.attr("height", oneUnit)
|
||||
.attr("fill", settings.colorMap["text"])
|
||||
|
||||
// console.log(text.node().getBBox())
|
||||
// console.log(text.node().getBoundingClientRect())
|
||||
}
|
||||
|
||||
// g.append("svg:rect")
|
||||
// .attr("width", oneUnit * nodes.length)
|
||||
// .attr("height", oneUnit)
|
||||
// .style("fill", "none")
|
||||
// .style("stroke", "green")
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
|
||||
class VectorAnimation {
|
||||
constructor(workSpace) {
|
||||
this.workSpace = workSpace
|
||||
}
|
||||
|
||||
swapElementAttr(attrName/* or attrNameList */, element1, element2) {
|
||||
function exchange(attrName) {
|
||||
// 保存 element1 的属性,将 element2 的属性赋值给 element1, 再将保存的属性赋值给 element2
|
||||
var tmp = element1.getAttribute(attrName)
|
||||
element1.setAttribute(attrName, element2.getAttribute(attrName))
|
||||
element2.setAttribute(attrName, tmp)
|
||||
}
|
||||
if (typeof attrName === "string") {
|
||||
exchange(attrName)
|
||||
} else if (typeof attrName === "object") {
|
||||
for (let i = 0; i < attrName.length; i++) {
|
||||
exchange(attrName[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
swapElementInnerHTML(element1, element2) {
|
||||
var tmp = element1.innerHTML
|
||||
element1.innerHTML = element2.innerHTML
|
||||
element2.innerHTML = tmp
|
||||
}
|
||||
|
||||
swapElementsAttr(elementPairList) {
|
||||
// [
|
||||
// [attrName or attrNameList, element1, element2],
|
||||
// [attrName or attrNameList, element1, element2],
|
||||
// ...
|
||||
// ]
|
||||
for (let i = 0; i < elementPairList.length; i++) {
|
||||
let elementPair = elementPairList[i]
|
||||
this.swapElementAttr(elementPair[0], elementPair[1], elementPair[2])
|
||||
}
|
||||
}
|
||||
|
||||
swapLinkedListItems(id, [fromIndex, toIndex]) {
|
||||
var settings = this.workSpace.settings
|
||||
let linkedList = document.getElementById(id)
|
||||
let customAttr = linkedList.customAttr
|
||||
console.log(customAttr)
|
||||
|
||||
var gList = linkedList.childNodes
|
||||
|
||||
let from = gList[fromIndex]
|
||||
let to = gList[toIndex]
|
||||
|
||||
var deltaX = customAttr.oneUnit * (fromIndex - toIndex);
|
||||
var deltaY = customAttr.oneUnit * 1.08
|
||||
var animateSettings = {
|
||||
duration: 0.3,
|
||||
ease: "sine.inOut",
|
||||
delay: 0,
|
||||
yoyo: true,
|
||||
}
|
||||
var tl = gsap.timeline({
|
||||
onComplete: function () {
|
||||
console.log("success")
|
||||
}
|
||||
})
|
||||
tl.add([
|
||||
gsap.to(from.childNodes[0], { ...animateSettings, fill: settings.colorMap["fill_focus"] }),
|
||||
gsap.to(to.childNodes[0], { ...animateSettings, fill: settings.colorMap["fill_focus"] }),
|
||||
gsap.to(from.childNodes[1], { ...animateSettings, fill: settings.colorMap["text_focus"] }),
|
||||
gsap.to(to.childNodes[1], { ...animateSettings, fill: settings.colorMap["text_focus"] }),
|
||||
gsap.to(from.childNodes, { ...animateSettings, y: -deltaY }),
|
||||
gsap.to(to.childNodes, { ...animateSettings, y: deltaY }),
|
||||
]).add([
|
||||
gsap.to(from.childNodes, { ...animateSettings, x: -deltaX }),
|
||||
gsap.to(to.childNodes, { ...animateSettings, x: deltaX }),
|
||||
]).add([
|
||||
gsap.to(from.childNodes[0], { ...animateSettings, fill: settings.colorMap["fill"] }),
|
||||
gsap.to(to.childNodes[0], { ...animateSettings, fill: settings.colorMap["fill"] }),
|
||||
gsap.to(from.childNodes[1], { ...animateSettings, fill: settings.colorMap["text"] }),
|
||||
gsap.to(to.childNodes[1], { ...animateSettings, fill: settings.colorMap["text"] }),
|
||||
gsap.to(from.childNodes, { ...animateSettings, y: 0 }),
|
||||
gsap.to(to.childNodes, { ...animateSettings, y: 0 }),
|
||||
])
|
||||
|
||||
// // 首先元素的文字,为了保证用户看起来不闪烁,同时用transform临时交换元素的位置(用户看起来就像是没有交换一样,但是此时已经交换过了)
|
||||
// // 最后再把 transform 恢复即可
|
||||
// this.swapElementInnerHTML(from, to)
|
||||
|
||||
}
|
||||
}
|
@ -13,20 +13,30 @@ var settings = {
|
||||
width: null, // 带单位,通过 outerSize 计算得到
|
||||
height: null, // 带单位,通过 outerSize 计算得到
|
||||
margin: { // 不带单位
|
||||
top: 20,
|
||||
top: 180,
|
||||
right: 20,
|
||||
bottom: 20,
|
||||
bottom: 180,
|
||||
left: 20
|
||||
},
|
||||
oneUnit: { // 不带单位,通过 innerSize 计算得到
|
||||
transverse: null, // 横向单位长度 ( innerSize 的 1% )
|
||||
longitudinal: null // 纵向单位长度 ( innerSize 的 1% )
|
||||
},
|
||||
colorMap: {
|
||||
"background": "#ddd",
|
||||
|
||||
"stroke": "#e02433", // 边框颜色
|
||||
"fill": "#ffa4ab", // 填充颜色
|
||||
"text": "blue", // 文本颜色
|
||||
"stroke": "#e02433", // 边框颜色
|
||||
"fill": "#ffa4ab", // 填充颜色
|
||||
"fill_focus": "#ee737d", // 填充颜色
|
||||
"text": "blue", // 文本颜色
|
||||
"text_focus": "white", // 文本颜色
|
||||
|
||||
"red": "#f00",
|
||||
"green": "#0f0",
|
||||
},
|
||||
animation: {
|
||||
duration: 2000, // 不带单位,单位是毫秒
|
||||
easing: "ease-in-out"
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,10 +44,15 @@ settings.width = settings.outerSize.width + "px";
|
||||
settings.height = settings.outerSize.height + "px";
|
||||
settings.innerSize.width = settings.outerSize.width - settings.margin.left - settings.margin.right;
|
||||
settings.innerSize.height = settings.outerSize.height - settings.margin.top - settings.margin.bottom;
|
||||
settings.oneUnit.transverse = settings.innerSize.width / 100;
|
||||
settings.oneUnit.longitudinal = settings.innerSize.height / 100;
|
||||
|
||||
console.log("settings", settings)
|
||||
|
||||
// 初始化
|
||||
var workSpace = new WorkSpace(settings)
|
||||
var shape = new Shape(workSpace)
|
||||
var animation = new VectorAnimation(workSpace)
|
||||
|
||||
function initialize() {
|
||||
|
||||
@ -46,72 +61,83 @@ function initialize() {
|
||||
initialize()
|
||||
|
||||
// 测试
|
||||
shape.rectangle("ele1", {
|
||||
x: 10,
|
||||
y: 10,
|
||||
width: "20%",
|
||||
height: "30%",
|
||||
fillColor: "blue",
|
||||
strokeColor: "red"
|
||||
}).style("stroke-width", "10px")
|
||||
shape.circle("ele2", {
|
||||
x: 200,
|
||||
y: 50,
|
||||
radius: "20px",
|
||||
fillColor: "green",
|
||||
strokeColor: "red"
|
||||
})
|
||||
shape.text("ele3", {
|
||||
x: 200,
|
||||
y: 150,
|
||||
text: "文本",
|
||||
fillColor: "red"
|
||||
})
|
||||
shape.line("ele4", {
|
||||
x1: 100,
|
||||
y1: 100,
|
||||
x2: 200,
|
||||
y2: 200,
|
||||
strokeColor: "red"
|
||||
// shape.rectangle("ele1", {
|
||||
// x: 10,
|
||||
// y: 10,
|
||||
// width: "20%",
|
||||
// height: "30%",
|
||||
// fillColor: "blue",
|
||||
// strokeColor: "red"
|
||||
// }).style("stroke-width", "10px")
|
||||
// shape.circle("ele2", {
|
||||
// x: 200,
|
||||
// y: 50,
|
||||
// radius: "20px",
|
||||
// fillColor: "green",
|
||||
// strokeColor: "red"
|
||||
// })
|
||||
// shape.text("ele3", {
|
||||
// x: 200,
|
||||
// y: 150,
|
||||
// text: "文本",
|
||||
// fillColor: "red"
|
||||
// })
|
||||
// shape.line("ele4", {
|
||||
// x1: 100,
|
||||
// y1: 100,
|
||||
// x2: 200,
|
||||
// y2: 200,
|
||||
// strokeColor: "red"
|
||||
// })
|
||||
|
||||
// var data = []
|
||||
// for (let i = 0; i < 20; i++) // 生成随机数
|
||||
// data.push(Math.ceil(Math.random() * 10))
|
||||
|
||||
// var scale = {
|
||||
// x: d3.scaleLinear()
|
||||
// .domain([0, data.length - 1])
|
||||
// .range([0, settings.innerSize.width]),
|
||||
// y: d3.scaleLinear()
|
||||
// .domain([0, d3.max(data)])
|
||||
// .range([settings.innerSize.height, 0])
|
||||
// }
|
||||
// var line_generator = d3.line()
|
||||
// .x(function (d, i) { return scale.x(i); })
|
||||
// .y(function (d, i) { return scale.y(d); })
|
||||
// // .curve(d3.curveBasis)
|
||||
// // .curve(d3.curveCardinal)
|
||||
|
||||
// shape.path("ele5", line_generator(data), {
|
||||
// fillColor: "none",
|
||||
// strokeColor: "red"
|
||||
// })
|
||||
// shape.path("ele6", line_generator.curve(d3.curveCardinal)(data), {
|
||||
// fillColor: "none",
|
||||
// strokeColor: "green"
|
||||
// })
|
||||
// // shape.addShape("g", "axisX").attr("transform", `translate(${settings.margin.left}, ${settings.outerSize.height - settings.margin.bottom})`)//.attr("fill", "red")
|
||||
// shape.axis("axisX", {
|
||||
// transform: `translate(${settings.margin.left}, ${settings.outerSize.height - settings.margin.bottom})`,
|
||||
// axis: d3.axisBottom(scale.x)
|
||||
// })
|
||||
// shape.axis("axisY", {
|
||||
// transform: `translate(${settings.margin.left}, ${settings.margin.top})`,
|
||||
// axis: d3.axisLeft(scale.y)
|
||||
// })
|
||||
|
||||
// shape.addNode("ele7", 300, 200, "20px", "20px", "文本")
|
||||
|
||||
let fragment = shape.getLinkedListFragment("ele8", [1, 2, 3, 4, 5, 6, 7, 8, 9], { //
|
||||
x: 100,
|
||||
y: 100,
|
||||
width: "100px",
|
||||
height: "100px",
|
||||
})
|
||||
|
||||
var data = []
|
||||
for (let i = 0; i < 20; i++) // 生成随机数
|
||||
data.push(Math.ceil(Math.random() * 10))
|
||||
|
||||
var scale = {
|
||||
x: d3.scaleLinear()
|
||||
.domain([0, data.length - 1])
|
||||
.range([0, settings.innerSize.width]),
|
||||
y: d3.scaleLinear()
|
||||
.domain([0, d3.max(data)])
|
||||
.range([settings.innerSize.height, 0])
|
||||
}
|
||||
var line_generator = d3.line()
|
||||
.x(function (d, i) { return scale.x(i); })
|
||||
.y(function (d, i) { return scale.y(d); })
|
||||
// .curve(d3.curveBasis)
|
||||
// .curve(d3.curveCardinal)
|
||||
|
||||
shape.path("ele5", line_generator(data), {
|
||||
fillColor: "none",
|
||||
strokeColor: "red"
|
||||
})
|
||||
shape.path("ele6", line_generator.curve(d3.curveCardinal)(data), {
|
||||
fillColor: "none",
|
||||
strokeColor: "green"
|
||||
})
|
||||
// shape.addShape("g", "axisX").attr("transform", `translate(${settings.margin.left}, ${settings.outerSize.height - settings.margin.bottom})`)//.attr("fill", "red")
|
||||
shape.axis("axisX", {
|
||||
transform: `translate(${settings.margin.left}, ${settings.outerSize.height - settings.margin.bottom})`,
|
||||
axis: d3.axisBottom(scale.x)
|
||||
})
|
||||
shape.axis("axisY", {
|
||||
transform: `translate(${settings.margin.left}, ${settings.margin.top})`,
|
||||
axis: d3.axisLeft(scale.y)
|
||||
})
|
||||
|
||||
shape.addNode("ele7", 300, 200, "20px", "20px", "文本")
|
||||
|
||||
// // 添加 g 元素
|
||||
// primaryCanvas.append("g")
|
||||
console.log(fragment)
|
||||
workSpace.primaryCanvas.node().appendChild(fragment)
|
||||
document.getElementById("ele8").customAttr = fragment.customAttr
|
||||
setTimeout(() => {
|
||||
animation.swapLinkedListItems("ele8", [0, 2])
|
||||
}, 100)
|
11
algorithm-visualization/assets/lib/gsap/3.10.4/CSSRulePlugin.min.js
vendored
Normal file
11
algorithm-visualization/assets/lib/gsap/3.10.4/CSSRulePlugin.min.js
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
/*!
|
||||
* CSSRulePlugin 3.10.4
|
||||
* https://greensock.com
|
||||
*
|
||||
* @license Copyright 2022, GreenSock. All rights reserved.
|
||||
* Subject to the terms at https://greensock.com/standard-license or for Club GreenSock members, the agreement issued with that membership.
|
||||
* @author: Jack Doyle, jack@greensock.com
|
||||
*/
|
||||
|
||||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e=e||self).window=e.window||{})}(this,function(e){"use strict";function h(){return"undefined"!=typeof window}function i(){return t||h()&&(t=window.gsap)&&t.registerPlugin&&t}function j(){return n||(s(),o||console.warn("Please gsap.registerPlugin(CSSPlugin, CSSRulePlugin)")),n}var t,n,c,o,s=function _initCore(e){t=e||i(),h()&&(c=document),t&&(o=t.plugins.css)&&(n=1)},r={version:"3.10.4",name:"cssRule",init:function init(e,t,n,i,s){if(!j()||void 0===e.cssText)return!1;var r=e._gsProxy=e._gsProxy||c.createElement("div");this.ss=e,this.style=r.style,r.style.cssText=e.cssText,o.prototype.init.call(this,r,t,n,i,s)},render:function render(e,t){for(var n,i=t._pt,s=t.style,r=t.ss;i;)i.r(e,i.d),i=i._next;for(n=s.length;-1<--n;)r[s[n]]=s[s[n]]},getRule:function getRule(e){j();var t,n,i,s,r=c.all?"rules":"cssRules",o=c.styleSheets,l=o.length,u=":"===e.charAt(0);for(e=(u?"":",")+e.split("::").join(":").toLowerCase()+",",u&&(s=[]);l--;){try{if(!(n=o[l][r]))continue;t=n.length}catch(e){console.warn(e);continue}for(;-1<--t;)if((i=n[t]).selectorText&&-1!==(","+i.selectorText.split("::").join(":").toLowerCase()+",").indexOf(e)){if(!u)return i.style;s.push(i.style)}}return s},register:s};i()&&t.registerPlugin(r),e.CSSRulePlugin=r,e.default=r;if (typeof(window)==="undefined"||window!==e){Object.defineProperty(e,"__esModule",{value:!0})} else {delete e.default}});
|
||||
|
File diff suppressed because one or more lines are too long
11
algorithm-visualization/assets/lib/gsap/3.10.4/CustomEase.min.js
vendored
Normal file
11
algorithm-visualization/assets/lib/gsap/3.10.4/CustomEase.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
11
algorithm-visualization/assets/lib/gsap/3.10.4/Draggable.min.js
vendored
Normal file
11
algorithm-visualization/assets/lib/gsap/3.10.4/Draggable.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
11
algorithm-visualization/assets/lib/gsap/3.10.4/EasePack.min.js
vendored
Normal file
11
algorithm-visualization/assets/lib/gsap/3.10.4/EasePack.min.js
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
/*!
|
||||
* EasePack 3.10.4
|
||||
* https://greensock.com
|
||||
*
|
||||
* @license Copyright 2022, GreenSock. All rights reserved.
|
||||
* Subject to the terms at https://greensock.com/standard-license or for Club GreenSock members, the agreement issued with that membership.
|
||||
* @author: Jack Doyle, jack@greensock.com
|
||||
*/
|
||||
|
||||
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((e=e||self).window=e.window||{})}(this,function(e){"use strict";function f(){return w||"undefined"!=typeof window&&(w=window.gsap)&&w.registerPlugin&&w}function g(e,n){return!!(void 0===e?n:e&&!~(e+"").indexOf("false"))}function h(e){if(w=e||f()){r=w.registerEase;var n,t=w.parseEase(),o=function createConfig(t){return function(e){var n=.5+e/2;t.config=function(e){return t(2*(1-e)*e*n+e*e)}}};for(n in t)t[n].config||o(t[n]);for(n in r("slow",a),r("expoScale",s),r("rough",u),c)"version"!==n&&w.core.globals(n,c[n])}}function i(e,n,t){var o=(e=Math.min(1,e||.7))<1?n||0===n?n:.7:0,r=(1-e)/2,i=r+e,a=g(t);return function(e){var n=e+(.5-e)*o;return e<r?a?1-(e=1-e/r)*e:n-(e=1-e/r)*e*e*e*n:i<e?a?1===e?0:1-(e=(e-i)/r)*e:n+(e-n)*(e=(e-i)/r)*e*e*e:a?1:n}}function j(n,e,t){var o=Math.log(e/n),r=e-n;return t=t&&w.parseEase(t),function(e){return(n*Math.exp(o*(t?t(e):e))-n)/r}}function k(e,n,t){this.t=e,this.v=n,t&&(((this.next=t).prev=this).c=t.v-n,this.gap=t.t-e)}function l(e){"object"!=typeof e&&(e={points:+e||20});for(var n,t,o,r,i,a,f,s=e.taper||"none",u=[],c=0,p=0|(+e.points||20),l=p,v=g(e.randomize,!0),d=g(e.clamp),h=w?w.parseEase(e.template):0,x=.4*(+e.strength||1);-1<--l;)n=v?Math.random():1/p*l,t=h?h(n):n,o="none"===s?x:"out"===s?(r=1-n)*r*x:"in"===s?n*n*x:n<.5?(r=2*n)*r*.5*x:(r=2*(1-n))*r*.5*x,v?t+=Math.random()*o-.5*o:l%2?t+=.5*o:t-=.5*o,d&&(1<t?t=1:t<0&&(t=0)),u[c++]={x:n,y:t};for(u.sort(function(e,n){return e.x-n.x}),a=new k(1,1,null),l=p;l--;)i=u[l],a=new k(i.x,i.y,a);return f=new k(0,0,a.t?a:a.next),function(e){var n=f;if(e>n.t){for(;n.next&&e>=n.t;)n=n.next;n=n.prev}else for(;n.prev&&e<=n.t;)n=n.prev;return(f=n).v+(e-n.t)/n.gap*n.c}}var w,r,a=i(.7);(a.ease=a).config=i;var s=j(1,2);s.config=j;var u=l();(u.ease=u).config=l;var c={SlowMo:a,RoughEase:u,ExpoScaleEase:s};for(var n in c)c[n].register=h,c[n].version="3.10.4";f()&&w.registerPlugin(a),e.EasePack=c,e.ExpoScaleEase=s,e.RoughEase=u,e.SlowMo=a,e.default=c;if (typeof(window)==="undefined"||window!==e){Object.defineProperty(e,"__esModule",{value:!0})} else {delete e.default}});
|
||||
|
File diff suppressed because one or more lines are too long
11
algorithm-visualization/assets/lib/gsap/3.10.4/EaselPlugin.min.js
vendored
Normal file
11
algorithm-visualization/assets/lib/gsap/3.10.4/EaselPlugin.min.js
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
/*!
|
||||
* EaselPlugin 3.10.4
|
||||
* https://greensock.com
|
||||
*
|
||||
* @license Copyright 2022, GreenSock. All rights reserved.
|
||||
* Subject to the terms at https://greensock.com/standard-license or for Club GreenSock members, the agreement issued with that membership.
|
||||
* @author: Jack Doyle, jack@greensock.com
|
||||
*/
|
||||
|
||||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e=e||self).window=e.window||{})}(this,function(e){"use strict";function k(){return"undefined"!=typeof window}function l(){return h||k()&&(h=window.gsap)&&h.registerPlugin&&h}function m(){return r||t&&t.createjs||t||{}}function n(e){return console.warn(e)}function o(e){var t=e.getBounds&&e.getBounds();t||(t=e.nominalBounds||{x:0,y:0,width:100,height:100},e.setBounds&&e.setBounds(t.x,t.y,t.width,t.height)),e.cache&&e.cache(t.x,t.y,t.width,t.height),n("EaselPlugin: for filters to display in EaselJS, you must call the object's cache() method first. GSAP attempted to use the target's getBounds() for the cache but that may not be completely accurate. "+e)}function p(e,t,r){(b=b||m().ColorFilter)||n("EaselPlugin error: The EaselJS ColorFilter JavaScript file wasn't loaded.");for(var i,l,s,u,a,f,c=e.filters||[],d=c.length;d--;)if(c[d]instanceof b){l=c[d];break}if(l||(l=new b,c.push(l),e.filters=c),s=l.clone(),null!=t.tint)i=h.utils.splitColor(t.tint),u=null!=t.tintAmount?+t.tintAmount:1,s.redOffset=i[0]*u,s.greenOffset=i[1]*u,s.blueOffset=i[2]*u,s.redMultiplier=s.greenMultiplier=s.blueMultiplier=1-u;else for(a in t)"exposure"!==a&&"brightness"!==a&&(s[a]=+t[a]);for(null!=t.exposure?(s.redOffset=s.greenOffset=s.blueOffset=255*(t.exposure-1),s.redMultiplier=s.greenMultiplier=s.blueMultiplier=1):null!=t.brightness&&(u=t.brightness-1,s.redOffset=s.greenOffset=s.blueOffset=0<u?255*u:0,s.redMultiplier=s.greenMultiplier=s.blueMultiplier=1-Math.abs(u)),d=8;d--;)l[a=M[d]]!==s[a]&&(f=r.add(l,a,l[a],s[a]))&&(f.op="easel_colorFilter");r._props.push("easel_colorFilter"),e.cacheID||o(e)}function u(e,t){if(!(e instanceof Array&&t instanceof Array))return t;var r,i,n=[],l=0,o=0;for(r=0;r<4;r++){for(i=0;i<5;i++)o=4===i?e[l+4]:0,n[l+i]=e[l]*t[i]+e[l+1]*t[i+5]+e[l+2]*t[i+10]+e[l+3]*t[i+15]+o;l+=5}return n}function z(e,t,r){(d=d||m().ColorMatrixFilter)||n("EaselPlugin: The EaselJS ColorMatrixFilter JavaScript file wasn't loaded.");for(var i,l,s,a,f=e.filters||[],c=f.length;-1<--c;)if(f[c]instanceof d){s=f[c];break}for(s||(s=new d(w.slice()),f.push(s),e.filters=f),l=s.matrix,i=w.slice(),null!=t.colorize&&(i=function _colorize(e,t,r){isNaN(r)&&(r=1);var i=h.utils.splitColor(t),n=i[0]/255,l=i[1]/255,o=i[2]/255,s=1-r;return u([s+r*n*x,r*n*y,r*n*_,0,0,r*l*x,s+r*l*y,r*l*_,0,0,r*o*x,r*o*y,s+r*o*_,0,0,0,0,0,1,0],e)}(i,t.colorize,Number(t.colorizeAmount))),null!=t.contrast&&(i=function _setContrast(e,t){return isNaN(t)?e:u([t+=.01,0,0,0,128*(1-t),0,t,0,0,128*(1-t),0,0,t,0,128*(1-t),0,0,0,1,0],e)}(i,Number(t.contrast))),null!=t.hue&&(i=function _setHue(e,t){if(isNaN(t))return e;t*=Math.PI/180;var r=Math.cos(t),i=Math.sin(t);return u([x+r*(1-x)+i*-x,y+r*-y+i*-y,_+r*-_+i*(1-_),0,0,x+r*-x+.143*i,y+r*(1-y)+.14*i,_+r*-_+-.283*i,0,0,x+r*-x+i*-(1-x),y+r*-y+i*y,_+r*(1-_)+i*_,0,0,0,0,0,1,0,0,0,0,0,1],e)}(i,Number(t.hue))),null!=t.saturation&&(i=function _setSaturation(e,t){if(isNaN(t))return e;var r=1-t,i=r*x,n=r*y,l=r*_;return u([i+t,n,l,0,0,i,n+t,l,0,0,i,n,l+t,0,0,0,0,0,1,0],e)}(i,Number(t.saturation))),c=i.length;-1<--c;)i[c]!==l[c]&&(a=r.add(l,c,l[c],i[c]))&&(a.op="easel_colorMatrixFilter");r._props.push("easel_colorMatrixFilter"),e.cacheID||o(),r._matrix=l}function A(e){h=e||l(),k()&&(t=window),h&&(g=1)}var h,g,t,r,b,d,M="redMultiplier,greenMultiplier,blueMultiplier,alphaMultiplier,redOffset,greenOffset,blueOffset,alphaOffset".split(","),w=[1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0],x=.212671,y=.71516,_=.072169,i={version:"3.10.4",name:"easel",init:function init(e,t,r,i,l){var o,s,u,a,f,c,d;for(o in g||(A(),h||n("Please gsap.registerPlugin(EaselPlugin)")),this.target=e,t)if(f=t[o],"colorFilter"===o||"tint"===o||"tintAmount"===o||"exposure"===o||"brightness"===o)u||(p(e,t.colorFilter||t,this),u=!0);else if("saturation"===o||"contrast"===o||"hue"===o||"colorize"===o||"colorizeAmount"===o)a||(z(e,t.colorMatrixFilter||t,this),a=!0);else if("frame"===o){if("string"==typeof f&&"="!==f.charAt(1)&&(c=e.labels))for(d=0;d<c.length;d++)c[d].label===f&&(f=c[d].position);(s=this.add(e,"gotoAndStop",e.currentFrame,f,i,l,Math.round))&&(s.op=o)}else null!=e[o]&&this.add(e,o,"get",f)},render:function render(e,t){for(var r=t._pt;r;)r.r(e,r.d),r=r._next;t.target.cacheID&&t.target.updateCache()},register:A,registerCreateJS:function(e){r=e}};l()&&h.registerPlugin(i),e.EaselPlugin=i,e.default=i;if (typeof(window)==="undefined"||window!==e){Object.defineProperty(e,"__esModule",{value:!0})} else {delete e.default}});
|
||||
|
File diff suppressed because one or more lines are too long
11
algorithm-visualization/assets/lib/gsap/3.10.4/Flip.min.js
vendored
Normal file
11
algorithm-visualization/assets/lib/gsap/3.10.4/Flip.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
11
algorithm-visualization/assets/lib/gsap/3.10.4/MotionPathPlugin.min.js
vendored
Normal file
11
algorithm-visualization/assets/lib/gsap/3.10.4/MotionPathPlugin.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
11
algorithm-visualization/assets/lib/gsap/3.10.4/Observer.min.js
vendored
Normal file
11
algorithm-visualization/assets/lib/gsap/3.10.4/Observer.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
11
algorithm-visualization/assets/lib/gsap/3.10.4/PixiPlugin.min.js
vendored
Normal file
11
algorithm-visualization/assets/lib/gsap/3.10.4/PixiPlugin.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
11
algorithm-visualization/assets/lib/gsap/3.10.4/ScrollToPlugin.min.js
vendored
Normal file
11
algorithm-visualization/assets/lib/gsap/3.10.4/ScrollToPlugin.min.js
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
/*!
|
||||
* ScrollToPlugin 3.10.4
|
||||
* https://greensock.com
|
||||
*
|
||||
* @license Copyright 2022, GreenSock. All rights reserved.
|
||||
* Subject to the terms at https://greensock.com/standard-license or for Club GreenSock members, the agreement issued with that membership.
|
||||
* @author: Jack Doyle, jack@greensock.com
|
||||
*/
|
||||
|
||||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e=e||self).window=e.window||{})}(this,function(e){"use strict";function k(){return"undefined"!=typeof window}function l(){return u||k()&&(u=window.gsap)&&u.registerPlugin&&u}function m(e){return"string"==typeof e}function n(e){return"function"==typeof e}function o(e,t){var o="x"===t?"Width":"Height",n="scroll"+o,r="client"+o;return e===T||e===i||e===c?Math.max(i[n],c[n])-(T["inner"+o]||i[r]||c[r]):e[n]-e["offset"+o]}function p(e,t){var o="scroll"+("x"===t?"Left":"Top");return e===T&&(null!=e.pageXOffset?o="page"+t.toUpperCase()+"Offset":e=null!=i[o]?i:c),function(){return e[o]}}function r(e,t){if(!(e=f(e)[0])||!e.getBoundingClientRect)return console.warn("scrollTo target doesn't exist. Using 0")||{x:0,y:0};var o=e.getBoundingClientRect(),n=!t||t===T||t===c,r=n?{top:i.clientTop-(T.pageYOffset||i.scrollTop||c.scrollTop||0),left:i.clientLeft-(T.pageXOffset||i.scrollLeft||c.scrollLeft||0)}:t.getBoundingClientRect(),l={x:o.left-r.left,y:o.top-r.top};return!n&&t&&(l.x+=p(t,"x")(),l.y+=p(t,"y")()),l}function s(e,t,n,l,i){return isNaN(e)||"object"==typeof e?m(e)&&"="===e.charAt(1)?parseFloat(e.substr(2))*("-"===e.charAt(0)?-1:1)+l-i:"max"===e?o(t,n)-i:Math.min(o(t,n),r(e,t)[n]-i):parseFloat(e)-i}function t(){u=l(),k()&&u&&document.body&&(T=window,c=document.body,i=document.documentElement,f=u.utils.toArray,u.config({autoKillThreshold:7}),v=u.config(),a=1)}var u,a,T,i,c,f,v,y={version:"3.10.4",name:"scrollTo",rawVars:1,register:function register(e){u=e,t()},init:function init(e,o,r,l,i){a||t();var c=this,f=u.getProperty(e,"scrollSnapType");c.isWin=e===T,c.target=e,c.tween=r,o=function _clean(e,t,o,r){if(n(e)&&(e=e(t,o,r)),"object"!=typeof e)return m(e)&&"max"!==e&&"="!==e.charAt(1)?{x:e,y:e}:{y:e};if(e.nodeType)return{y:e,x:e};var l,i={};for(l in e)i[l]="onAutoKill"!==l&&n(e[l])?e[l](t,o,r):e[l];return i}(o,l,e,i),c.vars=o,c.autoKill=!!o.autoKill,c.getX=p(e,"x"),c.getY=p(e,"y"),c.x=c.xPrev=c.getX(),c.y=c.yPrev=c.getY(),f&&"none"!==f&&(c.snap=1,c.snapInline=e.style.scrollSnapType,e.style.scrollSnapType="none"),null!=o.x?(c.add(c,"x",c.x,s(o.x,e,"x",c.x,o.offsetX||0),l,i),c._props.push("scrollTo_x")):c.skipX=1,null!=o.y?(c.add(c,"y",c.y,s(o.y,e,"y",c.y,o.offsetY||0),l,i),c._props.push("scrollTo_y")):c.skipY=1},render:function render(e,t){for(var n,r,l,i,s,p=t._pt,c=t.target,f=t.tween,u=t.autoKill,a=t.xPrev,y=t.yPrev,d=t.isWin,x=t.snap,g=t.snapInline;p;)p.r(e,p.d),p=p._next;n=d||!t.skipX?t.getX():a,l=(r=d||!t.skipY?t.getY():y)-y,i=n-a,s=v.autoKillThreshold,t.x<0&&(t.x=0),t.y<0&&(t.y=0),u&&(!t.skipX&&(s<i||i<-s)&&n<o(c,"x")&&(t.skipX=1),!t.skipY&&(s<l||l<-s)&&r<o(c,"y")&&(t.skipY=1),t.skipX&&t.skipY&&(f.kill(),t.vars.onAutoKill&&t.vars.onAutoKill.apply(f,t.vars.onAutoKillParams||[]))),d?T.scrollTo(t.skipX?n:t.x,t.skipY?r:t.y):(t.skipY||(c.scrollTop=t.y),t.skipX||(c.scrollLeft=t.x)),!x||1!==e&&0!==e||(r=c.scrollTop,n=c.scrollLeft,g?c.style.scrollSnapType=g:c.style.removeProperty("scroll-snap-type"),c.scrollTop=r+1,c.scrollLeft=n+1,c.scrollTop=r,c.scrollLeft=n),t.xPrev=t.x,t.yPrev=t.y},kill:function kill(e){var t="scrollTo"===e;!t&&"scrollTo_x"!==e||(this.skipX=1),!t&&"scrollTo_y"!==e||(this.skipY=1)}};y.max=o,y.getOffset=r,y.buildGetter=p,l()&&u.registerPlugin(y),e.ScrollToPlugin=y,e.default=y;if (typeof(window)==="undefined"||window!==e){Object.defineProperty(e,"__esModule",{value:!0})} else {delete e.default}});
|
||||
|
File diff suppressed because one or more lines are too long
11
algorithm-visualization/assets/lib/gsap/3.10.4/ScrollTrigger.min.js
vendored
Normal file
11
algorithm-visualization/assets/lib/gsap/3.10.4/ScrollTrigger.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
11
algorithm-visualization/assets/lib/gsap/3.10.4/TextPlugin.min.js
vendored
Normal file
11
algorithm-visualization/assets/lib/gsap/3.10.4/TextPlugin.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
11
algorithm-visualization/assets/lib/gsap/3.10.4/gsap.min.js
vendored
Normal file
11
algorithm-visualization/assets/lib/gsap/3.10.4/gsap.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="zh-CN">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
@ -8,6 +8,18 @@
|
||||
<title>小墨 | 算法可视化 | Algorithm Visualization</title>
|
||||
|
||||
<link rel="stylesheet" href="./assets/css/index.css">
|
||||
|
||||
<style>
|
||||
/* 调整 SVG 中文本定位点到文本中央 */
|
||||
text {
|
||||
text-anchor: middle;
|
||||
dominant-baseline: middle;
|
||||
}
|
||||
|
||||
svg {
|
||||
user-select: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -52,7 +64,10 @@
|
||||
</div>
|
||||
|
||||
<!-- D3.js refer: https://d3js.org/ -->
|
||||
<script src="./assets/lib/d3/7.4.4/d3.js"></script>
|
||||
<script src="./assets/lib/d3/7.4.4/d3.min.js"></script>
|
||||
|
||||
<!-- GSAP refer: https://greensock.com/docs/v3/Installation -->
|
||||
<script src="./assets/lib/gsap/3.10.4/gsap.min.js"></script>
|
||||
|
||||
<!-- class -->
|
||||
<script src="./assets/js/class.js"></script>
|
||||
@ -62,7 +77,7 @@
|
||||
<!-- 排序算法 -->
|
||||
<script src="./assets/js/algorithm/sort.js"></script>
|
||||
<!-- 算法测试 -->
|
||||
<script src="./assets/js/algorithm/test.js"></script>
|
||||
<!-- <script src="./assets/js/algorithm/test.js"></script> -->
|
||||
</body>
|
||||
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user