jiafeng123 / helloworld Goto Github PK
View Code? Open in Web Editor NEWLicense: MIT License
License: MIT License
<template>
<div class="ipas-container">
<div class="left-view">
<div
id="textInput"
ref="textInputRef"
class="container-left-input"
:contenteditable="true"
@input="handleInput"
>
</div>
</div>
<div class="right-view"></div>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted, nextTick } from 'vue'
import { cloneDeep,debounce } from 'lodash'
const textInputRef = ref()
const str = '\n【Simple Installation】: Telescope dovetail mounting plate, easy to replace and install within seconds, no complicated tools needed.\n【Type】: Telescope Dovetail Mounting Plate with m6 screw Replacement.\n【Material】: The dovetail mounting fixing plate is made of premium aluminum alloy material, wear resistant and durable, has good performance.\n【Multi Use】: This standard dovetail plate can be used to modify astronomical telescopes, connect to different equatorial mounts or add SLR, guide mirrors and other equipment to use.\n【Replacement 】: Directly replaces your worn, cracked, broken and unusable rail bar mounting plate.\nManufacturer: balikha\nASIN: B0CC9FXTP7\nDate First Available: July 19, 2023\nManufacturer: balikha\nASIN: B0CC9FXTP7\nDate First Available: July 19, 2023'
const offsetsData = [
{
"from": "text",
"origin_word": "Dovetail",
"offset": 34,
"length": 8
},
{
"from": "text",
"origin_word": "Dovetail",
"offset": 150,
"length": 8
},
{
"from": "text",
"origin_word": "Dovetail",
"offset": 217,
"length": 8
},
{
"from": "text",
"origin_word": "Dovetail",
"offset": 369,
"length": 8
}
]
const render = () => {
let html = ``
for (let i = 0; i < offsetsData.length; i++) {
// 处理第一个
if (i === 0) {
html += str.slice(0, offsetsData[i].offset)
html += `<span class="highlight">${str.slice(offsetsData[i].offset, offsetsData[i].offset + offsetsData[i].length)}</span>`
}
else {
html += str.slice(offsetsData[i - 1].offset + offsetsData[i - 1].length, offsetsData[i].offset)
html += `<span class="highlight">${str.slice(offsetsData[i].offset, offsetsData[i].offset + offsetsData[i].length)}</span>`
}
if (i === offsetsData.length - 1) {
html += str.slice(offsetsData[i].offset + offsetsData[i].length)
}
}
// 渲染
html = html.replace(/\n/g, '<br/>')
textInputRef.value.innerHTML = html
}
onMounted(() => {
nextTick(() => {
render()
})
})
function getCursorPosition(parent: any, node: any, offset: any, stat: any) {
if (stat.done) return stat;
let currentNode = null;
if (parent.childNodes.length === 0) {
stat.pos += parent.textContent.length;
} else {
for (let i = 0; i < parent.childNodes.length && !stat.done; i++) {
currentNode = parent.childNodes[i];
if (currentNode === node) {
stat.pos += offset;
stat.done = true;
return stat;
} getCursorPosition(currentNode, node, offset, stat);
}
}
return stat;
}
function setCursorPosition(parent: any, range: any, stat: any) {
if (stat.done) return range;
let currentNode = null;
if (parent.childNodes.length === 0) {
if (parent.textContent.length >= stat.pos) {
range.setStart(parent, stat.pos);
stat.done = true;
} else {
stat.pos -= parent.textContent.length;
}
} else {
for (let i = 0; i < parent.childNodes.length && !stat.done; i++) {
currentNode = parent.childNodes[i];
setCursorPosition(currentNode, range, stat);
}
}
return range;
}
function resetCursor(sel: any, pos: any) {
// restore the position
sel.removeAllRanges();
const range = setCursorPosition(textInputRef.value, document.createRange(), {
pos: pos.pos,
done: false,
});
range.collapse(true);
sel.addRange(range);
}
const handleInput = debounce(() => {
const sel = window.getSelection() as Selection;
const node = sel.focusNode;
const offset = sel.focusOffset;
const pos = getCursorPosition(textInputRef.value, node, offset, { pos: 0, done: false });
if (offset === 0) pos.pos += 0.5;
// 记录上次匹配的数据,用内容去匹配
const cloneData = cloneDeep(offsetsData)
let matchedData = cloneData.map(i => i.origin_word.toLowerCase())
// 去重
matchedData = Array.from(new Set(matchedData))
// 编辑之后,重新渲染
let html = textInputRef.value.innerHTML
// 去掉所有的span,包括class="highlight"和不包括class="highlight"
html = html.replaceAll(/<span[^>]*>([^<]*)<\/span>/g, '$1')
html = html.replaceAll(/<span[^>]*>([^<]*)<\/span>/g, '$1')
for (let i = 0; i < matchedData.length; i++) {
const reg = new RegExp(matchedData[i], 'gi')
html = html.replaceAll(reg, `<span class="highlight">${matchedData[i]}</span>`)
}
textInputRef.value.innerHTML = html
resetCursor(sel, pos)
},200)
</script>
<style>
.highlight {
padding: 2px;
border-radius: 2px;
background-color: #FFD700;
}
</style>
<style lang="less" scoped>
.ipas-container {
background-color: #fff;
height: 100%;
display: flex;
.left-view {
flex: 1;
padding: 32px 40px;
display: flex;
justify-content: center;
align-items: center;
// background-color: #F7F8FA;
#textInput {
width: 80%;
height: 80%;
margin: auto;
outline: none;
border-radius: 8px;
overflow-y: auto;
padding: 12px;
line-height: 30px;
background: var(---color-fill-1, #F7F8FA);
word-break: normal;
}
}
.right-view {
width: 840px;
padding: 32px 40px;
}
}
@media screen and (max-width: 1280px) {
.right-view {
width: 520px;
}
}
@media screen and (max-width: 1440px) {
.right-view {
width: 600px;
}
}
</style>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Handwritten Signature Animation</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #f0f0f0;
}
.signature-container {
width: 500px;
height: 200px;
}
svg {
width: 100%;
height: 100%;
}
path {
fill: none;
stroke: #000;
stroke-width: 2;
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
animation: draw 4s ease-in-out forwards;
}
@keyframes draw {
to {
stroke-dashoffset: 0;
}
}
</style>
</head>
<body>
<div class="signature-container">
<svg viewBox="0 0 500 200">
<path
id="signature-path"
d="M20,80 Q40,10 60,80 T100,80 Q140,10 160,80 T200,80"
/>
</svg>
</div>
<script>
// script.js
document.addEventListener('DOMContentLoaded', () => {
const path = document.getElementById('signature-path');
const length = path.getTotalLength();
path.style.strokeDasharray = length;
path.style.strokeDashoffset = length;
});
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas Particle Background</title>
<style>
body, html {
margin: 0;
padding: 0;
overflow: hidden;
background: #000;
}
</style>
</head>
<body>
<canvas id="particleCanvas"></canvas>
<script>
const canvas = document.getElementById('particleCanvas');
const ctx = canvas.getContext('2d');
let particles = [];
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
window.addEventListener('resize', resizeCanvas);
resizeCanvas();
class Particle {
constructor() {
this.reset();
}
reset() {
this.x = Math.random() * canvas.width;
this.y = Math.random() * canvas.height;
this.size = Math.random() * 3 + 1;
this.speedX = Math.random() * 2 - 1;
this.speedY = Math.random() * 2 - 1;
this.color = `rgba(255, 255, 255, ${Math.random()})`;
}
update() {
this.x += this.speedX;
this.y += this.speedY;
if (this.x < 0 || this.x > canvas.width || this.y < 0 || this.y > canvas.height) {
this.reset();
}
}
draw() {
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
}
}
function createParticles(count) {
for (let i = 0; i < count; i++) {
particles.push(new Particle());
}
}
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
particles.forEach(particle => {
particle.update();
particle.draw();
});
requestAnimationFrame(animate);
}
createParticles(100);
animate();
</script>
</body>
</html>
var element = {
"text": "The blood pressure was initially elevated on the patient's outpatient medications, so his hypertension medicines were adjusted by increasing his lisinopril to 20 mg qd."
},
rawText = element.text.slice(),
spans = [{
"begin": 145,
"end": 155,
"tooltip": "section 1"
}, {
"begin": 4,
"end": 18,
"tooltip": "section 2"
}, {
"begin": 4,
"end": 18,
"tooltip": "section 3"
}, {
"begin": 90,
"end": 102,
"tooltip": "section 4"
}, {
"begin": 4,
"end": 41,
"tooltip": "section 5"
}];
var highlightedString = createHighlightedString(spans,element.text);
document.getElementById('text').innerHTML = highlightedString;
function createHighlightedString(ranges, text) {
var flatRanges = flattenRanges(ranges);
var inflatedRanges = inflateRanges(flatRanges, text.length);
var filledRanges = fillRanges(inflatedRanges, text);
var str = "";
var index = 0;
console.log('===============', filledRanges)
for (var i in filledRanges) {
var range = filledRanges[i];
var begin = range.begin, end = range.end;
if (range.count > 0) {
if (range.tooltip) {
str += "<span class='highlight-" + range.count + " tooltip'>" + range.text + "<span class='tooltiptext tooltip-bottom'>" + range.tooltip.join('<br/>') + "</span></span>";
} else {
str += "<span class='highlight-" + range.count + "'>" + range.text + "</span>";
}
} else {
str += range.text;
}
}
return str;
}
function flattenRanges(ranges) {
var points = [];
var flattened = [];
for (var i in ranges) {
if (ranges[i].end < ranges[i].begin) { //RE-ORDER THIS ITEM (BEGIN/END)
var tmp = ranges[i].end; //RE-ORDER BY SWAPPING
ranges[i].end = ranges[i].begin;
ranges[i].begin = tmp;
}
points.push(ranges[i].begin);
points.push(ranges[i].end);
}
//MAKE SURE OUR LIST OF POINTS IS IN ORDER
points.sort(function(a, b){return a-b});
//FIND THE INTERSECTING SPANS FOR EACH PAIR OF POINTS (IF ANY)
//ALSO MERGE THE ATTRIBUTES OF EACH INTERSECTING SPAN, AND INCREASE THE COUNT FOR EACH INTERSECTION
for (var i in points) {
if (i==0 || points[i]==points[i-1]) continue;
var includedRanges = ranges.filter(function(x){
return (Math.max(x.begin,points[i-1]) < Math.min(x.end,points[i]));
});
if (includedRanges.length > 0) {
var flattenedRange = {
begin:points[i-1],
end:points[i],
count:0
}
for (var j in includedRanges) {
var includedRange = includedRanges[j];
for (var prop in includedRange) {
if (prop != 'begin' && prop != 'end') {
if (!flattenedRange[prop]) flattenedRange[prop] = [];
flattenedRange[prop].push(includedRange[prop]);
}
}
flattenedRange.count++;
}
flattened.push(flattenedRange);
}
}
return flattened;
}
function inflateRanges(ranges, length=0) {
var inflated = [];
var lastIndex;
for (var i in ranges) {
if (i==0) {
//IF THERE IS EMPTY TEXT IN THE BEGINNING, CREATE AN EMOTY RANGE
if (ranges[i].begin > 0){
inflated.push({
begin:0,
end:ranges[i].begin-1,
count:0
});
}
inflated.push(ranges[i]);
} else {
if (ranges[i].begin == ranges[i-1].end) {
ranges[i-1].end--;
}
if (ranges[i].begin - ranges[i-1].end > 1) {
inflated.push({
begin:ranges[i-1].end+1,
end:ranges[i].begin-1,
count:0
});
}
inflated.push(ranges[i]);
}
lastIndex = ranges[i].end;
}
//FOR SIMPLICITY, ADD ANY REMAINING TEXT AS AN EMPTY RANGE
if (lastIndex+1 < length-1) {
inflated.push({
begin:lastIndex+1,
end:length-1,
count:0
})
}
return inflated;
}
function fillRanges(ranges, text) {
for (var i in ranges) {
ranges[i].text = text.slice(ranges[i].begin,ranges[i].end+1);
}
return ranges;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Smooth Canvas Star Drawing Animation</title>
<style>
body, html {
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background: #000;
}
canvas {
border: 1px solid #fff;
}
</style>
</head>
<body>
<canvas id="starCanvas" width="600" height="600"></canvas>
<script>
const canvas = document.getElementById('starCanvas');
const ctx = canvas.getContext('2d');
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
const outerRadius = 200;
const innerRadius = 80;
const points = 5;
const totalSteps = 500; // 动画的总步数
let currentStep = 0;
function drawStar(cx, cy, outerR, innerR, n, step) {
ctx.beginPath();
let progress = step / totalSteps;
let maxIndex = Math.floor(progress * n * 2);
let remainingProgress = (progress * n * 2) - maxIndex;
for (let i = 0; i <= maxIndex; i++) {
const angle = i * Math.PI / n;
const radius = (i % 2 === 0) ? outerR : innerR;
const x = cx + radius * Math.cos(angle);
const y = cy + radius * Math.sin(angle);
if (i === 0) {
ctx.moveTo(x, y);
} else {
ctx.lineTo(x, y);
}
}
if (remainingProgress > 0 && maxIndex < n * 2) {
const angle = (maxIndex + 1) * Math.PI / n;
const radius = ((maxIndex + 1) % 2 === 0) ? outerR : innerR;
const x = cx + radius * Math.cos(angle);
const y = cy + radius * Math.sin(angle);
const prevAngle = maxIndex * Math.PI / n;
const prevRadius = (maxIndex % 2 === 0) ? outerR : innerR;
const prevX = cx + prevRadius * Math.cos(prevAngle);
const prevY = cy + prevRadius * Math.sin(prevAngle);
const interpolatedX = prevX + (x - prevX) * remainingProgress;
const interpolatedY = prevY + (y - prevY) * remainingProgress;
ctx.lineTo(interpolatedX, interpolatedY);
}
ctx.strokeStyle = '#fff';
ctx.lineWidth = 2;
ctx.stroke();
}
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawStar(centerX, centerY, outerRadius, innerRadius, points, currentStep);
currentStep++;
if (currentStep <= totalSteps) {
requestAnimationFrame(animate);
}
}
animate();
</script>
</body>
</html>
<template>
<section class="carousel_wrapper">
<a-carousel
auto-play
indicator-type="line"
style="height: 480px;"
@change="handleChange"
>
<a-carousel-item
v-for="image,i of carouselData"
:key="i"
>
<section class=" relative h-full">
<img
:src="image.img"
class="h-full w-full object-cover"
>
<section class="absolute left-[134px] 2xl:top-[134px] xl:top-28 lg:top-16 max-lg:top-12 Djinbu flex flex-col items-start">
<p
class="text-[#1A3471] 2xl:text-3xl xl:text-[26px] lg:text-2xl max-lg:text-2xl"
:class="{
'!text-white': i == 1
}"
>
{{ image.title1 }}
</p>
<p
class="text-[#1A3471] 2xl:text-7xl mt-4 max-lg:mt-2 xl:text-6xl lg:text-5xl max-lg:text-4xl"
:class="{
'!text-white': i == 1
}"
>
{{ image.title2 }}
</p>
<p
v-if="i == 1"
class=" !text-white text-sm fontSC 2xl:mt-9 xl:mt-8 lg:mt-7 max-lg:mt-4"
>
领域:多模态大模型 / 数据采集 / NLP / CV
</p>
<section
:class="{
' !bg-white/15 !text-white hover:!bg-white/30': i == 1
}"
class="2xl:mt-20 xl:mt-12 lg:mt-10 max-lg:mt-6 py-2 cursor-pointer transition-all hover:bg-[#57A9FB] text-white text-sm fontSC px-5 gap-2 flex justify-center items-center rounded-lg bg-[#3491FA] backdrop-blur-[2px]"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="14"
height="14"
viewBox="0 0 14 14"
fill="none"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M10.3906 6.41627L7.67475 3.70038L8.4997 2.87542L12.6245 7.00021L8.4997 11.125L7.67475 10.3L10.3918 7.58294L1.45825 7.58294L1.45825 6.41627L10.3906 6.41627Z"
fill="white"
/>
</svg>
<span>查看全部赛题</span>
</section>
</section>
</section>
</a-carousel-item>
</a-carousel>
<section
id="test-tabs"
class="flex gap-4 overflow-x-auto test-tabs"
>
<div
v-for="i of 20"
:key="i"
class="flex flex-shrink-0 items-center justify-center w-16 h-16 bg-[#E6E6E6] rounded-lg"
>
{{ i }}
</div>
</section>
</section>
</template>
<script setup lang="ts">
import img1 from '@/assets/images/banner1.png'
import img2 from '@/assets/images/banner2.png'
const images = [
img1,
img2,
];
const carouselData = ref([
{
title1: '第一届上海交大-三态',
title2: '跨境电商 AI 全球挑战赛',
img: img1
},
{
title1: '枪械零件识别:',
title2: '这个零件可以用在枪上吗?',
img: img2
},
])
const handleChange=(value)=>{
}
onMounted(() => {
nextTick(() => {
const scrollableDiv = document.getElementById('test-tabs');
let isDown = false;
let startX;
let scrollLeft;
scrollableDiv.addEventListener('mousedown', (e) => {
isDown = true;
startX = e.pageX - scrollableDiv.offsetLeft;
scrollLeft = scrollableDiv.scrollLeft;
});
scrollableDiv.addEventListener('mousemove', (e) => {
if (!isDown) return;
e.preventDefault();
const x = e.pageX - scrollableDiv.offsetLeft;
const walk = (x - startX) * 3;
scrollableDiv.scrollLeft = scrollLeft - walk;
});
scrollableDiv.addEventListener('mouseup', () => {
isDown = false;
});
scrollableDiv.addEventListener('mouseleave', () => {
isDown = false;
});
scrollableDiv.addEventListener('touchstart', (e) => {
isDown = true;
startX = e.touches[0].pageX - scrollableDiv.offsetLeft;
scrollLeft = scrollableDiv.scrollLeft;
});
scrollableDiv.addEventListener('touchmove', (e) => {
if (!isDown) return;
e.preventDefault();
const x = e.touches[0].pageX - scrollableDiv.offsetLeft;
const walk = (x - startX) * 3;
scrollableDiv.scrollLeft = scrollLeft - walk;
});
scrollableDiv.addEventListener('touchend', () => {
isDown = false;
});
setTimeout(() => {
const tab = document.querySelector('.test-tabs > div:nth-child(10)');
tab.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'center' });
}, 3000);
})
})
</script>
<style scoped lang="less">
@media screen and (min-width: 1536px) {
.carousel_wrapper{
:deep(.arco-carousel){
height: 480px !important;
}
}
}
@media screen and (max-width: 1536px) and (min-width: 1280px) {
.carousel_wrapper{
:deep(.arco-carousel){
height: 400px !important;
}
}
}
@media screen and (max-width: 1280px) and (min-width: 1024px) {
.carousel_wrapper{
:deep(.arco-carousel){
height: 320px !important;
}
}
}
@media screen and (max-width: 1024px) {
.carousel_wrapper{
:deep(.arco-carousel){
height: 240px !important;
}
}
}
:deep(.arco-carousel-indicator-item){
background-color: #fff;
opacity: 0.25;
width: 30px;
}
:deep(.arco-carousel-indicator-item-active){
opacity: 0.4;
}
.carousel_wrapper:has(.arco-carousel-slide div:first-child.arco-carousel-item-current){
:deep(.arco-carousel-indicator-item){
background-color: #57A9FB;
opacity: 0.25;
width: 30px;
}
:deep(.arco-carousel-indicator-item-active){
opacity: 0.6;
}
}
:deep(.arco-carousel-arrow > div > svg){
font-size: 3rem;
stroke: rgba(255, 255, 255, 0.6);
}
:deep(.arco-carousel-arrow-left),:deep(.arco-carousel-arrow-right){
background-color: transparent;
width: 3rem;
height: 3rem;
&:hover{
background-color: transparent;
svg{
transition: all 0.3s ease-in-out;
stroke: rgba(255, 255, 255, 0.85);
}
}
}
// 隐藏滚动条
::-webkit-scrollbar {
display: none;
}
.test-tabs{
-webkit-overflow-scrolling: touch;
cursor: pointer;
scroll-snap-type: x mandatory;
}
</style>
const toggleTheme = useToggle(isDark)
const handleToggleTheme = (event: MouseEvent) => {
console.log(event)
const x = event.clientX
const y = event.clientY
const { innerWidth, innerHeight } = window
const endRadius = Math.hypot(Math.max(x, innerWidth - x), Math.max(y, innerHeight - y))
// @ts-expect-error: Transition API
if (!document.startViewTransition) {
toggleTheme()
return
}
// @ts-expect-error: Transition API
const transition = document.startViewTransition(() => {
toggleTheme()
})
transition.ready.then(() => {
const clipPath = [`circle(0px at ${x}px ${y}px)`, `circle(${endRadius}px at ${x}px ${y}px)`]
document.documentElement.animate(
{
clipPath: theme.value === 'dark' ? clipPath : [...clipPath].reverse()
},
{
duration: 300,
easing: 'ease-in',
pseudoElement: theme.value === 'dark' ? '::view-transition-new(root)' : '::view-transition-old(root)'
}
)
})
}
const calculateSimilarity = (str1:string, str2:string) => {
const len1 = str1.length;
const len2 = str2.length;
// 创建一个矩阵,其中单元格 (i, j) 存储将 str1[0...i-1] 转换为 str2[0...j-1] 的最小编辑距离
const matrix = new Array(len1 + 1).fill(null).map(() => new Array(len2 + 1).fill(0));
// 初始化第一行和第一列
for (let i = 0; i <= len1; i++) {
matrix[i][0] = i;
}
for (let j = 0; j <= len2; j++) {
matrix[0][j] = j;
}
// 填充矩阵
for (let i = 1; i <= len1; i++) {
for (let j = 1; j <= len2; j++) {
const cost = str1[i - 1] === str2[j - 1] ? 0 : 1;
matrix[i][j] = Math.min(
matrix[i - 1][j] + 1, // 删除
matrix[i][j - 1] + 1, // 插入
matrix[i - 1][j - 1] + cost // 替换
);
}
}
// 返回矩阵的右下角单元格,即两个字符串之间的 Levenshtein 距离
return matrix[len1][len2];
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.