专业网站建设86215,大丰网站建设价格,闵行做网站费用,企业邮箱怎么使用效果图 解题思路
将图片全部定位至中心点#xff0c;然后x轴就变动translateX #xff0c;y轴同理#xff1b;
这里有两个问题
浏览器#xff1a; 以左上角为原点0#xff0c;0 越往下y越大 数学坐标系#xff1a;以中心点为原点0#xff0c;0 越往下y越小#xff1…效果图 解题思路
将图片全部定位至中心点然后x轴就变动translateX y轴同理
这里有两个问题
浏览器 以左上角为原点00 越往下y越大 数学坐标系以中心点为原点00 越往下y越小 曲线函数坐标确定了原点确定了就需要对应的曲线函数来描述这条线段
我们一个个来解决
一、如何把数学坐标系运用到浏览器之中转化y轴的上下大小反序
translateX 变化多少就是多少translateY 变化多少就是反向移动多少所以重要的是这个反向我们如何来描述,其实这里也很简单我们使用css变量然后在变化的时候setProperty对应的变量值然后在css里我们做对应的描述
style#container {width: 100vw;height: 100vh;background-color: aqua;position: relative;overflow: auto;}.curveImg {--size: 30px;--dx: 1;--dy: 1;border-radius: calc(var(--size) / 2);width: var(--size);height: var(--size);position: absolute;left: 50%;top: 50%;margin-left: calc(var(--size) / 2);margin-top: calc(var(--size) / 2);object-fit: cover; /* 保持图片纵横比 */transition: all 0.8s ease-out ;transform: translate(calc(var(--dx) * 1px), calc(var(--dy) * -1px));}/stylebodydiv idcontainer/div/body此时我们已经完成了准备工作接着完成反向排序的准备工作dy越大则在html中排列就越小超越原点即为负数
二、将原点挪至中心点
原点在与你想让它在那个位置它都可以排列到那个位置这里我想让它在容器内渲染所以我想设置在容器内的中心位置那么这个中心位置其实就是我给定的最大值与最小值和的一半就是我的中心点 那么我只要让其对应的横坐标点减去当前的原点就是它当前需要移动的距离也就是dxy同理
曲线函数
不管是曲线还是抛物线还是斜线其实都是有一个方程式或者叫做函数来表示
那么如果是在数学中 yx; 那就表示一段45度的斜线 y-x ; 那就表示一段-45度的斜线 ysin(x); 那就表示连绵的曲线 数学坐标系中是无限延伸的但在我们的浏览器中他是有一个范围呢所以我们还需要给他一个范围
如果是在代码中如果我们得到了曲线的表示函数接下来就是将其用html、css、js来绘制到我们的电脑屏幕中
我们先来写一个类来表示这个计算类
class Curve {
/** * 创建一个计算类的实例 * * constructor * param {Function} curveFunc 要添加的任务实例 * param {Array} xRange x取值范围* param {Array} yRange y取值范围*/ constructor(curveFunc, xRange, yRange) {this.xRange xRangethis.yRange yRangethis.curveFunc curveFunc}/*** 计算曲线函数* param {Number} x x值* returns {Number} y y值*/getY(x) {let y this.curveFunc(x)if (y this.yRange[0]) {y this.yRange[0]}if (y this.yRange[1]) {y this.yRange[1]}return y}
}上面我们已经创建好一个计算类、具体释义有jsdoc注释
那么我们如何来表示曲线或者直线呢
const line new Curve(xx,[-1,1],[-1,1])
const wave new Curve(x Math.sin(x),[-1 * Math.PI, 3 * Math.PI],[-1, 1]
)这样就表示出来了 曲线y wave.getY(x); 直线y line.getY(x); 那么关于坐标关系我们已经用代码描述出来绘制就是最简单的事了 div idcontainer/div假设我们现在有这么一个div 然后我们先在div里创建一些图片当然这里也可以换成你喜欢的样式
const box document.querySelector(#container)
const initImg className {const frag document.createDocumentFragment()for (let i 0; i 100; i) {const img document.createElement(img)img.classList.add(className)img.src ./test.jpg // 设置图片路径frag.appendChild(img)}box.appendChild(frag)
}
initImg(curveImg)接下来就是渲染
const layout (curve, doms, width, height) {const [minX, maxX] curve.xRangeconst [minY, maxY] curve.yRange// 步长 const xStep (maxX - minX) / (doms.length - 1)// 与实际坐标轴的比例const xScale width / (maxX - minX)const yScale height / (maxY - minY)const cx (maxX minX) / 2const cy (maxY minY) / 2for (let i 0; i doms.length; i) {const dom doms[i]const x minX i * xStepconst y curve.getY(x)const dx (x - cx) * xScaleconst dy (y - cy) * yScaledom.style.setProperty(--dx, dx)dom.style.setProperty(--dy, dy)}
}接下来只要我们执行layout函数那么图片就会进行对应的渲染
上全部代码
!DOCTYPE html
html langenheadmeta charsetUTF-8 /meta nameviewport contentwidthdevice-width, initial-scale1.0 /titleDocument/titlestyle#container {width: 100vw;height: 100vh;background-color: aqua;position: relative;overflow: auto;}.curveImg {--size: 30px;--dx: 1;--dy: 1;border-radius: calc(var(--size) / 2);width: var(--size);height: var(--size);position: absolute;left: 50%;top: 50%;margin-left: calc(var(--size) / 2);margin-top: calc(var(--size) / 2);object-fit: cover; /* 保持图片纵横比 */transition: all 0.8s ease-out ;transform: translate(calc(var(--dx) * 1px), calc(var(--dy) * -1px));}/style/headbodydivbutton onclickrenderLine()直线/buttonbutton onclickrenderWave()曲线/buttonbutton onclickrenderLineX()x线/buttonbutton onclickrenderWaveX()交叉曲线线/button/divdiv idcontainer/divscriptclass Curve {/*** 创建一个计算类的实例 ** constructor* param {Function} curveFunc 要添加的任务实例* param {Array} xRange x取值范围* param {Array} yRange y取值范围*/constructor(curveFunc, xRange, yRange) {this.xRange xRangethis.yRange yRangethis.curveFunc curveFunc}/*** 计算曲线函数* param {Number} x x值* returns {Number} y y值*/getY(x) {let y this.curveFunc(x)if (y this.yRange[0]) {y this.yRange[0]}if (y this.yRange[1]) {y this.yRange[1]}return y}}const layout (curve, doms, width, height) {const [minX, maxX] curve.xRangeconst [minY, maxY] curve.yRangeconst xStep (maxX - minX) / (doms.length - 1)const xScale width / (maxX - minX)const yScale height / (maxY - minY)const cx (maxX minX) / 2const cy (maxY minY) / 2for (let i 0; i doms.length; i) {const dom doms[i]const x minX i * xStepconst y curve.getY(x)const dx (x - cx) * xScaleconst dy (y - cy) * yScaledom.style.setProperty(--dx, dx)dom.style.setProperty(--dy, dy)}}const box document.querySelector(#container)const initImg className {const frag document.createDocumentFragment()for (let i 0; i 100; i) {const img document.createElement(img)img.classList.add(className)img.src ./test.jpg // 设置图片路径frag.appendChild(img)}box.appendChild(frag)}initImg(curveImg)const images document.querySelectorAll(.curveImg)const wave new Curve(x Math.sin(x),[-1 * Math.PI, 3 * Math.PI],[-1, 1])const wave2 new Curve(x Math.sin(x),[0 * Math.PI, 4 * Math.PI],[-1, 1])const line new Curve(x x, [-1, 1], [-1, 1])const line2 new Curve(x -x, [-1, 1], [-1, 1])const middleIndex Math.floor(images.length / 2)const dom1 Array.from(images).slice(0,middleIndex);const dom2 Array.from(images).slice(middleIndex);function renderLine() {layout(line, images, box.clientWidth - 200, box.clientHeight - 200)}function renderWave() {layout(wave, images, box.clientWidth - 200, box.clientHeight - 200)}function renderLineX() {layout(line, dom1, box.clientWidth - 200, box.clientHeight - 200)layout(line2, dom2, box.clientWidth - 200, box.clientHeight - 200)}function renderWaveX() {layout(wave, dom1, box.clientWidth - 200, box.clientHeight - 200)layout(wave2, dom2, box.clientWidth - 200, box.clientHeight - 200)}document.addEventListener(DOMContentLoaded, () {renderLine()})/script/body
/html